Страница 4 из 14

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 08:02:50
Dimon456
slav0n, молодец, садись, пять.
Теперь то же самое, только на реальном устройстве.

Я не зря картинку давал
СпойлерИзображение
Столько хватит шума?
Как один человек сказал - что же хваленый СТМ шумит аж в трех младших разрядах. И это на опоре ТЛ431 = 3,3 счем-то там, не помню, лень смотреть.

Что же мы все делаем, берем сумму к примеру из 64 отсчетов и делим на 64.

Первый вопрос slav0n, по чему не на 63, ну взяли бы сумму из 63 и поделили на 63, нет берем сумму кратную степени 2 и делим на степень 2.
slav0n писал(а):та забыли уже про того чувака с его 240
Что же на самом деле произошло у slav0n: он взял сумму из 64 и сдвинул на 3 бита вправо, эти 3 бита несут какую-то информацию.
Второй вопрос slav0n, какую информацию?
далее оставшееся от сдвига на три бита умножил на опору 5000.0 (усилил, просто взял и усилил на какой то К) и поделил на что там не хватает.

Далее мне лень объяснять, может так дойдет.
Верьте в чудо, а Starichok51, просто взял и поставил ADS1115, и молчит, а я stm32f030.

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 14:44:40
slav0n
Dimon456 писал(а):по чему не на 63, ну взяли бы сумму из 63 и поделили на 63, нет берем сумму кратную степени 2 и делим на степень 2.
ты снова пропустил уроки...
правильно вот так - берем сумму из кратных 4^N выборок и делим на 2^N. целочисленно
Dimon456 писал(а):взял сумму из 64 и сдвинул на 3 бита вправо, эти 3 бита несут какую-то информацию.
Второй вопрос slav0n, какую информацию?
незначащую бесполезную информацию, которую бессмысленно использовать в дальнейших вычислениях.

Добавлено after 2 hours 23 minutes 44 seconds:
кстати, множитель 4^N выборок удобно брать из весов разрядов (2, 4, 8, 16...)
тогда децимацию и усреднение можно делать одновременно одним сдвигом

Добавлено after 2 hours 50 minutes 27 seconds:
Dimon456 писал(а):Столько хватит шума?
а такой шум тебе нравится или нет?

Изображение

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 17:31:45
Dimon456
slav0n писал(а):незначащую бесполезную информацию, которую бессмысленно использовать в дальнейших вычислениях.
А ты попробуй

Код: Выделить всё

return adcv_value;	// >> 3;//13 bit

soft = ADCV_Conv() * 5000.0 / (1024UL << (3 + 3));

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 18:12:24
slav0n
сколько выборок суммировать?
а впрочем не важно...
ты предлагаешь то что есть умножить на 8 и разделить на 8192

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 18:16:30
Dimon456
Спойлер

Код: Выделить всё

unsigned int ADCV_Conv(void) {
	unsigned long adcv_value = 0; //сброс регистра хранения результата оцифровки напряжения
//	ADMUX &= ~((1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0)); //выбор канала АЦП ADC0
//	_delay_us(10); //пауза 10мкс
	u16 rounds = 64;//13 bit
	for (u16 i = 0; i < rounds; i++) //цикл суммирования результатов оцифровки 64 замеров
	{
		ADCSRA |= (1 << ADSC); //запуск АЦП
		while ((ADCSRA & (1 << ADSC))); //ожидание окончания преобразования
		adcv_value += ADCW; //прибавим к сумме значений предыдущих измерений значение очередного измерения
	}
	return adcv_value;	// >> 3;//13 bit
}


soft = ADCV_Conv() * 5000.0 / (1024UL << (3 + 3));

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 18:22:17
slav0n
смотри ответ выше

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 19:02:55
Dimon456
slav0n писал(а):то что есть умножить на 8 и разделить на 8192
по чему умножить на 8?
Сумму из 64 выборок умножаем на 5000.0 и делим на 65536, твои 16 бит.

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 19:20:15
Starichok51
Dimon456, сумму 64 выборок следует делить на 8, чтобы получить 13 бит.
а ты взялся делить на 64.

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 20:34:45
slav0n
Dimon456 писал(а):Сумму из 64 выборок умножаем на 5000.0 и делим на 65536
это банальное усреднение, никакого увеличения разрядности не дает
оно даже не может толком отфильтровать мою помеху

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 20:50:14
Dimon456
slav0n, а ты на что делишь?
Сумму из 64 выборок делишь на 8, далее умножаешь на 5000.0 и еще раз делишь на 8192. Результат 13 бит.

