|
терморегулятор, помогите |
|
|
|
Jul 30 2008, 12:01
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Собираю терморегулятор. Готова динамическая индикация (спасибо форумчанам). Теперь проблема с АЦП. Цитата /***************************************************** Chip type : ATmega16 Clock frequency : 1,000000 MHz *****************************************************/ #include <mega16.h> char Dig[10]; // Массив, с кодами чисел для индикатора с общим анодом char i=0; // счетчик для переключения анодов char e=0; // единицы установленной температуры char d=0; // десятки char s=0; // сотни char s2=0; // единицы измеренной температуры char e2=0; // десятки char d2=0; // сотни char res=0; // в эту переменную поочереди записываются e,d,s или e2,d2,s2 char keys_prev=0; // две переменной для правильной работы кнопок char keys_now=0; // unsigned int current_temp=0; // измеренная температура short temp2=0; // временная переменная short set_temp=0; // установленная температура
char num (void) { // функция, для опроса клавиатуры, и вывода на катоды кода текущего разряда if (PINB.4!=0){ // если кнопка "нагрев" не нажата, то if ((keys_prev!=keys_now)&(PINB.0==0)) e++; // если нажата кнопка "единицы", то прибавить 1 к нулевому разряду (единицы) if (e==10) e=0; // если результат прибавления перевалил за 9, то сбросить его в нуль if ((keys_prev!=keys_now)&(PINB.1==0)) d++; // если нажата кнопка "десятки", то прибавить 1 к первому разряду (десятки) if (d==10) d=0; // если результат прибавления перевалил за 9, то сбросить его в нуль if ((keys_prev!=keys_now)&(PINB.2==0)) s++; // если нажата кнопка "сотни", то прибавить 1 к второму разряду (сотни) if (s==3) s=0; // если результат прибавления перевалил за 9, то сбросить его в нуль if (PINB.3==0) { // если нажата кнопка "сброс", то сбросить все разряды в нуль e=0; d=0; s=0;} switch (i) { // в зависимости от переменной i выбираем что показываем в текущий момент: единицы, десятки, или сотни case 0: res=e; break; case 1: res=d; break; case 2: res=s; break; } return res;} else { // если нажата кнопка "нагрев", то
current_temp=ADCL; // в переменную записываем значение из регистра ADCL current_temp+=((int)ADCH << 8); // прибавляем к переменной значение из регистра ADCH со сдвигом влево на 8 разрядов current_temp=current_temp/2.5; // преобразовываем (ADCH ADCL) в температуру. Т.к. используется внутренний ИОН 2560 мВ, то 2560/1024=2.5 e2=current_temp%10; // получаем единицы измеренной температуры temp2=current_temp/10; // промежуточная операция, для понижения степени d2=temp2%10; // получаем десятки измеренной температуры s2=temp2/10; // получаем сотни измеренной температуры // в зависимости от переменной i выбираем что показываем в текущий момент времени switch (i) { case 0: res=e2; break; case 1: res=d2; break; case 2: res=s2; break; } return res;
;}} // Timer 0 output compare interrupt service routine interrupt [TIM0_COMP] void timer0_comp_isr(void) //обработка прерывания таймера по совпадению с OCR0 { keys_prev=keys_now; //для клавиш keys_now=PINB; //читаем что нажато if (i==3) i=0; //если показатель текущего разряда перевалил за 2, то зажигаем нулевой разряд PORTC=Dig[num()]; //выставляем на катодах число, которое получаем из функции num() switch (i) { //в зависимости от переменной i поочередно подаем питание на аноды case 0: //если i=0, то включаем разряд для единиц PORTD.1=1; //гасим ненужные разряды PORTD.2=1; PORTD.0=0; //включаем нулевой разряд, активный уровень - 0,т.к. используются p-n-p break; case 1: // и т.д. PORTD.0=1; PORTD.2=1; PORTD.1=0; break; case 2: PORTD.0=1; PORTD.1=1; PORTD.2=0; break;} i++; }
// Declare your global variables here
void main(void) { PORTA=0x00; DDRA=0x00; PORTB=0xFF; DDRB=0x00; PORTC=0x00; DDRC=0xFF; PORTD=0x00; DDRD=0xFF;
// Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 0,977 kHz // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x0D; TCNT0=0x00; OCR0=0x03; //задаем частоту развертки. подбирал наглаз.
// Timer/Counter 1 initialization TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00;
// Timer/Counter 2 initialization ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00;
// External Interrupt(s) initialization MCUCR=0x00; MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x02;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // free running режим АЦП ADMUX=0xC0; // Внутренний источник опорного напряжения 2.56В REFS1..0=1; правое выравнивание ADLAR=0,вход ADC0 ADCSRA=0xE4; //ADEN=1(включили АЦП),ADSC=1(начали преобразование),ADATE:1(авто триггер включен),ADIE=0(прерывания от АЦП нам не нужны), делитель на 16
// заполняем массив комбинациями нулей/единиц для катодов Dig[0] = 0xC0; Dig[1] = 0xF9; Dig[2] = 0xA4; Dig[3] = 0xB0; Dig[4] = 0x99; Dig[5] = 0x92; Dig[6] = 0x82; Dig[7] = 0xF8; Dig[8] = 0x80; Dig[9] = 0x90;
#asm("sei") // включаем прерывания while (1) { if (PINB.4==0) { // если нажата кнопка "нагрев", то set_temp=e+d*10+s*100; // вычисляем установленную температуру, исходя из того, что в переменных e,d,s if (current_temp<(set_temp-1)) {PORTD.3=1;}; //если текущая температура ниже установленной на 1 градус, то включаем релюшку if (current_temp>=set_temp) {PORTD.3=0;};} //если текущая температура больше или равна установленной, то выключаем релюшку else {PORTD.3=0;}; }; //если кнопка "нагрев" не нажата, то реле должно быть выключенным. } // game over почему-то в Proteus переменные e2,s2,d2 неправильно считаются. Залил в мегу - на индикаторе 409. Когда использовал прерывание АЦП, то у меня все работало. Но хочется упростить немного код (пусть хоть потребляет больше) Схемку прилагаю. Подскажите что не так, я уже не знаю чего делать.
Эскизы прикрепленных изображений
|
|
|
|
|
 |
Ответов
(1 - 91)
|
Jul 30 2008, 12:31
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Lost_Viking @ Jul 30 2008, 18:01)  почему-то в Proteus переменные e2,s2,d2 неправильно считаются. Залил в мегу - на индикаторе 409. А сколько должно быть? Смущает вот что: Код current_temp=current_temp/2.5; // преобразовываем (ADCH ADCL) в температуру. Т.к. используется внутренний ИОН 2560 мВ, то 2560/1024=2.5 Во-первых, current_temp у вас unsigned int, то есть это эквивалентно current_temp=current_temp/2. Во-вторых, не вижу здесь вычисления значения температуры, вижу только вычисление напряжения. ЗЫ. Для форматирования кода - кнопочка "код", а не "цитата":)
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 30 2008, 12:40
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Код current_temp=current_temp/2.5; // преобразовываем (ADCH ADCL) в температуру. Т.к. используется внутренний ИОН 2560 мВ, то 2560/1024=2.5 то есть 1 дискрет АЦП = 2,5 мВ. Причём тогда тут деление? Наверно, умножить надо? Получим Uadc в милливольтах ещё такая штучка: x*2.5=(x<<1)+(x>>1)
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 30 2008, 17:04
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(=GM= @ Jul 30 2008, 19:50)  У вас на самом деле последовательно с транзисторами стоят сопротивления 1 Ом? Не боитесь попалить МК и индикатор?
Последовательно с диодом D1 надо бы включить сопротивление, а то и здесь всё попалите. нет, номиналы там от балды. Не от балды - катушка, емкости, и резистор к питанию АЦП Цитата(domowoj @ Jul 30 2008, 19:26)  Протеус 7.2 .2 с авр работает глючно!!! Мегу 16 не проверял, а 8535 и тиньки - глюк, особенно что касаемо АЦП. По заверениям разработчиков в версии 7.3 глюки обещали исправить. Ждем-с. АЦП в протеусе у меня работает, по крайней мере так говорит ADCL регистр. Но были замеченны другие глюки, например глюкаво работает динамическая индикация. Цитата(MrYuran @ Jul 30 2008, 16:40)  Код current_temp=current_temp/2.5; // преобразовываем (ADCH ADCL) в температуру. Т.к. используется внутренний ИОН 2560 мВ, то 2560/1024=2.5 то есть 1 дискрет АЦП = 2,5 мВ. Причём тогда тут деление? Наверно, умножить надо? Получим Uadc в милливольтах просто я это так назвал "температурой", ну то, что пропорционально. Насчет деления ты прав. Это я что-то ступил, но сути все равно не изменит Цитата(AHTOXA @ Jul 30 2008, 16:31)  А сколько должно быть? число от 0 до ... Т.е. кручу переменник - меняется на нем падение напряжения, которое приложенно ко входу АЦП. Заметил такую вещь: подал на вход АЦП напряжение (1;2;3 вольта) от блока питания - показания изменились. При напряжении 3 вольта опять выдало 409. По сути это 2,56 вольта. Поставил добавочное сопротивление ко входу АЦП, опять все вернул на места (по схеме) - ничего не изменилось, все равно 409. Как ни крути переменник. Померил напряжометром - напряжение действительно >2.56В, амперметр включенный между переменником и входом АЦП вообще ничего не показал. Чудеса. Цитата(AHTOXA @ Jul 30 2008, 16:31)  Смущает вот что: Код current_temp=current_temp/2.5; // преобразовываем (ADCH ADCL) в температуру. Т.к. используется внутренний ИОН 2560 мВ, то 2560/1024=2.5 Во-первых, current_temp у вас unsigned int, то есть это эквивалентно current_temp=current_temp/2. да и там вместо деления умножение должно быть. просто на скорую руку переписал код - сделал без прерывания, и влезли некоторые оплошности. Надо будет погрешность пересчитать теперь... Цитата(AHTOXA @ Jul 30 2008, 16:31)  Во-вторых, не вижу здесь вычисления значения температуры, вижу только вычисление напряжения. Ну, блин!  Мне для теста хотя бы напряжение показать, а коэффициенты пересчета для температуры потом введу Цитата(AHTOXA @ Jul 30 2008, 16:31)  ЗЫ. Для форматирования кода - кнопочка "код", а не "цитата":) писал на работе, юзая gprs internet Megafon. В целях экономии траффика отключил все картинки, и почему-то вместо (code) вставилось (quote). Сообщение не перечитывал, т.к. рабочий день подходил к концу. sorry
Сообщение отредактировал Lost_Viking - Jul 30 2008, 17:10
|
|
|
|
|
Jul 30 2008, 18:56
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(AHTOXA @ Jul 30 2008, 21:31)  А как соотносятся номиналы R1 и переменника? Может переменник просто большой и не до конца выкручивается?  на работе у меня целая гора переменников разных номиналов. все перепробовал - ну ни как! а вот с блока питания напрямую напряжение на вход АЦП - все работает. чудеса. завтра поколдую. Цитата(defunct @ Jul 30 2008, 21:45)  Уберите их вообще, вместо них поставьте резисторы 390-510om между пинами МК и сегментами индикатора (ABC..GH). Чтобы яркость цифр не менялась взависимости от заполнения. Транзисторы должны быть расчитаны на ток не менее 100ma. упс, извинясь. просто эта схема взята из Proteus'а, и я туда специально воткнул эти резисторы, т.к. без них в протеусе транзисторы не закрывались (чудеса протеуса!). в реале их у меня нет. Люди, скажите как вычислить абсолютную погрешность, если учесть, что два младших разряда АЦП по даташиту грешат,плюс округление с real до integer? Т.е. имеем результат измерения 0010101100, младшие 2 разряда могут быть любыми, т.к. по даташиту абсолютная погрещность АЦП +/- 2 младших разряда. Далее, этот результат (dec(172)) умножаем на коэф.пересчета напряжения в температуру, например 2.6, и заносим в переменную unsigned int, соответственно все, что после точки отбрасывается. Пока попробую в Excel'e покумекать на катодах у меня по 100 Ом в реале стоят (вроде бы). Завтра гляну. Транзюки нормальные стоят. Короче, индикация работает на ура! А АЦП что-то мне в морду плюет
Сообщение отредактировал Lost_Viking - Jul 30 2008, 19:04
|
|
|
|
|
Jul 31 2008, 06:26
|
Группа: Новичок
Сообщений: 11
Регистрация: 8-02-08
Пользователь №: 34 857

