реклама на сайте
подробности

 
 
> терморегулятор, помогите
Lost_Viking
сообщение Jul 30 2008, 12:01
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 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. Когда использовал прерывание АЦП, то у меня все работало. Но хочется упростить немного код (пусть хоть потребляет больше)
Схемку прилагаю.

Подскажите что не так, я уже не знаю чего делать.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
7 страниц V  « < 2 3 4 5 6 > »   
Start new topic
Ответов (45 - 59)
_Pasha
сообщение Aug 1 2008, 17:30
Сообщение #46


;
******

Группа: Участник
Сообщений: 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, чем вопросы. smile.gif

По поводу усреднения - не забудьте, что отношение сигнал/шум растет пропорционально квадратному корню из числа N усредняемых выборок, т.е. для 256 отсчетов имеем с/ш выросла в 16 раз. Младший разряд должен стоять и бояться. Это если у нас мат. ожидание есть состоятельная оценка. В противном случае придеццо делать обработку медианой.
Go to the top of the page
 
+Quote Post
xemul
сообщение Aug 1 2008, 18:01
Сообщение #47



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(_Pasha @ Aug 1 2008, 21:30) *
Какая чушь! ADLAR=1! Вай-вай-вай! Лучше RTFM, чем вопросы. smile.gif

ADLAR=1 очень даже удобно, если читать только ADCH.
Вот REFS0 = REFS1 = 0 только с кондюком на AVref гораздо прикольней - опора на входном токе ноги контроллера. Срочно патентовать!!! smile.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Aug 1 2008, 18:19
Сообщение #48


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(xemul @ Aug 1 2008, 22:01) *
ADLAR=1 очень даже удобно, если читать только ADCH.

Дык автор хочет 10 бит, а получает 8 и радуется smile.gif
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Aug 1 2008, 21:47
Сообщение #49


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(xemul @ Aug 1 2008, 22:01) *
ADLAR=1 очень даже удобно, если читать только ADCH.
Вот REFS0 = REFS1 = 0 только с кондюком на AVref гораздо прикольней - опора на входном токе ноги контроллера. Срочно патентовать!!! smile.gif


Однако работает! Сам не понимаю. Собрал опору на TL431, и радуюсь.10Бит. Вот только наводки иногда проскакивают, теперь займусь ФНЧ, возможно применю цифровую фильтрацию.
Как закончу - выложу полный код на Си с комментами и алгоритмом. Что бы такие же как я не наступали на грабли.

Цитата(_Pasha @ Aug 1 2008, 22:19) *
Дык автор хочет 10 бит, а получает 8 и радуется smile.gif

Для меня и 8 бит хватило бы. Но мне пришла в голову мысль использовать сабж на даче для измерения сетевого напряжения, для регистрации (с записью в EEPROM,и дальнейшей пересылкой в ПК) температуры окружающей среды за промежуток времени, и т.п.
Далее хотелось бы попробовать сделать датчик влажности грунта для автоматической поливалки...
Вот так-то wacko.gif

Цитата(_Pasha @ Aug 1 2008, 21:30) *
Это если у нас мат. ожидание есть состоятельная оценка. В противном случае придеццо делать обработку медианой.

1111493779.gif
а можно без нецензурных выражений? 07.gif

Сообщение отредактировал Lost_Viking - Aug 1 2008, 21:48
Go to the top of the page
 
+Quote Post
domowoj
сообщение Aug 2 2008, 11:26
Сообщение #50


Профессионал
*****

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



Lost_Viking
А мож Вам лучше DS18x20 применить, никаких АЦП и никаких тебе опорных.
Дергай только ножками правильно, читай температуру в цифре и выводи на индикатор.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Aug 2 2008, 15:27
Сообщение #51


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(domowoj @ Aug 2 2008, 15:26) *
Lost_Viking
А мож Вам лучше DS18x20 применить, никаких АЦП и никаких тебе опорных.
Дергай только ножками правильно, читай температуру в цифре и выводи на индикатор.


Нет, все эти датчики до 125 градусов. Мне же нужно до 200, в реале регулировка будет в районе 160-170.
Go to the top of the page
 
+Quote Post
domowoj
сообщение Aug 3 2008, 06:25
Сообщение #52


Профессионал
*****

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



Цитата(_Pasha @ Jul 31 2008, 18:57) *
1. TL431 ему в опору, чтоб не баловался.
2. Noise canceler ему в мозги, иначе у младшего разряда нервный тик не пройдет.
3. Накопление методом скользящего среднего вне зависимости от того, удался ли п.2.


1.ТЛка - слабовато для опорного по точности
2.Это -сомо собой необходимо
3.Может быть применить какой-нибудь вероятностный критерий вместо скользящего среднего.

И провести темпер. диапазон изменения входного к опорному.

На каком датчике остановился?


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Aug 3 2008, 12:32
Сообщение #53


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



Цитата(Lost_Viking @ Aug 2 2008, 15:27) *
Мне же нужно до 200, в реале регулировка будет в районе 160-170.

А что в качестве датчика, если не секрет ?
Я использовал термопару, но точность (в начале шкалы) не понравилась, видимо из-за смещения усилителя.
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Aug 3 2008, 14:01
Сообщение #54


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
domowoj
сообщение Aug 3 2008, 15:05
Сообщение #55


Профессионал
*****

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



Хотя бы REF02.

Я бы вообще выключил все генераторы.

Чтобы диапазон измеряемой темперотуры 0...200
соотв. напряжению с датчика 0...Uref,

а 1024 - это кол-во дискрет от 0 до 1023.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Aug 3 2008, 15:18
Сообщение #56


Частый гость
**

Группа: Участник
Сообщений: 168
Регистрация: 25-04-08
Пользователь №: 37 091



Цитата(domowoj @ Aug 3 2008, 19:05) *
а 1024 - это кол-во дискрет от 0 до 1023.


А для рассчета в EXCEL ставить что? 1024 или 1023? Думаю, что 1023.
Go to the top of the page
 
+Quote Post
domowoj
сообщение Aug 3 2008, 15:31
Сообщение #57


Профессионал
*****

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



Lost_Viking
Может лучше применить ЖК индикатор.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Lost_Viking
сообщение Aug 3 2008, 15:46
Сообщение #58


Частый гость
**

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
domowoj
сообщение Aug 3 2008, 17:17
Сообщение #59


Профессионал
*****

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



EXCEL не знаю.

А ЖК от чего?


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
rezident
сообщение Aug 3 2008, 17:34
Сообщение #60


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post

7 страниц V  « < 2 3 4 5 6 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 1st September 2025 - 16:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01662 секунд с 7
ELECTRONIX ©2004-2016