Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
28.02.2011, 17:54
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Стабилизация измерения АЦП ATMega8535
Доброе время всем.
Вобщем проблема наверное стара как мир. При измерении напряжения пляшет последний разряд. Каналов измерения 2, ADC7 и ADC6. Измеряемое напряжение подается пока на один канал ADC6. Оба канала имеют в своем составе цепи фильтров. Опорное 2,55В, непосредственно в канал подается 1,27В.
Код выполнения АЦП сделан без прерываний и выглядит так:
Код:
|
void ADC (void){ //делаем АЦП
static unsigned char calculator_bufer_I[15]; //буфер фильтра тока среднее арифметическое
volatile unsigned char I_ADC; //переменная результат измерения I
static unsigned char flag_ADC_I; //флаг тригер разрешения ADC_I
static unsigned char calculator_bufer_U[15];//буфер фильтра напряжения среднее арифметическое
volatile unsigned char U_ADC; //переменная результат измерения U
static unsigned char flag_ADC_U; //флаг тригер разрешения ADC_U
if (flag_ADC==1){//Если разрешено АЦП (частота разрешений 8.928 кГц)
flag_ADC=1; //сбросили флаг запуска АЦП
divider_ADC=0; //обнулили счетчик времени установки флага flag_ADC
if (flag_ADC_I==0&&flag_ADC_U==0){//если оба флага 0 (так будет при первом заходе в функцию)
flag_ADC_U=1; //то устанавливаем 1 флаг ADC_U
}//в дальнейшем эта функция не работает потому что 1 из флагов всегда установлен 1
/***************ADC_U***********************/
if (((ADCSRA&(1‹‹6))==0)&&flag_ADC_U==1){//Если завершено АЦП и разрешено АЦП в этом канале
I_ADC=ADCH; //передали значение тока в переменную
calculator_bufer_I[14]=calculator_bufer_I[13];
calculator_bufer_I[13]=calculator_bufer_I[12];
calculator_bufer_I[12]=calculator_bufer_I[11];
calculator_bufer_I[11]=calculator_bufer_I[10];
calculator_bufer_I[10]=calculator_bufer_I[9];
calculator_bufer_I[9]=calculator_bufer_I[8];
calculator_bufer_I[8]=calculator_bufer_I[7];
calculator_bufer_I[7]=calculator_bufer_I[6];
calculator_bufer_I[6]=calculator_bufer_I[5];
calculator_bufer_I[5]=calculator_bufer_I[4];
calculator_bufer_I[4]=calculator_bufer_I[3];
calculator_bufer_I[3]=calculator_bufer_I[2];
calculator_bufer_I[2]=calculator_bufer_I[1];
calculator_bufer_I[1]=calculator_bufer_I[0];
calculator_bufer_I[0]=I_ADC;
izmerenoe_I=(calculator_bufer_I[0]+calculator_bufer_I[1]+calculator_bufer_I[2]+calculator_bufer_I[3]
+calculator_bufer_I[4]+calculator_bufer_I[5]+calculator_bufer_I[6]+calculator_bufer_I[7]
+calculator_bufer_I[8]+calculator_bufer_I[9]+calculator_bufer_I[10]+calculator_bufer_I[11]
+calculator_bufer_I[12]+calculator_bufer_I[13]+calculator_bufer_I[14])/15;
indy_I=izmerenoe_I; //переменной которую будем передавать в индикацию присваиваем то что намерили (Ток)
ADMUX=0b00100111; //Выбрали канал измерения ADC7 напряжение
ADCSRA=0b11000111; //делитель 128
flag_ADC_I=1; //разрешили ADC_I
flag_ADC_U=0; //запретили ADC_U
}
/***************ADC_I***********************/
if (((ADCSRA&(1‹‹6))==0)&&flag_ADC_I==1){//Если завершено АЦП и разрешено АЦП в этом канале
U_ADC=ADCH; //передали значение напряжения в переменную
calculator_bufer_U[14]=calculator_bufer_U[13];
calculator_bufer_U[13]=calculator_bufer_U[12];
calculator_bufer_U[12]=calculator_bufer_U[11];
calculator_bufer_U[11]=calculator_bufer_U[10];
calculator_bufer_U[10]=calculator_bufer_U[9];
calculator_bufer_U[9]=calculator_bufer_U[8];
calculator_bufer_U[8]=calculator_bufer_U[7];
calculator_bufer_U[7]=calculator_bufer_U[6];
calculator_bufer_U[6]=calculator_bufer_U[5];
calculator_bufer_U[5]=calculator_bufer_U[4];
calculator_bufer_U[4]=calculator_bufer_U[3];
calculator_bufer_U[3]=calculator_bufer_U[2];
calculator_bufer_U[2]=calculator_bufer_U[1];
calculator_bufer_U[1]=calculator_bufer_U[0];
calculator_bufer_U[0]=U_ADC;
izmerenoe_U=(calculator_bufer_U[0]+calculator_bufer_U[1]+calculator_bufer_U[2]+calculator_bufer_U[3]
+calculator_bufer_U[4]+calculator_bufer_U[5]+calculator_bufer_U[6]+calculator_bufer_U[7]
+calculator_bufer_U[8]+calculator_bufer_U[9]+calculator_bufer_U[10]+calculator_bufer_U[11]
+calculator_bufer_U[12]+calculator_bufer_U[13]+calculator_bufer_U[14])/15;
indy_U=izmerenoe_U; //переменной которую будем передавать в индикацию присваиваем то что намерили (Напряжение)
ADMUX=0b00100110; //выбрали канал измерения ADC6 ток
ADCSRA=0b11000111; //делитель 128
flag_ADC_U=1; //разрешили ADC_U
flag_ADC_I=0; //запретили ADC_I
}
}
} |
В принципе все просто. Обращение к функции идет достаточно часто, в функцию заходим по флагу, каналы запускаем по совпадению.
Всеб и хорошо только пляшет последний разряд. Заметил какойто странный эфект, если при вычислении среднего арифметического делить не на кличество элементов масива ( 15), а делить на 14 то результаты измерения стабиллизируются но завышаются на на 8-9В. Другими словами вместо 127В получается 136В. Конечно некоторая не стабильность есть но очень весьма не значительная раз в минуту или может и в 3 минуты с 136 прыгает на 137 и последняя цыфра подрагивает но глазами увидеть чтото не представляется возможным, скорей всего не успевает отобразится какоето изменение. Вобщем можно сказать что последний разряд стоит железно бетонно. Но только вот не задача масива 15 байт. Такое усреднение должно бы железобетонно поставить значение. Но не ставит. Если суму элементов масива делить не на количество элементов масива 15, а на 14 то выводимое значение должно быть в районе 255, а выводит 136.
В чем может быть секрет.
|
|
|
|
28.02.2011, 18:01
|
|
Гуру портала
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
если бы ваш код был читабельным, можно было бы вкурить и решить проблему. А пока кажется только, что тип переменной выбран не верно.
Я использую переменную длинной в 2 байта. 10 бит ацп складываю в нее 64 раза, затем беру старший байт - это и есть хорошие, фильтрованные 8 бит АЦП без всякого дрожания.
Последний раз редактировалось Easyrider83; 28.02.2011 в 18:05.
|
|
|
Сказали "Спасибо" Easyrider83
|
|
|
28.02.2011, 18:12
|
|
Прописка
Регистрация: 16.07.2010
Сообщений: 150
Сказал спасибо: 19
Сказали Спасибо 29 раз(а) в 23 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Сообщение от 7Fantomas7
|
Если суму элементов масива делить не на количество элементов масива 15, а на 14 то выводимое значение должно быть в районе 255, а выводит 136.
В чем может быть секрет.
|
В программе количество элемнтов массива - 15, а делите вы их на 14, вот и выходит завышение значения в результате. Для эксперимента попробуйте выкинуть один элемент массива и не будет превышения на 8-9В.
И схему канала АЦП можно увидеть?
Последний раз редактировалось Zeman1979; 28.02.2011 в 18:15.
|
|
|
Сказали "Спасибо" Zeman1979
|
|
|
28.02.2011, 18:48
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Easyrider83,
Цитата:
|
если бы ваш код был читабельным
|
А читабельным это как? Куда уж читабельнее?
Цитата:
|
Я использую переменную длинной в 2 байта. 10 бит ацп складываю в нее 64 раза
|
Я беру масив 15 байт и в принципе делаю тоже, суммирую. Только беру не 10 бит АЦП а 8 старших. В принципе те же яйца только вид с боку.
Так как необходимо по результатам АЦП регулировать ШИМ (отображение дело совсем пятое) то необходима максимально быстрая реакция на реальное изменение измеряемой величины. Конечно понятно что без усреднения не обойтись но увеличение размеров буфера в моем случае или записи результатов в вашем случае не позволяют адекватно реагировать на изменение измеряемой величины.
Zeman1979,
А Вы русский язык распознаете. Так по честному.
Я Вам приведу то что вы цитировали.
Цитата:
|
Если суму элементов масива делить не на количество элементов масива 15, а на 14 то выводимое значение должно быть в районе 255, а выводит 136.
В чем может быть секрет.
|
Водителям бронепоезда сообщаю пробовал и так и так, об чем и сказано. К вашему сведению я не спрашивал почему больше. Я спрашивал почему 136, а не 255.
|
|
|
|
28.02.2011, 19:55
|
|
Прописка
Регистрация: 16.07.2010
Сообщений: 150
Сказал спасибо: 19
Сказали Спасибо 29 раз(а) в 23 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Сообщение от 7Fantomas7
|
Zeman1979,
А Вы русский язык распознаете. Так по честному.
Я Вам приведу то что вы цитировали.
Цитата:
|
Если суму элементов масива делить не на количество элементов масива 15, а на 14 то выводимое значение должно быть в районе 255, а выводит 136. В чем может быть секрет.
|
Водителям бронепоезда сообщаю пробовал и так и так, об чем и сказано. К вашему сведению я не спрашивал почему больше. Я спрашивал почему 136, а не 255.
|
Хрошо объясню на примере.
Ваш массив, предположим намеряли вот такие значения:
calculator_bufer_I[14]=127;
calculator_bufer_I[13]=126;
calculator_bufer_I[12]=127;
calculator_bufer_I[11]=126;
calculator_bufer_I[10]=125;
calculator_bufer_I[9]=126;
calculator_bufer_I[8]=127;
calculator_bufer_I[7]=127;
calculator_bufer_I[6]=126;
calculator_bufer_I[5]=125;
calculator_bufer_I[4]=125;
calculator_bufer_I[3]=127;
calculator_bufer_I[2]=126;
calculator_bufer_I[1]=125;
calculator_bufer_I[0]=127;
Сумма значений =1892
Если вы делите на 14 то выходит 135, если делть на 15, то выйдет 126. 255 там никогда не возникнет, откуда вы взяли это число? Или я опять в бронепоезде?
Сообщение от 7Fantomas7
|
Опорное 2,55В, непосредственно в канал подается 1,27В.
|
Вот это я просмотрел.
Приведите опорное в соответсвие с измеряемым значением, сделайте 1,5В и будет вам счастье.
Сейчас у вас выходит, что цена младшего разряда 0,01В, а значение измеряется как раз до второго знака после запятой. Ошибка оцифровки удвоенное значение младшего разряда, следовательно у вас погрешность измерений составит 0,02В, отсюда и все прыжки младшего разряда.
Вот и если сделать 1,3В-1,5В опоры, то цена младшего разряда будет 0,0051-0,0059В, сразу станет легче жить.
Последний раз редактировалось Zeman1979; 28.02.2011 в 20:07.
|
|
|
|
28.02.2011, 19:58
|
|
Прописка
Регистрация: 26.01.2009
Сообщений: 249
Сказал спасибо: 23
Сказали Спасибо 102 раз(а) в 61 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Сообщение от 7Fantomas7
|
Всеб и хорошо только пляшет последний разряд. Заметил какойто странный эфект, если при вычислении среднего арифметического делить не на кличество элементов масива (15), а делить на 14 то результаты измерения стабиллизируются но завышаются на на 8-9В.
|
Все дело в том, что Вы плохо себе представляете, что происходит при делении. При определенных входных значениях напряжения последний разряд будет скакать при любом количестве элементов массива и при любом делителе.
При АЦ-преобразовании младший разряд будет гулять (из-за шумов питания, шумов опоры, шумов сигнала, близости к порогу и пр.).
Если все элемнты = 127, а один = 128, то получите
(127*14+128 )/15 = 127.0666 = 127 (при переводе в int)
Если все элементы = 127, а один = 126, то получите
(127*14+126)/15 = 126.9333 = 126
При гулянии любого измерения на +/- одну единицу младшего разряда Вы будете получать числа в пределах: (126*15)/15..(128*15/15), т.е. 126.0..128.0. Т.к. большинство измерений будет = 127 (а измерения с отклонениями будут взаимокомпенсировать друг друга), то значение будет скакать в районе 127 +/- лапоть. И т.к. при целочисленном делении дробная часть просто отбрасывается, то в большинстве случаев будут два результата: 126 и 127.
Когда Вы делите на 14, Вы получаете среднее значение чуть больше 136. И в этом случае помехи должны быть немного сильнее, чтобы он стал либо чуть меньше 136 (что у Вас и происходит раз в три минуты). Подайте на вход другое напряжение - и даже при делителе 14 получите те же скачки младшего разряда..
Цитата:
|
Если суму элементов массива делить не на количество элементов масива 15, а на 14 то выводимое значение должно быть в районе 255, а выводит 136.В чем может быть секрет.
|
Секрет - в плохом понимании мат. модели собственной программы. Откуда 255?
При опоре 2.55 и входе 1.27 Вы получаете 15 измерений с результатом 127.
15*127 = 1905
Это число делим на 14 - получаем 136.07.
Последний раз редактировалось testerplus; 28.02.2011 в 20:43.
|
|
|
Сказали "Спасибо" testerplus
|
|
|
28.02.2011, 22:14
|
|
Гражданин KAZUS.RU
Регистрация: 16.06.2005
Сообщений: 943
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Сообщение от 7Fantomas7
|
Заметил какойто странный эфект, если при вычислении среднего арифметического делить не на кличество элементов масива (15), а делить на 14 то результаты измерения стабиллизируются но завышаются на на 8-9В.
|
Во первых, при нахождении среднего, производится деление на 15. Зная качество оптимизации кодевижна (про стиль программирования пока промолчу ), можно предположить, что код весь получается весьма раздутый. В то же время, если брать 16 значений (интересно, откуда вообще взялось 15) то деление превратится всего лишь в 4 сдвига влево.
Во вторых, при делении не на число слагаемых, фактически выкидывается последний бит (про метод повышения разрядности тоже пока промолчу, нет его при среднем), с таким же успехом его можно сразу обнулять или ставить в 1 в только что измеренном значении.
|
|
|
|
28.02.2011, 22:15
|
|
Почётный гражданин KAZUS.RU
Регистрация: 24.09.2007
Сообщений: 1,437
Сказал спасибо: 287
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Zeman1979,
Цитата:
|
Или я опять в бронепоезде?
|
Не теперь я .
Цитата:
|
Приведите опорное в соответсвие с измеряемым значением, сделайте 1,5В и будет вам счастье
|
Не приведу, счастья не будет.
Мне необходимо мерять от 0 -255 например вольт с точностью 1вольт.
Просто я подал в качестве теста половину, подавал и 2,55 в принципе при четком среднем арифметическом соответвуют 1 в 1.
Так как я беру результаты измерений из регистра ADCH то это 8 бит, 2 бита из ADCL я просто игнорирую. Понятно что ADCH+ADCL выровнены по левому краю. Поэтому опору трогать не вижу смысла, сделано класически.
Цитата:
|
Секрет - в плохом понимании мат. модели собственной программы. Откуда 255?
При опоре 2.55 и входе 1.27 Вы получаете 15 измерений с результатом 127.
15*127 = 1905
Это число делим на 14 - получаем 136.07.
|
Признаю я тормознул.
Спасибо растолковали оченно доходчиво. Понятно все.
Только вот как из ситуации выйти другими словами застабилизировать как. Дело в том что если б был необходим показометр то может что и придумал бы. Этого добра в вроде как достаточно чтоб слизать. Только от результата измерения завист на прямую ШИМ. И если я сейчас даю в канал фильтрованую и стабильную постоянку и получаю такие дрова чтож будет если я подам 30 кГц импульсное да и еще с разным коэфициентом заполнения. Понятно что стоят RC цепи понятно что усреднение происходит еще до АЦП но сигнал то всеравно будет изменяться во времени.
|
|
|
|
28.02.2011, 22:59
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.10.2007
Адрес: Беларусь
Сообщений: 8,048
Сказал спасибо: 60
Сказали Спасибо 3,954 раз(а) в 2,309 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Если надо мерять 0...255 - 10 бит вам в руки. ОБЯЗАТЕЛЬНО нужны 2...3 "лишних" бита, которые сгладят эти "пол-шага". И частоту поставьте 5...10 ксэмплов (для авр), тогда фильтрация нужна будет чисто символическая. Резкие выбросы фильтровать
|
|
|
|
28.02.2011, 23:04
|
|
Прописка
Регистрация: 16.07.2010
Сообщений: 150
Сказал спасибо: 19
Сказали Спасибо 29 раз(а) в 23 сообщении(ях)
|
Re: Сбилизация измерения АЦП ATMega8535
Сообщение от 7Fantomas7
|
Не приведу, счастья не будет.
Мне необходимо мерять от 0 -255 например вольт с точностью 1вольт.
Просто я подал в качестве теста половину, подавал и 2,55 в принципе при четком среднем арифметическом соответвуют 1 в 1.
Так как я беру результаты измерений из регистра ADCH то это 8 бит, 2 бита из ADCL я просто игнорирую. Понятно что ADCH+ADCL выровнены по левому краю. Поэтому опору трогать не вижу смысла, сделано класически.
|
Ага, так да, получается младшие разряды выкинуты, так что шумы оцифровки поумолчанию откинуты.
Последний раз редактировалось Zeman1979; 28.02.2011 в 23:12.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 02:11.
|
|