|
Цитата(Lost_Viking @ Jul 30 2008, 21:56)  Короче, индикация работает на ура! А АЦП что-то мне в морду плюет Если Вы пробовали подавать разное напряжение на вход АЦП, и на индикаторе отбражалость новое число, значит ваш девайс работает правильно.. Попробуйте замерять мультиметром напряжения на входе АЦП во время подключения к нему переменного резистора, если крутить ручку, и мультиметр будет показывать разные напряжения, то и девас покажет новое значение. Если нет, проверьте номинал переменного резистора он не должен быть слышком большим.. У меня для таких целей 5,1-33кОм прекрасно работают.. Странно, если вы убрали прерывания от АЦП, то где вы считываете текущее значение с регистра данных АЦП? Я бы поставил его в main. т.е. как я понял у вас данные считываються с АЦП только один раз при включении.
|
|
|
|
|
Jul 31 2008, 06:42
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Lost_Viking @ Jul 30 2008, 22:56)  Люди, скажите как вычислить абсолютную погрешность, если учесть, что два младших разряда АЦП по даташиту грешат Я что-то вообще не понял, что за датчик, схема какая-то трудночитабельная. Вообще, имхо, на АВР очень хитро вывернувшись можно, наверно, получить погрешность в пределах +/- 1 градуса... Это при условии калибровки. Про нестабильность внутренней опоры тоже надо подумать...
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 31 2008, 10:08
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(AVRdeveloper @ Jul 31 2008, 10:26)  Если Вы пробовали подавать разное напряжение на вход АЦП, и на индикаторе отбражалость новое число, значит ваш девайс работает правильно..
Попробуйте замерять мультиметром напряжения на входе АЦП во время подключения к нему переменного резистора, если крутить ручку, и мультиметр будет показывать разные напряжения, то и девас покажет новое значение. Если нет, проверьте номинал переменного резистора он не должен быть слышком большим.. У меня для таких целей 5,1-33кОм прекрасно работают.. Странно, если вы убрали прерывания от АЦП, то где вы считываете текущее значение с регистра данных АЦП? Я бы поставил его в main. т.е. как я понял у вас данные считываються с АЦП только один раз при включении. Там сделано гораздо проще: АЦП преобразовывает все время, т.к. находится в режиме free run, и его не нужно все время запускать. Ну, а значения берутся из АЦП с частотой, равной частоте развертки, т.е. регулируется регистром OCR0. Там при каждом совпадении таймера с OCR0 вызывается фнукция обработчика прерывания: Код interrupt [TIM0_COMP] void timer0_comp_isr(void) в ней есть комманда: Код PORTC=Dig[num()] где num() - это функция, где при нажатой кнопке "нагрев" значения из ADCL и ADCH (ну или в CodevisionAvr - ADCW) помещаются в переменную current_temp. Далее это значение разбивается на 3 десятичных разряда. Вобщем, я понял в чем ошибка. Смотрите схему. Слева - как было, справа - как стало. Т.е. теперь снимаю напряжение фактически с делителя. Может кто-нибудь объяснить почему при включении, что слева, АЦП не понимает в чем дело? Я не совсем понимаю.
Сообщение отредактировал Lost_Viking - Jul 31 2008, 10:26
Эскизы прикрепленных изображений
|
|
|
|
|
Jul 31 2008, 10:55
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(MrYuran @ Jul 31 2008, 10:42)  Я что-то вообще не понял, что за датчик, схема какая-то трудночитабельная. Вообще, имхо, на АВР очень хитро вывернувшись можно, наверно, получить погрешность в пределах +/- 1 градуса... Это при условии калибровки. Про нестабильность внутренней опоры тоже надо подумать... датчиком будет какой-нибудь терморезистор, или транзистор. А пока для опытов вместо датчика использую обычный переменник на 2.4 кОм. А такую погрешность можно получить и не выворачиваясь. Самое главное питание стабилизировать. Насчет внутренней опоры я не подумал. Насколько она нестабильна?
|
|
|
|
|
Jul 31 2008, 11:05
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(Lost_Viking @ Jul 31 2008, 14:55)  датчиком будет какой-нибудь терморезистор, или транзистор. Какой именно? Платиновый точно не подойдёт, только термистор. У него характеристика покруче, но нелинейная. Цитата Насчет внутренней опоры я не подумал. Насколько она нестабильна? по даташиту +/- 0,1В, то есть почти +/-5%
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Jul 31 2008, 11:19
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(AHTOXA @ Jul 31 2008, 14:53)  А в исходной схеме нарисовано как справа  опа  . Ну да, помнится у меня как раз и не получалось что-то, а потом сделал делитель. Только при сборке я про это забыл. Цитата(AHTOXA @ Jul 31 2008, 14:53)  В левой схеме тоже получается делитель, но его нижнее сопротивление равно бесконечности. Потому на выходе получается всё время 5в. Эммм. погоди, а почему? Разве падение напряжения на резисторе будет все время 5В независимо от положения ползунка? Что-то у меня с физикой напряги стали... Теперь заметил проблему: все время скачет младшая цифра, причем очень быстро. Думаю, что это либо из-за паразитных 50Гц пульсаций, или же как раз погрешность АЦП в 2 младших разряда его 10-и битного результата. Сейчас попробую ADLAR=1 сделать, и читать 8 бит из ADCH.
|
|
|
|
|
Jul 31 2008, 11:37
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(GDI @ Jul 31 2008, 17:11)  Отнють не бесконечности, а равно входному сопротивлению АЦП, которое составляет около 100к (имеющие даташит под руками меня поправят если что) Я писал про делитель, а не про всю схему. А так - да, входное сопротивление снизу. Цитата(Lost_Viking @ Jul 31 2008, 17:19)  Эммм. погоди, а почему? Разве падение напряжения на резисторе будет все время 5В независимо от положения ползунка? Что-то у меня с физикой напряги стали... Падение будет 0в. Ибо току течь некуда, он равен нулю  U=IR. Закон Ома  Цитата(Lost_Viking @ Jul 31 2008, 17:19)  Теперь заметил проблему: все время скачет младшая цифра, причем очень быстро. Думаю, что это либо из-за паразитных 50Гц пульсаций, или же как раз погрешность АЦП в 2 младших разряда его 10-и битного результата. Сейчас попробую ADLAR=1 сделать, и читать 8 бит из ADCH. Чтобы младший разряд не скакал, надо сделать всё очччень аккуратно. Отвязать аналоговое питание, аккуратно развести, и проч. и проч. Можно программно фильтровать. А можно отбросить младшие разряды, если точности 9 или 8 разрядов будет достаточно.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jul 31 2008, 11:55
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(GDI @ Jul 31 2008, 14:11)  Отнють не бесконечности, а равно входному сопротивлению АЦП, которое составляет около 100к (имеющие даташит под руками меня поправят если что) Посмотрите рисунок "Analog Input Circuitry" Fig. 105 в ДШ на m16. Как эти 100k подключены и на что нагружены. Для постоянного тока эквивалентная схема: --Rвнешн----Rвнутр----"вникуда". Rвнутр + "вникуда" => бесконечность.
|
|
|
|
|
Jul 31 2008, 11:56
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Хочу уточнить чтобы не было иллюзий. В левой схеме где ножка переменного резистора не подсоединена к земле, нижним плечем делителя является входное сопротивление АЦП, и диаразон регулировки схемы зависит от сопротивления переменного резистора. Например, если полное сопротивление переменного резистора 100к и входное сопротивление АЦП тоже 100к, то диапазон будет ~0-50% (2,56 - 1,28 В, к примеру), если резистор будет 10к, то диапазон получится порядка 0-10%
P.S. Входное сопротивление всегда считается от земли в однополярной схеме.
--------------------
|
|
|
|
|
Jul 31 2008, 11:57
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Lost_Viking @ Jul 31 2008, 14:19)  Теперь заметил проблему: все время скачет младшая цифра, причем очень быстро. 1. TL431 ему в опору, чтоб не баловался. 2. Noise canceler ему в мозги, иначе у младшего разряда нервный тик не пройдет. 3. Накопление методом скользящего среднего вне зависимости от того, удался ли п.2. Что же Вы, уважаемый, плохо воспитываете свой девайс ?
|
|
|
|
|
Jul 31 2008, 12:04
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(GDI @ Jul 31 2008, 14:56)  P.S. Входное сопротивление всегда считается от земли в однополярной схеме. Схема входа АЦП: ---R---C--GND Цитата В левой схеме где ножка переменного резистора не подсоединена к земле, нижним плечем делителя является входное сопротивление АЦП, и диаразон регулировки схемы зависит от сопротивления переменного резистора. Все вами сказанное относится только к переменке и сильно зависит от частоты сигнала. Для постоянного тока входное сопротивление АЦП стремится к бесконечности. Иначе как по вашему АЦП выдает всегда одинаковый результат при постоянном Vinp, независимо от выходного сопротивления источника сигнала. Иными словами в левой схеме положение переменного резистора может управлять только лаем собак на луну.
|
|
|
|
|
Jul 31 2008, 14:47
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(_Pasha @ Jul 31 2008, 15:57)  1. TL431 ему в опору, чтоб не баловался. 2. Noise canceler ему в мозги, иначе у младшего разряда нервный тик не пройдет. 3. Накопление методом скользящего среднего вне зависимости от того, удался ли п.2. Что же Вы, уважаемый, плохо воспитываете свой девайс ?  1. насчет TL431 мне тоже пришла идея. А 78L05 пойдет? Только я не помню: 78 - это для плюса, а 79 - это для минуса? Или наоборот? 2. шозах?  что-то слышал об этом, вроде даже в даташите. 3. По-подробнее плиз. Сдается мне, что в этом пункте я еще больше внесу погрешность измерения. Просто я пока еще молодой папа  Цитата(defunct @ Jul 31 2008, 16:04)  Иными словами в левой схеме положение переменного резистора может управлять только лаем собак на луну. подтверждаю  Хотя немножко напряжение на входе АЦП регулировалось. Совсем чуть-чуть. Переменник 2.4кОм. Цитата(xemul @ Jul 31 2008, 17:01)  Типовое значение для входного сопротивление АЦП указано в таблице "ADC Characteristics" как 100 МОм. предлагаю Мегометром брякнуть его  Нашел я инфу про ADC Noise Reduction. Как стремно это дело работает: все выключается на время преобразования. Бррр... Щаззз проверим.
Сообщение отредактировал Lost_Viking - Jul 31 2008, 14:01
Эскизы прикрепленных изображений
|
|
|
|
|
Jul 31 2008, 14:54
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Jul 31 2008, 18:47)  3. По-подробнее плиз. Сдается мне, что в этом пункте я еще больше внесу погрешность измерения. Это будет погрешность обработки. Если будете правильно округлять, то внесете не более 0.5 LSB. Цитата предлагаю Мегометром брякнуть его  Есть китайские мультиметры с пределом 200 МОм, на шупах при этом не более 2 В. Корректнее по отношению к АЦП измерять его входной ток, а дальше по закону Ома относительно AVcc/2.
|
|
|
|
|
Jul 31 2008, 15:29
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Jul 31 2008, 18:54)  Это будет погрешность обработки. Если будете правильно округлять, то внесете не более 0.5 LSB. можешь хотя бы примерно рассказать про данный метод? или, хотя бы, алгоритм если есть. Цитата(xemul @ Jul 31 2008, 18:54)  Есть китайские мультиметры с пределом 200 МОм, на шупах при этом не более 2 В. Корректнее по отношению к АЦП измерять его входной ток, а дальше по закону Ома относительно AVcc/2. у меня есть советский измеритель сопротивления изоляции. там ручка есть такая волшебная: раскручиваешь ее, и на выходе привет  сдается мне, что придется опять использовать прерывание АЦП. Это даже к лучшему. Мне вот что интересно: когда я начинаю читать данные из ADCL, то работа АЦП останавливается, пока я не прочту данные из ADCH? Так или нет? Кстати, катушку поставил с индуктивностью 40мкГн, а емкость 0.1мкФ. Такие номиналы вычитал где-то в инете. Просто катушку 10мкГн не нашел
Сообщение отредактировал Lost_Viking - Jul 31 2008, 15:41
|
|
|
|
|
Jul 31 2008, 17:05
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(Lost_Viking @ Jul 31 2008, 17:47)  78 - это для плюса да Цитата(Lost_Viking @ Jul 31 2008, 17:47)  2. шозах?  что-то слышал об этом, вроде даже в даташите. на время преобразования АЦП ядро МК уходит в спячку и просыпается по прерыванию окончания преобразования АЦП. Цитата(Lost_Viking @ Jul 31 2008, 17:47)  1. насчет TL431 мне тоже пришла идея. А 78L05 пойдет? термостабилизация конечно же лучше у TL431, но на худший случай пойдёт. Цитата(Lost_Viking @ Jul 31 2008, 17:47)  а 79 - это для минуса? Или наоборот? гугле - 79L05 Datasheet pdf - Negative-Voltage Regulators Цитата(Lost_Viking @ Jul 31 2008, 18:29)  можешь хотя бы примерно рассказать про данный метод? или, хотя бы, алгоритм если есть. очень просто скользящее среднее, тоже о скользещем среднем
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Jul 31 2008, 17:17
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Jul 31 2008, 19:29)  можешь хотя бы примерно рассказать про данный метод? или, хотя бы, алгоритм если есть. Метод - просто какой-либо НЧ фильтр в цифре. Простейший НЧ фильтр 1-го порядка: Yi = a * Yi-1 + b * Xi, a+b = 1 Т.е. Код Y = a * Y + b * X; Для целочисленной арифметики удобно делать a=c/2^N, b=(2^N-c)/2^N. Чтобы не набегала погрешность при обработке, разрядность Y должна быть не менее (разрядность X) + N. Найдите что-нибудь вроде "Цифровые фильтры" Р. Хемминга - там все доступно.
|
|
|
|
|
Jul 31 2008, 17:38
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(sKWO @ Jul 31 2008, 21:05)  как я понял - это просто среднее какое-то значение. блин, и там погрешность, и тут ... Цитата(xemul @ Jul 31 2008, 21:17)  Найдите что-нибудь вроде "Цифровые фильтры" Р. Хемминга - там все доступно.  я умер от этой книги. ничего не понял. мне проще стабилизировать опорное напряжение и питание, чем разобраться в этих греческих символах Нашел вот что.Я смотрю там через операционник подают измеряемое напряжение. Только я не понял зачем там обратная связь в операционнике?
Сообщение отредактировал Lost_Viking - Jul 31 2008, 17:47
|
|
|
|
|
Jul 31 2008, 18:10
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Jul 31 2008, 21:38)  как я понял - это просто среднее какое-то значение. блин, и там погрешность, и тут ... Вряд ли погрешность обработки превысит погрешность АЦП АВР  . Цитата  я умер от этой книги. ничего не понял. мне проще стабилизировать опорное напряжение и питание, чем разобраться в этих греческих символах Код u16_t Yavg;
for(;;) { Yavg -= Yavg/256; Yavg += ADCH; } Запуск и готовность АЦП за Вами. Утверждается, что в старшем байте Yavg получим фильтр НЧ с частотой среза = частоте запуска АЦП/256 с погрешностью обработки <0.5 LSB, по АФЧХ эквивалентный RC цепочке с такой же частотой среза. Почему? Хемминг уже рассказал, у меня лучше не получится  . Цитата Нашел вот что.Я смотрю там через операционник подают измеряемое напряжение. Только я не понял зачем там обратная связь в операционнике? Операционник включен повторителем и согласует входной делитель со входом АЦП. Использование в нем LM358 и заявление "3. Входное напряжение – 0..100В" оставим на совести автора.
|
|
|
|
|
Jul 31 2008, 18:50
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Jul 31 2008, 22:10)  Операционник включен повторителем и согласует входной делитель со входом АЦП. Использование в нем LM358 и заявление "3. Входное напряжение – 0..100В" оставим на совести автора.  там и на 1000 вольт есть, если поищешь. Короче, вот мои соображения: - на вход АЦП повесить ФНЧ из RC цепочки с частотой среза примерно 50Гц.
- использовать внешний ИОН на каком-либо стабилизаторе
- использовать КР514ИД2 по совету kipmaster'а
- наконец перенести все с макетной платы на печатку, предварительно подумав о развязке земли
- если все это не поможет, то использовать опцию "подавитель шумов"
- если и это не поможет, то использовать цифровой фильтр
подскажите пожалуйста как грамотно отделить питание аналоговой части от цифровой?
Сообщение отредактировал Lost_Viking - Jul 31 2008, 19:28
|
|
|
|
|
Jul 31 2008, 20:24
|