А усреднение: сумму из 64 выборок делишь на 64, далее умножаешь на 5000.0 и еще раз делишь на 1024. Результат 10 бит.

В чем проблема?

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 21:18:21
slav0n
все правильно
Dimon456 писал(а):Сумму из 64 выборок делишь на 8
получаешь +3 бита разрешения
Dimon456 писал(а):сумму из 64 выборок делишь на 64
получаешь +0 бит разрешения

и наличие шума в сигнале здесь имеет решающую роль

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 21:39:23
Dimon456
Я тебе предлагаю
Dimon456 писал(а):Сумму из 64 выборок умножаем на 5000.0 и делим на 65536, твои 16 бит.

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 22:01:03
slav0n
та делал я это - фигня, 10 бит.

я тут поставил опору 4096, так вообще не надо ничего умножать-делить

Код: Выделить всё

unsigned int ADCV_Conv(void) {
	unsigned long adcv_value = 0;
	u16 rounds = 16 * 16;//+2 bit
	for (u16 i = 0; i < rounds; i++){	
		ADCSRA |= (1 << ADSC); //запуск АЦП
		while ((ADCSRA & (1 << ADSC))); //ожидание окончания преобразования
		adcv_value += ADC;
	}
	return adcv_value >> (2 + 4);//+2 bit
}		

    u16 soft = ADCV_Conv();//+2 bit
    ledprint(soft, 5);

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 22:14:05
Starichok51
Dimon456, извини, выше я был не прав, а ты прав.
деление суммы на 8 и последующее деление на 8192 можно заменить одним делением на 65536.
а деление на 65536 после умножения на 5000 можно заменить отбрасыванием двух младших байтов, если на ассемблере делать.
slav0n писал(а):u16 rounds = 16 * 16;//+2 bit
16 * 16 = 256 выборок, а это дает +4 бита. но ты после сдвига оставляешь только 2 дополнительных бита.

Re: ATmega + 12bit ADC

Добавлено: Пт авг 13, 2021 22:20:53
Dimon456
slav0n, вот смотри
СпойлерИзображение
Добавлено after 4 minutes 26 seconds:
Starichok51 писал(а):деление суммы на 8
при делении на 8 он отбрасывает 3 младших бита, которые несут информацию.
slav0n писал(а):я тут поставил опору 4096
Не всегда можно опору уменьшить, к примеру у stm32f030f4p6 имеется вывод под опору, хотел уменьшить с 3.3В до 2.048, из-за того что чип урезанный и где-то что там внутри не так спаяно, одним словом мк переставал работать.

Re: ATmega + 12bit ADC

Добавлено: Сб авг 14, 2021 06:15:24
slav0n
Dimon456 писал(а):при делении на 8 он отбрасывает 3 младших бита, которые несут информацию.
правильно, потому что там она бесполезна
но при этом я сохраняю 3 дополнительных бита с весьма полезной информацией
а ты мне предлагаешь сдвинуть сразу на 6 бит и все уничтожить
не, так не пойдет

Добавлено after 26 minutes:
кстати, ранее был вопрос про цифры [uquote="parovoZZ",url="/forum/viewtopic.php?p=4074682#p4074682"][uquote="Starichok51",url="/forum/viewtopic.php?p=4074597#p4074597"]тут всё до предела просто:
сумма 4 выборок добавляет 1 бит.
сумма 16 выборок добавляет 2 бита.
сумма 64 выборок добавляет 3 бита.
сумма 256 выборок добавляет 4 бита.
сумма 1024 выборок добавляет 5 бит.[/uquote]
это теорема какая-то или что? Откуда взяты эти цифры?[/uquote]
4 = 1 бит + 1 бит
16 = 2 бита + 2 бита
64 = 3 бита + 3 бита
256 = 4 бита + 4 бита
1024 = 5 бит + 5 бит

Добавлено after 36 minutes 38 seconds:
Dimon456 писал(а):slav0n, вот смотри
и что я вижу - софтовый оверсемплинг меги лучше хардового 12бит ацп

Re: ATmega + 12bit ADC

Добавлено: Сб авг 14, 2021 17:43:41
Dimon456
slav0n писал(а):и что я вижу - софтовый оверсемплинг меги лучше хардового
Ты слишком то не радуйся, это же протеус, там все идеально.

