Страница 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В в секунду