извечный пессимист
    
Группа: Свой
Сообщений: 1 113
Регистрация: 9-10-06
Из: Днепропетровск
Пользователь №: 21 125

|
Цитата(Lost_Viking @ Jul 31 2008, 23:50)   там и на 1000 вольт есть, если поищешь. Короче, вот мои соображения: - на вход АЦП повесить ФНЧ из RC цепочки с частотой среза примерно 50Гц.
- использовать внешний ИОН на каком-либо стабилизаторе
- использовать КР514ИД2 по совету kipmaster'а
- наконец перенести все с макетной платы на печатку, предварительно подумав о развязке земли
- если все это не поможет, то использовать опцию "подавитель шумов"
- если и это не поможет, то использовать цифровой фильтр
подскажите пожалуйста как грамотно отделить питание аналоговой части от цифровой? Через LC фильтр, землю цифровую и аналоговую соединить в одной точке, допустим на конденсаторе фильтра после выпрямителя.
--------------------
Slaves are those of this world Given freedom to lay chains upon The Master The wolf is no longer free Release the chains and come for me
|
|
|
|
|
Jul 31 2008, 20:48
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Jul 31 2008, 22:50)   там и на 1000 вольт есть, если поищешь. Проблема не верхнем пределе, а в нижнем. LM358 не является ОУ с диапазоном rail-to-rail ни по входу, ни по выходу. Цитата [*]использовать КР514ИД2 по совету kipmaster'а имхо, при разумной смехотехнике и трассировке достаточно отключать индикаторы на время преобразования АЦП. Цитата [*]если все это не поможет, то использовать опцию "подавитель шумов" Вы собираетесь биться за 9 честный бит? А "внешний ИОН на каком-либо стабилизаторе" у Вас какую точность опоры обеспечит? А где брать в розницу резисторы 0.25% Вы уже знаете? Или это задача для души? Тогда все-таки начните с теории. Цитата [*]если и это не поможет, то использовать цифровой фильтр Не поможет от чего? От мельтешения младшего разряда на индикаторе? Да тупо пропустите сигнал с АЦП через цифровой ФНЧ с частотой среза в 0.5 Гц - будет мельтешить не чаще раза в секунду. Только точности это не добавит, хотя и не убавит.
|
|
|
|
|
Jul 31 2008, 21:10
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Jul 31 2008, 21:17)  Метод - просто какой-либо НЧ фильтр в цифре. Простейший НЧ фильтр 1-го порядка: Yi = a * Yi-1 + b * Xi, a+b = 1 Т.е. Код Y = a * Y + b * X; Для целочисленной арифметики удобно делать a=c/2^N, b=(2^N-c)/2^N. что такое a и b? для чего они нужны? как я понял - это Взвешенное скользящее среднее (WMA), взято от сюда
|
|
|
|
|
Jul 31 2008, 21:29
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Aug 1 2008, 01:10)  что такое a и b? для чего они нужны? как я понял - это Взвешенное скользящее среднее (WMA), взято от сюдаНет, это Экспоненциальное скользящее среднее (EMA) Yi = Yi-1 + A*(Xi - Yi-1). С помощью несложных преобразований можно показать, что a = 1 - A, b = A. оттуда жеЦитата В случае EMA, коэффициент A - параметр фильтра, определяющий степень сглаживания. Чем он меньше, тем сильнее будет сглаживаться входной временной ряд. При A=0 фильтр перестает реагировать на изменения входного ряда, а при A=1 он будет повторять входной временной ряд. Попробуйте смоделировать (хоть в ёкселе) реакцию фильтра на единичный скачок (x=0 при i<0, x=1 при i>=0), поиграйтесь с A, и все станет просто и понятно.
|
|
|
|
|
Aug 1 2008, 13:46
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(MrYuran @ Aug 1 2008, 14:50)  А может даласовские датчики поставить и не мучиться? +/-1оС точность - лечится калибровкой, дискретность - где-то полградуса... Хотя, если хочется повозиться с АЦП, то флаг в руки... ДАЛАСОВСКИЕ? DS которые? Они у них диапозон до 120градусов. Мне нужно 160 градусов. У меня такой даласовский лежит уже, купил не прочитав даташит. Цитата(MrYuran @ Aug 1 2008, 14:50)   Опора не оказывает влияния на результат (только нестабильность резисторов) Как это опора не оказывает влияние на результат?  Ведь если Uоп = 5В, а Uвх = 2.5В, то 10битный ADC выдаст 512. А если опора 10В, то выдаст 256. Заметил вот что: записал в ADMUX: Код REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 0 0 1 0 0 0 0 0 Циферки перестали бегать, а АЦП все еще мерял что-то. Короче, получилось тоже самое, что и с внутренним ИОН, но только стабильнее. На AREF у меня всего лишь кондер висит, и никакого опорного напряжения не подводится. Объясните мне в чем секрет? Я в чудеса не верю
|
|
|
|
|
Aug 1 2008, 14:54
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Aug 1 2008, 17:46)  Как это опора не оказывает влияние на результат?  Ведь если Uоп = 5В, а Uвх = 2.5В, то 10битный ADC выдаст 512. А если опора 10В, то выдаст 256. При таком включении Rt = Nadc * Rоп / (Nadc_max - Nadc), где Nadc - результат преобразования АЦП Nadc_max - максимальное значение АЦП (0x3ff для однополярного 10-битного АЦП) Цитата Заметил вот что: записал в ADMUX: Код REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 0 0 1 0 0 0 0 0 Циферки перестали бегать, а АЦП все еще мерял что-то. Короче, получилось тоже самое, что и с внутренним ИОН, но только стабильнее. На AREF у меня всего лишь кондер висит, и никакого опорного напряжения не подводится. Объясните мне в чем секрет? Я в чудеса не верю Вы забыли еще помолиться и свечку затеплить - без этого цифирки все равно иногда будут бегать.
|
|
|
|
|
Aug 1 2008, 15:52
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Lost_Viking @ Aug 1 2008, 19:46)  Как это опора не оказывает влияние на результат?  Ведь если Uоп = 5В, а Uвх = 2.5В, то 10битный ADC выдаст 512. А если опора 10В, то выдаст 256. Это называется ратиометрическим способом измерения, от слова ratio - отношение. На вход опоры можно подавать Vcc напрямую, если конечно это допустимо. Либо можно поставить буфер и вход опоры и делитель запитывать от него (т.к. ток по входу опоры в несколько раз выше, чем по входу АЦП). Либо использовать внутреннюю опору и выход опоры использовать для запитки делителя Rоп-Rt. В общем когда резистивный делитель запитывается от того же напряжения что и опора, то через оба резистора протекает один и тот же ток (соединение-то последовательное). Поэтому результат преобразования уже не зависит от величины напряжения, а только от отношения величин резисторов, ну и соответственно от временнОй и температурной стабильности опорного резистора. Результат преобразования АЦП является функцией отношения этих резисторов. Следует это отсюда Ut=Rt/(Rt+Rоп)*Uref Поскольку Ut мы получаем в виде результата преобразования АЦП (кодАЦП), а Uref соответствует максимальному коду АЦП = 1023, то получаем что кодАЦП=Rt/(Rt+Rоп)*1023. После простейших метематических преобразования получаем формулу Rt=Rоп*кодАЦП/(1023-кодАЦП). Где величина опоры никак не участвует, а играет роль только сопротивление опорного резистора Rоп. Конечно же превышать максимально допустимое для АЦП и опоры напряжение нельзя. Так что про "если опора 10В" это вы погорячились  Update. Кстати при вычислениях в последней формуле существует вероятная ситуация исключения - деление на нуль, когда кодАЦП=1023. На практике это означает, что Rt>>Rоп (Rt много больше, на несколько порядков больше Rоп) или просто обрыв в цепи измеряемого сопротивления.
Сообщение отредактировал rezident - Aug 1 2008, 17:39
|
|
|
|
|
Aug 1 2008, 17:30
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Lost_Viking @ Aug 1 2008, 17:46)  Заметил вот что: записал в ADMUX: Код REFS1 REFS0 ADLAR MUX4 MUX3 MUX2 MUX1 MUX0 0 0 1 0 0 0 0 0 Циферки перестали бегать, а АЦП все еще мерял что-то. Какая чушь! ADLAR=1! Вай-вай-вай! Лучше RTFM, чем вопросы.  По поводу усреднения - не забудьте, что отношение сигнал/шум растет пропорционально квадратному корню из числа N усредняемых выборок, т.е. для 256 отсчетов имеем с/ш выросла в 16 раз. Младший разряд должен стоять и бояться. Это если у нас мат. ожидание есть состоятельная оценка. В противном случае придеццо делать обработку медианой.
|
|
|
|
|
Aug 1 2008, 21:47
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Aug 1 2008, 22:01)  ADLAR=1 очень даже удобно, если читать только ADCH. Вот REFS0 = REFS1 = 0 только с кондюком на AVref гораздо прикольней - опора на входном токе ноги контроллера. Срочно патентовать!!!  Однако работает! Сам не понимаю. Собрал опору на TL431, и радуюсь.10Бит. Вот только наводки иногда проскакивают, теперь займусь ФНЧ, возможно применю цифровую фильтрацию. Как закончу - выложу полный код на Си с комментами и алгоритмом. Что бы такие же как я не наступали на грабли. Цитата(_Pasha @ Aug 1 2008, 22:19)  Дык автор хочет 10 бит, а получает 8 и радуется  Для меня и 8 бит хватило бы. Но мне пришла в голову мысль использовать сабж на даче для измерения сетевого напряжения, для регистрации (с записью в EEPROM,и дальнейшей пересылкой в ПК) температуры окружающей среды за промежуток времени, и т.п. Далее хотелось бы попробовать сделать датчик влажности грунта для автоматической поливалки... Вот так-то  Цитата(_Pasha @ Aug 1 2008, 21:30)  Это если у нас мат. ожидание есть состоятельная оценка. В противном случае придеццо делать обработку медианой. а можно без нецензурных выражений?
Сообщение отредактировал Lost_Viking - Aug 1 2008, 21:48
|
|
|
|
|
Aug 2 2008, 15:27
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(domowoj @ Aug 2 2008, 15:26)  Lost_Viking А мож Вам лучше DS18x20 применить, никаких АЦП и никаких тебе опорных. Дергай только ножками правильно, читай температуру в цифре и выводи на индикатор. Нет, все эти датчики до 125 градусов. Мне же нужно до 200, в реале регулировка будет в районе 160-170.
|
|
|
|
|
Aug 3 2008, 06:25
|