Я сейчас глянул мануал на stm32f030

Код: Выделить всё

Bit 4:3 RES[1:0]: Data resolution
These bits are written by software to select the resolution of the conversion.
00: 12 bits
01: 10 bits
10: 8 bits
11: 6 bits
Давай проверим в реальном железе, но будем использовать тот шум который есть, то есть без добавления шума на опору? Это вопрос, жду ответа.

Re: ATmega + 12bit ADC

Добавлено: Сб авг 14, 2021 18:34:18
slav0n
к сожалению с железками придется подождать, сломал ногу, еще месяц в гипсе.
А пока вот моя гифка симуляции:
СпойлерИзображение

Re: ATmega + 12bit ADC

Добавлено: Сб авг 14, 2021 20:20:05
Dimon456
Я прогнал 10 бит
Спойлер

Код: Выделить всё

	  ADC1->CFGR1 |= (uint32_t)(ADC_Resolution_10b | ((uint32_t)(1) << 13) |
			  ADC_ExternalTrigConvEdge_None  |
			  ADC_DataAlign_Right | ADC_ScanDirection_Upward);

#define ARRAYSIZE 2*64

Umax_adc = 3300;

          	for( uint8_t s = 0; s< ARRAYSIZE; s++)
          	{
          		ain[0] += ADC_values[s++];
          		ain[1] += ADC_values[s];
          	}			  
			  ain[0] = (uint16_t) (ain[0] >> 3);
			  ain[1] = (uint16_t) (ain[1] >> 3);
			  
			tlong = ain[0];
			tlong = (uint32_t)((tlong * (uint32_t)Umax_adc)/(1024 << 3));       // 10 бит			  
			u_izm = tlong;		// 0-30 В  
Данные измерения
Спойлер

Код: Выделить всё

На выходе	4,996В		10 бит									
												
											DAC +0,01В		АЦП
		ADC_values[0]	153									
		ADC_values[2]	154							497		5,00
		ADC_values[4]	154							498		5,01
		ADC_values[6]	153							499		5,01
		ADC_values[8]	153							500		5,02
		ADC_values[10]	154							501		5,03
		ADC_values[12]	153							502		5,04
		ADC_values[14]	154							503		5,05
		ADC_values[16]	154							504		5,06
		ADC_values[18]	154							505		5,07
		ADC_values[20]	153							506		5,08
		ADC_values[22]	154							507		5,09
		ADC_values[24]	154							508		5,10
		ADC_values[26]	153							509		
		ADC_values[28]	154									
		ADC_values[30]	153									
		ADC_values[32]	154									
		ADC_values[34]	153									
		ADC_values[36]	154									
		ADC_values[38]	153																	
		ADC_values[40]	153									
		ADC_values[42]	153									
		ADC_values[44]	155									
		ADC_values[46]	154									
		ADC_values[48]	153									
		ADC_values[50]	154									
		ADC_values[52]	154									
		ADC_values[54]	153									
		ADC_values[56]	153									
		ADC_values[58]	153									
		ADC_values[60]	154									
		ADC_values[62]	154									
		ADC_values[64]	153									
		ADC_values[66]	154									
		ADC_values[68]	153									
		ADC_values[70]	153									
		ADC_values[72]	153									
		ADC_values[74]	154									
		ADC_values[76]	153									
		ADC_values[78]	153									
		ADC_values[80]	154									
		ADC_values[82]	154									
		ADC_values[84]	154									
		ADC_values[86]	154									
		ADC_values[88]	153									
		ADC_values[90]	154									
		ADC_values[92]	153									
		ADC_values[94]	153									
		ADC_values[96]	151									
		ADC_values[98]	154									
		ADC_values[100]	153									
		ADC_values[102]	154									
		ADC_values[104]	154									
		ADC_values[106]	154									
		ADC_values[108]	154									
		ADC_values[110]	153									
		ADC_values[112]	154									
		ADC_values[114]	154									
		ADC_values[116]	154									
		ADC_values[118]	153									
		ADC_values[120]	154									
		ADC_values[122]	153									
		ADC_values[124]	153									
		ADC_values[126]	154									
																		
						9825		>>3	1228		499				
мне мало стало, еще 8 бит прогнал
Спойлер