Профессионал
    
Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486

|
Цитата(_Pasha @ Jul 31 2008, 18:57)  1. TL431 ему в опору, чтоб не баловался. 2. Noise canceler ему в мозги, иначе у младшего разряда нервный тик не пройдет. 3. Накопление методом скользящего среднего вне зависимости от того, удался ли п.2. 1.ТЛка - слабовато для опорного по точности 2.Это -сомо собой необходимо 3.Может быть применить какой-нибудь вероятностный критерий вместо скользящего среднего. И провести темпер. диапазон изменения входного к опорному. На каком датчике остановился?
--------------------
И на камнях растут деревья!
|
|
|
|
|
Aug 3 2008, 14:01
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(domowoj @ Aug 3 2008, 10:25)  1.ТЛка - слабовато для опорного по точности Уже заметил. На чем посоветуешь опорное сделать? Цитата(domowoj @ Aug 3 2008, 10:25)  2.Это -сомо собой необходимо Еще бы сделать небольшую паузу между переключением анодов индикатора, и в эту паузу мерить температуру с подавителем шумов.Тлько с синхронизацией замучаюсь. Цитата(domowoj @ Aug 3 2008, 10:25)  3.Может быть применить какой-нибудь вероятностный критерий вместо скользящего среднего. брр, только если на голодный желудок. Цитата(domowoj @ Aug 3 2008, 10:25)  И провести темпер. диапазон изменения входного к опорному. что-что? Цитата(domowoj @ Aug 3 2008, 10:25)  На каком датчике остановился? Что-нибудь из этого. Пока еще не занимался конкретным выбором датчика.Как мозги доделаю, так датчик буду искать. Кстати, такой вопрос: как правильно рассчитать значение на выходе АЦП? Судя по этой формуле:  На выходе получится максимум 1024, что никак не 10 бит, а все 11. т.е. 10000000000. Так как правильно считать?
Сообщение отредактировал Lost_Viking - Aug 3 2008, 14:10
|
|
|
|
|
Aug 3 2008, 15:18
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(domowoj @ Aug 3 2008, 19:05)  а 1024 - это кол-во дискрет от 0 до 1023. А для рассчета в EXCEL ставить что? 1024 или 1023? Думаю, что 1023.
|
|
|
|
|
Aug 3 2008, 15:46
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(domowoj @ Aug 3 2008, 19:31)  Lost_Viking Может лучше применить ЖК индикатор. Не хочу тратиться на него. В принципе, у меня есть дома индикатор, но я не знаю как им управлять. Посмотри, может ты подскажешь? P.S. Так все-таки что мне ставить в EXCEL для рассчета значения на выходе АЦП?1024 или 1023?
Сообщение отредактировал Lost_Viking - Aug 3 2008, 15:52
|
|
|
|
|
Aug 3 2008, 17:34
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Lost_Viking @ Aug 3 2008, 21:46)  P.S. Так все-таки что мне ставить в EXCEL для рассчета значения на выходе АЦП?1024 или 1023? Вас в школе пропорцию составлять учили? Когда Vin=Vref получаем максимальное число которое можно представить 10-ю разрядами: 1023, т.е. Vref соответствует максимальному коду АЦП - 1023. Составляем пропорцию Код ADC Vin ---- = ----- отсюда следует 1023 Vref ADC=Vin/Vref*1023
|
|
|
|
|
Aug 3 2008, 19:56
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(domowoj @ Aug 3 2008, 21:17)  А ЖК от чего? не помню. Цитата(rezident @ Aug 3 2008, 21:34)  Вас в школе пропорцию составлять учили? Когда Vin=Vref получаем максимальное число которое ADC=Vin/Vref*1023 с какого перепуга в ДАТАШИТЕ пишут 1024???
|
|
|
|
|
Aug 3 2008, 20:38
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Lost_Viking @ Aug 4 2008, 01:56)  с какого перепуга в ДАТАШИТЕ пишут 1024??? Господи, как же тяжело с недоученными школьниками!  В микроконтроллере AVR 10-ти разрядный АЦП. С помощью 10-и двоичных разрядов можно представить 1024 числа, но максимальное значение такого 10-и разрядного числа составляет 0b1111111111=0x03FF= 1023. Если мне не верите, воспользуйтесь виндовым калькулятором для перевода из одной системы счисления в другую  Также не нужно забывать о том, что нуль это тоже число! 1023+1=1024 числа. Так понятно? Ну про прямую линию, ее графическое изображение и аналитическое представление (в виде формулы y=a*x+b ) вам надеюсь все-же объяснить не нужно? АЦП квантует входной сигнал по линейному закону (по крайней мере разработчики АЦП к этому очень стремятся  ) _y_ = ________________ a _______________ *_x_ + __b__ ADC=(ADC(max)-ADC(min))/(Uref(max)-Uref(min))*Uin+ADC(min) поскольку значения ADC(min)=0 и Uref(min)=0V, а ADC(max)=1023, то формула приводится к виду ADC=1023/Uref(max)*Uin=1023*Uin/Uref(max)
|
|
|
|
|
Aug 4 2008, 08:13
|
Местный
  
Группа: Свой
Сообщений: 437
Регистрация: 23-04-05
Из: Таганрог
Пользователь №: 4 425

|
Цитата where VIN is the voltage on the selected input pin and VREF the selected voltage reference (see Table 22-2 on page 255 and Table 22-3 on page 256). 0x000 represents analog ground, and 0x3FF represents the selected reference voltage minus one LSB. Вот что написано в документации, а переводится это так - значение 0 говорит о том, что входное напряжение равно земле, значение 0x3FF говорит о том, что входное напряжение равно опорному минус напряжение одного младшего разряда (а не опорному!), т.е. верна формула из документации и в эксель надо писать 1024.
|
|
|
|
|
Aug 4 2008, 14:39
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(Dopler @ Aug 4 2008, 12:13)  Вот что написано в документации, а переводится это так - значение 0 говорит о том, что входное напряжение равно земле, значение 0x3FF говорит о том, что входное напряжение равно опорному минус напряжение одного младшего разряда (а не опорному!), т.е. верна формула из документации и в эксель надо писать 1024. Короче, почти понятно. Нашел в инете понятный учебник по цифорвым фильтрам, в отличие от того, который мне тут предлагали. Вот ссылка. Там найдете "Уолт Кестер - Цифровые Фильтры". Кроме этого там много чего есть! Попробовал сделать осреднение результата АЦП. Примерно так: - АЦП в режиме постоянного преобразования (free run)
- По совпадению таймера с OCR0 вызывается прерывание, при помощи которого реализована дин.индикация
- В этом же обработчике прерывания:
Код 1 for (i=1;i<=9;i++) 2 {current_temp=ADCL; 3 current_temp+=((int)ADCH << 8); 4 summ+=current_temp;} 5 current_temp=summ/9; 6 summ=0; /*дальше идет разбиение числа по десятичным разрядам*/ Т.е. просто суммирую девять преобразований, и делю на их число. Т.е. нахожу среднее значение. В итоге младший разряд на индикаторе по-меньше стал дрыгаться. Noice Reduction (с прерыванием) не особо помог. Сдается мне, что у меня что-то работает как антена  . Сделал отдельный провод со входа АЦП, что бы вольтметром мерить напряжение на нем, и при касании этого провода рукой - циферки начинают бегать вплоть до второго разряда. Или все-таки в "коленной" разводке? Все сделано на макетке, спаяно медным лакированным проводом 0.2мм. Земля приходит почти везде в одну точку. Вот только аналоговая часть ненмого крива разведена. Вобщем, буду травить плату, посмотрю что получится. Как я понял рекомендации такие: разявязать аналоговую часть от цифровой конденсаторами, все землянные выводы в одну точку, конденсаторы по-ближе к микросхеме, на вход АЦП RC ФНЧ с частотой среза 10..50Гц. Так? Завтра попробую создать промежутки между включением анодов, что бы в эти промежутки впихнуть измерение сигнала.
|
|
|
|
|
Aug 4 2008, 16:01
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(Lost_Viking @ Aug 4 2008, 04:34)  вопрос остается открытым: почему в Даташите в этой формуле стоит 1024? Я-то прекрасно понимаю, что нуль - это тоже число, но мне непонятно почему в ДАТАШИТЕ для рассчета значения АЦП используют 1024. Ведь при этом совсем другое значение. Не веришь - сам посмотри, только там есть небольшая поправка к этому. Ну раз в даташите написано, то спорить не буду.  Тем более, что там в самом начале раздела описания ADC указано Цитата The ADC converts an analog input voltage to a 10-bit digital value through successive approxi- mation. The minimum value represents GND and the maximum value represents the voltage on the AREF pin minus 1 LSB. Т.е. входной диапазон напряжений для ADC: Uin(min)=0V, Uin(max)=Uref-Uref/1024 и на вход АЦП напряжение равное AREF подавать нельзя. Точнее конечно можно, но не имеет смысла. Тогда вполне логично получается. Подставляем в вышеуказанноую мной формулу ADC=(ADC(max)-ADC(min))/(Uref(max)-Uref(min))*Uin+ADC(min) значения ADC(max)=1023, ADC(min)=0, Uref(min)=0V, Uref(max)=Uref-Uref/1024=(1023*Uref)/1024 и получаем ADC=(1023-0)/((1023*Uref)/1024)-0V)*Uin+0, а после преобразований ADC=1024/Uref*Uin. Выходит формула в даташите верная. Просто таковы особенности этого АЦП в AVR, о которых я не знал.
|
|
|
|
|
Aug 4 2008, 18:56
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Aug 1 2008, 01:29)  Попробуйте смоделировать (хоть в ёкселе) реакцию фильтра на единичный скачок (x=0 при i<0, x=1 при i>=0), поиграйтесь с A, и все станет просто и понятно.  и уважуха! Все, теперь я знаю "Простое скользящее среднее", "Взвешенное скользящее среднее" и "Экспоненциальное скользящее среднее". Возникло сразу несколько вопросов: (WMA) - как правильно рассчитать коэффициенты? Я пока беру 4 отсчета, соответственно ставлю 1/4. (EMA) - было бы интересно привязать коэфф. "А" к помехам, т.е. если вдруг начинается частое мельтишение младших разрядов, то уменьшить А.
|
|
|
|
|
Aug 4 2008, 20:57
|
Гуру
     
Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588