Код: Выделить всё

	  ADC1->CFGR1 |= (uint32_t)(ADC_Resolution_8b | ((uint32_t)(1) << 13) |
			  ADC_ExternalTrigConvEdge_None  |
			  ADC_DataAlign_Right | ADC_ScanDirection_Upward);
			  
              ain[0] = (uint16_t) (ain[0] >> 1);
              ain[1] = (uint16_t) (ain[1] >> 1);

			tlong = ain[0];
			tlong = (uint32_t)((tlong * (uint32_t)Umax_adc)/(256 << 5));       // 8 бит			  
			u_izm = tlong;		// 0-30 В     
измерения
Спойлер

Код: Выделить всё

	4,996В		8 бит									
												
												DAC +0,01В	АЦП
		ADC_values[0]	38									
		ADC_values[2]	38							501		4,99
		ADC_values[4]	38							502		5,00
		ADC_values[6]	38							503		5,02
		ADC_values[8]	38							504		5,03
		ADC_values[10]	38							505		5,03
		ADC_values[12]	38							506		5,03
		ADC_values[14]	38							507		5,04
		ADC_values[16]	38							508		5,05
		ADC_values[18]	38							509		5,06
		ADC_values[20]	38							510		5,07
		ADC_values[22]	38							511		5,07
		ADC_values[24]	38							512		5,08
		ADC_values[26]	38							513		5,09
		ADC_values[28]	38							514		5,11
		ADC_values[30]	38									
		ADC_values[32]	38									
		ADC_values[34]	38									
		ADC_values[36]	38									
		ADC_values[38]	38									
		ADC_values[40]	38									
		ADC_values[42]	38									
		ADC_values[44]	38									
		ADC_values[46]	38									
		ADC_values[48]	38									
		ADC_values[50]	38									
		ADC_values[52]	38									
		ADC_values[54]	38									
		ADC_values[56]	38									
		ADC_values[58]	38									
		ADC_values[60]	38									
		ADC_values[62]	38									
		ADC_values[64]	38									
		ADC_values[66]	38									
		ADC_values[68]	38									
		ADC_values[70]	38									
		ADC_values[72]	38									
		ADC_values[74]	38									
		ADC_values[76]	38									
		ADC_values[78]	38									
		ADC_values[80]	38									
		ADC_values[82]	38									
		ADC_values[84]	38									
		ADC_values[86]	38									
		ADC_values[88]	38									
		ADC_values[90]	38									
		ADC_values[92]	38									
		ADC_values[94]	38									
		ADC_values[96]	38									
		ADC_values[98]	38									
		ADC_values[100]	38									
		ADC_values[102]	38									
		ADC_values[104]	38									
		ADC_values[106]	38									
		ADC_values[108]	38									
		ADC_values[110]	38									
		ADC_values[112]	38									
		ADC_values[114]	38									
		ADC_values[116]	38									
		ADC_values[118]	37									
		ADC_values[120]	38									
		ADC_values[122]	38									
		ADC_values[124]	38									
		ADC_values[126]	38									
																						
						2431		>> 1	1216		492				
DAC прибавляет строго по 0,01В.
У меня смещение задано относительно 0, для 12бит составляет -6 единиц АЦП, может по этому не соответствие 499 и 492.
На ножку АЦП подано с буферного ОУ через RC цепь, 200 Ом и 10нФ.

Еще используется скользящее среднее
Спойлер

Код: Выделить всё

// глубина буфера усреднения. чем больше, тем сильнее фильтрация и медленнее работа
// очень хорошо, если число кратно степени двойки (т.е. 1, 2, 4, 8, 16, 32, 64 и т.д.)
#define AVERAGE_DEPTH	K	//8
// функция получает результат очередного замера и возвращает отфильтрованное значение
uint16_t get_average_u(uint16_t val){
  static uint16_t buf[64];
  static uint8_t cur;
  uint32_t sum = 0;

  buf[cur++] = val;
  if(cur >= AVERAGE_DEPTH) cur = 0;

  for(uint8_t i=0; i < AVERAGE_DEPTH; i++) sum += buf[i];

  return sum / AVERAGE_DEPTH;
}
K = 8, я его пробовал в меню крутить, но так же на 8 оставил.

Re: ATmega + 12bit ADC

Добавлено: Вс авг 15, 2021 07:31:39
slav0n
Dimon456 писал(а):DAC прибавляет строго по 0,01В.
это фигня.
сделай шаг 0.001В в секунду