|
Цитата(Lost_Viking @ Aug 4 2008, 18:56)  Все, теперь я знаю "Простое скользящее среднее", "Взвешенное скользящее среднее" и "Экспоненциальное скользящее среднее". Бугагага: // SMA - Simple Moving Average // EMA - Exponential Moving Average // WMA - Weighted Moving Average // DEMA - Double Exponential Moving Average // TEMA - Triple Exponential Moving Average // TRIMA - Triangular Moving Average // KAMA - Kaufman Adaptive Moving Average // MAMA - MESA Adaptive Moving Average // T3 - Triple Exponential Moving Average
|
|
|
|
|
Aug 5 2008, 07:05
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(Огурцов @ Aug 5 2008, 00:57)  Бугагага: // SMA - Simple Moving Average // EMA - Exponential Moving Average // WMA - Weighted Moving Average // DEMA - Double Exponential Moving Average // TEMA - Triple Exponential Moving Average // TRIMA - Triangular Moving Average // KAMA - Kaufman Adaptive Moving Average // MAMA - MESA Adaptive Moving Average // T3 - Triple Exponential Moving Average пилять! Вопрос такой: при использовании EMA метода, коэфф-т A должен быть вещественным. Т.е. в итоге функция получается вещественной. Но у меня дальше идет оператор "остаток от деления". Как мне согласовать вщественный тип с получением остатка от деления? Простое приведение типов не катит - нет округления. Т.е. мне нужно вещественное число округлить, а потом это число привести в целый тип. Как это реализовать на Си?
|
|
|
|
|
Aug 5 2008, 09:04
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(Lost_Viking @ Aug 5 2008, 11:05)  Вопрос такой: при использовании EMA метода, коэфф-т A должен быть вещественным. Т.е. в итоге функция получается вещественной. Но у меня дальше идет оператор "остаток от деления". Как мне согласовать вщественный тип с получением остатка от деления? Простое приведение типов не катит - нет округления. Т.е. мне нужно вещественное число округлить, а потом это число привести в целый тип. Как это реализовать на Си? Помните, что такое подмножество рациональных чисел? Правильно, это подмножество чисел, которые могут быть представлены в виде отношения (ratio = дробь, отношение) двух целых чисел. И примерно в то же время Вам должны были сообщить, что любое вещественное число может быть с любой точностью приближено рациональным (хотя нет - года на 3-4 позже). Дальше сами догадаетесь? Это в качестве посказки: Цитата(xemul @ Jul 31 2008, 21:17)  Простейший НЧ фильтр 1-го порядка: Yi = a * Yi-1 + b * Xi, a+b = 1 Т.е. Код Y = a * Y + b * X; Для целочисленной арифметики удобно делать a=c/2^N, b=(2^N-c)/2^N. Чтобы не набегала погрешность при обработке, разрядность Y должна быть не менее (разрядность X) + N. Y = a * Y + b * X; // это фильтр на С; X - новое входное значение, Y - справа предыдущее выходное значение, слева - новое. Цитата(xemul @ Jul 31 2008, 22:10)  Код u16_t Yavg;
for(;;) { Yavg -= Yavg/256; Yavg += ADCH; } А это целочисленная реализация приведенного выше фильтра с коэффиентами a=255/256, b=1/256. Ну и уж совсем на всякий случай: деление целого числа на 2^N компилятор заменит на N сдвигов вправо. 256 = 2^8. ЗЫЖ я к своему детенышу (которому, думаю, примерно столько же годочков, сколько и Вам) за серьезной беседой обращаюсь на "Вы". ЗЗЫЖ радует, что в Ваших постах не так уж много проблем с русским языком.
|
|
|
|
|
Aug 5 2008, 14:50
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(xemul @ Aug 5 2008, 13:04)  ЗЫЖ я к своему детенышу (которому, думаю, примерно столько же годочков, сколько и Вам) за серьезной беседой обращаюсь на "Вы". ЗЗЫЖ радует, что в Ваших постах не так уж много проблем с русским языком. Ну, извинните, я думал, что тут люди простые. Лично я не люблю когда меня на "Вы". Мне проще на "Ты". Сразо как-то "по-свойски". Если чем-то задел, то прошу прощения. Кстати, я себе EMA сделал. смотрю на девайс и радуюсь =) Позже поэксперементирую с другими фильтрами. Ко всем: EMA - это КИХ или БИХ?
|
|
|
|
|
Aug 5 2008, 17:14
|
Частый гость
 
Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091

|
Цитата(rezident @ Aug 5 2008, 19:00)  Кстати, EMA эквивалентно установке RC-цепи на входе измерителя. Я уже заметил =).
|
|
|
|
|
Aug 5 2008, 17:49
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
Цитата(domowoj @ Aug 5 2008, 23:25)  Да нет, похоже не медианная. Почему не похоже? Если вашу фразу продолжить Цитата мз массива оцифрованных значенний выбрать наиболее часто встречающееся значения в окне фильтрации, то вполне медианная фильтрация получается.
|
|
|
|
|
Aug 5 2008, 21:55
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(domowoj @ Aug 5 2008, 20:41)  Усреднение не всегда есть хорошо. Если есть время( а оно у автора есть) лучше применить вероятностный метод (не знаю как он называтся по научному)
мз массива оцифрованных значенний выбрать наиболее часто встречающееся. Вы предлагаете построить гистограмму выборки? Могу предположить, что закон распределения для выборки, не очень искаженной какими-либо неприличными факторами, будет близок к нормальному, и, соответственно, максимум распределения совпадет со средним значением выборки. Если же закон распределения будет даже несимметричен, то имеет смысл сначала проверить смехотехнику и программу, а потом уж пускаться во всякие тяжкие. Если выборка содержит выбросы (ну, н-р, АЦП не вовремя прочитали), то их, как уже отметил ув. rezident, можно попробовать отрезать медианным фильтром. Но: 1) нужны ли такие навороты в придумываемой коробочке? 2) готов ли автор (которого пугают греческие буквы  ) лезть в теорию измерений? Там этих буковок...
|
|
|
|
|
Aug 5 2008, 23:40
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Lost_Viking @ Aug 4 2008, 17:39)  Попробовал сделать осреднение результата АЦП. Примерно так:[list] [*]АЦП в режиме постоянного преобразования (free run) [*]По совпадению таймера с OCR0 вызывается прерывание, при помощи которого реализована дин.индикация [*]В этом же обработчике прерывания: Блин, всю свадьбу пропустил... Вот мне одно непонятно: как можно так мощно дрыгать ногами в динамич. индикации и не отбрасывать значения АЦП, полученные за период, в котором было переключение ног ? Я так понимаю, что у нас должно быть прерывание во free run, и прерывание по OCR0, если угодно. В gcc-шной нотации где-то так: Код volatile uint8_t bad_adc; // used as flag volatile uint8_t ad_cnt; //counter volatile uint32_t ad_sum; volatile uint16_t ad_result; ISR(SIG_ADC) { if(!bad_adc) { ad_sum+=(uint32_t) ADC; if(ad_cnt++ == 0) { ad_result = (ad_sum >>8) & 1023; ad_sum = 0; } } else { bad_adc = 0; } }
ISR(SIG_OUTPUT_COMPARE0) { /* здесь динамическая индикация*/ /* и обязательно пометка о плохих измерениях */ bad_adc = 1; }
|
|
|
|
|
Aug 6 2008, 00:54
|

Профессионал
    
Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486

|
Цитата(xemul @ Aug 6 2008, 04:55)  Вы предлагаете построить гистограмму выборки? Могу предположить, что закон распределения для выборки, не очень искаженной какими-либо неприличными факторами, будет близок к нормальному, и, соответственно, максимум распределения совпадет со средним значением выборки. Если же закон распределения будет даже несимметричен, то имеет смысл сначала проверить смехотехнику и программу, а потом уж пускаться во всякие тяжкие. Если выборка содержит выбросы (ну, н-р, АЦП не вовремя прочитали), то их, как уже отметил ув. rezident, можно попробовать отрезать медианным фильтром. Но: 1) нужны ли такие навороты в придумываемой коробочке? 2) готов ли автор (которого пугают греческие буквы  ) лезть в теорию измерений? Там этих буковок... Автору же точность нужна и пусть тренируется.
--------------------
И на камнях растут деревья!
|
|
|
|
|
Aug 6 2008, 07:54
|
    
Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731

|
Цитата(_Pasha @ Aug 6 2008, 03:40)  Блин, всю свадьбу пропустил... Вот мне одно непонятно: как можно так мощно дрыгать ногами в динамич. индикации и не отбрасывать значения АЦП, полученные за период, в котором было переключение ног ? Я так понимаю, что у нас должно быть прерывание во free run, и прерывание по OCR0, если угодно. А зачем freerun? Пусть хочется вывести 4 десятичных разряда для индикации с частотой обновления 100 Гц (2.5 мс на разряд). Пусть АЦП стоит в single shot с частотой 100 кГц (135 мкс на преобразование). Вывели все разряды, погасили индикаторы, запустили АЦП (хоть с noise canceller'ом), проснулись и поехали дальше индицировать. Цитата(domowoj @ Aug 6 2008, 04:54)  Автору же точность нужна и пусть тренируется.  Автору сначала нужно понять, что такое точность. От того, что он выведет на индикатор 10 бит, зафильтрованные по дальше некуда, точность не увеличится. Да и пытаться одним камнем и измерять на пределе точности АЦП, и светодиодами мыргать - не совсем разумный подход.
|
|
|
|
|
Aug 6 2008, 15:22
|

Профессионал
    
Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486

|
Цитата(xemul @ Aug 6 2008, 14:54)  А зачем freerun? Пусть хочется вывести 4 десятичных разряда для индикации с частотой обновления 100 Гц (2.5 мс на разряд). Пусть АЦП стоит в single shot с частотой 100 кГц (135 мкс на преобразование). Вывели все разряды, погасили индикаторы, запустили АЦП (хоть с noise canceller'ом), проснулись и поехали дальше индицировать.  Автору сначала нужно понять, что такое точность. От того, что он выведет на индикатор 10 бит, зафильтрованные по дальше некуда, точность не увеличится. Да и пытаться одним камнем и измерять на пределе точности АЦП, и светодиодами мыргать - не совсем разумный подход. Согласен Lost_Viking-у стоило сперва сделать АЦП без динамической индикации, а потом усовершенствовать индикацию. Я думаю 3 индикатора с 514ИДх - подошло бы.
--------------------
И на камнях растут деревья!
|
|
|
|
|
Sep 27 2008, 17:38
|
Группа: Новичок
Сообщений: 1
Регистрация: 27-09-08
Пользователь №: 40 526

|
Lost_Viking как устройство, получилось? Вот _http://www.kosmodrom.com.ua/data/kty.php_ вроде неплохие датчики для вашего устройства, а вот это устройство сделано на этих датчиках _http://www.radiokot.ru/lab/controller/21/ . Может вам будет интересно. Данный термометр я сейчас изготавливаю, жду когда приедут датчики. Прошу прощения может чего-то недосмотрел где можно посмотреть схему вашего устройства.
|
|
|
|
|
Oct 21 2016, 07:27
|
Частый гость
 
Группа: Участник
Сообщений: 160
Регистрация: 21-06-16
Пользователь №: 92 272

|
Цитата(Lost_Viking @ Jul 30 2008, 12:01)  Готова динамическая индикация Какая острая необходимость вешать атмегу динамической индикацией http://www.chipdip.ru/product/ldm-208ra/
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|