Термостат на ATmeg8 , LCD, DS18B20... делаем на CVAVR

Обсуждаем контроллеры компании Atmel.
Ответить
Мучитель микросхем
Аватара пользователя
Сообщения: 420
Зарегистрирован: Чт июн 03, 2010 23:06:12

Сообщение Coviraylhik »

Доброго времени.
Конечно этих термостатов как грязи, но когда он тебе нужен , схемы подходящей не найти.
Моя проба сделать своё конечно же постепенно заходит в тупик.
Вот моя начальная программа для МК

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

#include <mega8.h>
// 1 Wire Bus functions
#asm
   .equ __w1_port=0x18 ;PORTB
   .equ __w1_bit=0
#endasm
#include <1wire.h>
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h> 
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>    
unsigned char lcd_buffer[10];  
void main(void)
{
// Port B initialization
PORTB=0b00000000;
DDRB=0b11111100;
// Port C initialization
PORTC=0b10000000;
DDRC=0b00000000;
// Port D initialization
PORTD=0b00000000;
DDRD=0b00000000;

ACSR=0x80;
SFIOR=0x00;

w1_init();
lcd_init(16);                     //инициилизация LCD, и говорим что он на 16 символов
while (1) /* бесконечный цикл */
{
unsigned char devices;         //переменная в которой количество присоеденённых датчиков
int temp;                        //переменная для хранения температуры                
devices=w1_init();               //ищy датчики
//while(1)                 //бесконечный цикл, если датчик подключон
      {
          temp=ds18b20_temperature(0);  //читаем температуру  
          if (temp>1000){               //если датчик выдаёт больше 1000
             temp=4096-temp;            //отнимаем от данных 4096
             temp=-temp;                //и ставим знак "минус"
                    } 
                    if ((temp >= 20) & (temp <= 23))    // установим порог PORTB.6
                    PORTB.6 = 1;
                     else
                        if ((temp >= 25) & (temp <= 32))    // установим порог 
                        PORTB.6 = 1;
                        else
                        {
                        PORTB.6 = 0;
                        }      
                    if ((temp >= -12) & (temp <= -10))    // установим порог PORTB.7
                    PORTB.7 = 1;
                     else
                        if ((temp >= -16) & (temp <= -14))    // установим порог 
                        PORTB.7 = 1;
                        else
                        {
                        PORTB.7 = 0;
                        }
      sprintf(lcd_buffer,"t=%i.%u\xdfC",temp,temp%1);    //на экран температуру и всё такое 
      lcd_clear();    //чистим дисплей перед выводом       
      //lcd_gotoxy(0,0);            
      lcd_puts(lcd_buffer);    //выводим первую строку 
      /*/ формирование второй строки для вывода
        sprintf(lcd_buffer,"t=%i.%u\xdfC",temp,temp%1);    //на экран температуру и всё такое
      lcd_gotoxy(0,1);
      lcd_puts(lcd_buffer);    // выводим вторую строку с индикацией тока */
      delay_ms(50);              //ждём 50мс   
      };
   }
}

В данный момент это термостат , пороги срабатывания на температуру задаются из МК (это правильно так надо).
Далее что я хотел бы сделать, но у меня не получается:
Отображение температуры с десятыми, а также чтобы в исходнике можно было задавать значения
if ((temp >= 200) & (temp <= 232)) ..... (сейчас это if ((temp >= 20) & (temp <= 23))

И как сделать второй аналогичный термостат (с выводом данных температуры во вторую стороку).
Этот проект в протеусе и исходник в архиве.
Mega8_wire_LCD16x2.rar
(83.16 КБ) 609 скачиваний
P.S.
В соседней ветке форума по подобному вопросу был дан совет
Это - при отсутствии исходников, да собственно как и с ними - минимум день работы с отладкой.
Платите за работу или сделайте сами.
Возможно, кто-то захочет размять пальцы и бесплатно, как бы его решение :)
Понятное дело вникнуть в кусок кода написаный мной займет какое то время, и размять прийдется не только пальцы, но ведь все вы когда то начинали, и вовремя оказанная помощь всегда большое дело.
Котоварищи , гуру и начинающие , как говорится не проходите мимо, с интересом воспользуюсь вашей помощью и советами.
Последний раз редактировалось Coviraylhik Вс окт 30, 2011 01:34:47, всего редактировалось 2 раза.
Некакого перимирия, Некаких мирных шагов навстречу и периговоров.
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 160
Зарегистрирован: Чт авг 13, 2009 08:22:53
Откуда: Vinnitsa

Сообщение masterpc »

Не увидел откуда Вы получаете температуру...
Вот как я делал:

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

int TEMPERATURE; // - температура в десятых долях градуса c округлением, естественно 
        int meas=((int)(sens[i][1])<<8)+(sens[i][0]);  // meas - то, что с датчика считали (два байта приведенные к signed int)
                
        if(meas<0) TEMPERATURE = 0-(((~meas+1)*0.625)+0.5);  // Subzero        
        else TEMPERATURE = (meas*0.625)+0.5;   
Массив sens[][] хранит в себе считанные данные с датчиков. Первых две ячейки содержат данные о температуре. Умножаем на 0,625, а не на 0,0625 для того, чтобы представить измерянную температуру без запятой. Т.е если температура +25,5, то результат будет 255. Запятую нарисовать уже дело техники.
+0.5 - это округление

Удачи!!!
Реклама
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Сообщение Vlad0o »

Здравствуйте.
У меня возникла небольшая трудность с датчиком ds18(s)20, а точнее с несколькими. С одного уже нормально получаю температуру. а вот работать с несколькими пока не очень получается. точнее не смог найти пример кода. Может у кого-нибудь есть? А то мне почему то все время попадаются варианты с несколькими датчиками, но каждый датчик вставлен в отдельный порт, а не на одном проводе.
Друг Кота
Аватара пользователя
Сообщения: 7439
Зарегистрирован: Чт ноя 04, 2010 01:56:36
Откуда: г. Москва

Сообщение Satyr »

просто в начале добавляется команда MatchROM и все, дальше как с одним.
Тут смотри в исходникам в 1wire.c http://radiokot.ru/forum/download/file.php?id=80761
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Сообщение Vlad0o »

Спасибо, Satyr!
Реклама
Мучитель микросхем
Аватара пользователя
Сообщения: 420
Зарегистрирован: Чт июн 03, 2010 23:06:12

Сообщение Coviraylhik »

masterpc спасибо за подсказку , пока не получилось воспользоватся , не понял я как прописать это выражение sens.

Vlad0o , а я как раз нацеленно искал, чтобы каждый датчик вставлен в отдельный порт, такой пример попадался?

Так дальше наваял еще один вариант, термометр с точностью в 0,1°C датчик DS18b20.
Значит что хорошего получилось ; в принципе уже полноценный термометр, скомплимировалось без ошибок, точность в 0,1°C , работает в протеусе и испытано в железе на макетной плате, это всё ОК.
Теперь жалуюсь, что не получаеся: как термостат он понимает значения только в положительном диапазоне (зеркально эти же значения дублируются и в отриц. диапазоне, это не порядок).
Несколько тормознут, наверное неуравновешенно выставлены задержки.
Нет датчика (или обрыв датчика) появляется фантастическое число -62428.65534.
Попробовал ему сделать условие.

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

    if (temp_0 > 1000)                           // 
    temp_0 = 0;                                  // 
        else
        {
        temp_0 = temp_0;
        }
пока неполучилось.
В архиве проект исходника и протеус.
Вложения
Mega8_wire_LCD16x2_02.rar
(118.93 КБ) 416 скачиваний
Некакого перимирия, Некаких мирных шагов навстречу и периговоров.
Реклама
Нашел транзистор. Понюхал.
Аватара пользователя
Сообщения: 160
Зарегистрирован: Чт авг 13, 2009 08:22:53
Откуда: Vinnitsa

Сообщение masterpc »

Coviraylhik писал(а):masterpc спасибо за подсказку , пока не получилось воспользоватся , не понял я как прописать это выражение sens.

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

/чтение байта из 1-wire
void rd_mem_s1(void){
  
     byte i, j,chr;
     byte bufsens[9];
     
	reset_wire_s1();
	wire_out_s1(0xCC);
	wire_out_s1(0xBE);
	
	for(i=0; i<9; i++){
                            chr=0x00;
                            for (j=0; j<8; j++){
                                                  chr=(chr>>1);
                                                  _CLI();
                                                  TX_W01();
                                                  PAUSE_US(4);  // ~4 us
                                                  TDN1();
                                                  PAUSE_US(8);  // ~8 us
                                                  if one_set1()	chr|=0x80;	                                                                     
                                                  _SEI();
                                                  PAUSE_US(120);  // ~120us 
                                              }
                            bufsens[i]=chr;
                        }
         if((CalcCrcT(bufsens,9)==0)){                                                                 
                                       byte k;
                                       for(k=0; k<9; k++) sens[0][k]=bufsens[k]; 
                                     }                           
}
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Сообщение Vlad0o »

Coviraylhik, вот http://www.sicklinger.com/en/atmel-avr- ... -in-c.html
Но вроде бы если получилось с одним датчиком, то с большим числом и каждом выделить порт - не сильно сложно.
Открыл глаза
Сообщения: 67
Зарегистрирован: Вт июл 19, 2011 19:09:46

Сообщение Vlad0o »

Я не сильно разбираюсь, но эта функция определяет наличие датчика на линии.

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

//////////////////////////////////////////////////////////////////////////////
// OW_RESET - performs a reset on the one-wire bus and
// returns the presence detect. Reset is 480us, so delay
// value is (480-24)/16 = 28.5 - we use 29. Presence checked
// another 70us later, so delay is (70-24)/16 = 2.875 - we use 3.
//
unsigned char ow_reset(void)
{
unsigned char presence;
DQ = 0; //pull DQ line low
delay(29); // leave it low for 480us
DQ = 1; // allow line to return high
delay(3); // wait for presence
presence = DQ; // get presence signal
delay(25); // wait for end of timeslot
return(presence); // presence signal returned
} // 0=presence, 1 = no part
И вполне можно написать условие:
if (ow_reset() ==1)
{lcd_write("no part")}
else
{.....}

Как то так :)) Повторюсь. у меня у самого только только начало что то получаться с программированием. и после LCD, 1-wire постигаю))
Мучитель микросхем
Аватара пользователя
Сообщения: 420
Зарегистрирован: Чт июн 03, 2010 23:06:12

Сообщение Coviraylhik »

Vlad0o писал(а):...... С одного уже нормально получаю температуру. а вот работать с несколькими пока не очень получается. точнее не смог найти пример кода. Может у кого-нибудь есть?
Освоил немножко как "размножаются" датчики , вот сделал термометр на два датчика, оч. маленькй код в программе , однако прошивка весит , аж 9кб... Тем не менее все работает и в железе и в протеусе, весь проект приложил в архиве, тренируюсь на CodeVisionAVR.
Coviraylhik писал(а):Нет датчика (или обрыв датчика) появляется фантастическое число -62428.65534.Попробовал ему сделать условие.
пока сделал примитивно
  • temp2 = ds18b20_temperature( &rom_code[1][0] );//читаем температуру с выбранного датчика
    if ((temp2 < 130) & (temp2 > -60)) // установим границу диапазона
    temp2= temp2;
    else
    {
    temp2 =0; //если выходит за границу тогда 0
    }

    sprintf(lcd_buffer_2," t%u=%i.%u\xdfC ",i+2,temp2,temp2%1);
    lcd_gotoxy(0,1);
    lcd_puts(lcd_buffer_2); //выводим масив на LCD
    delay_ms(30); //ждём
    };
Конечно сначала предполагалось сделать , сообщение error но это пока еще в перспективе.
Вложения
Mega8_wire_LCD16x2_03.rar
(93 КБ) 375 скачиваний
Некакого перимирия, Некаких мирных шагов навстречу и периговоров.
Мучитель микросхем
Аватара пользователя
Сообщения: 420
Зарегистрирован: Чт июн 03, 2010 23:06:12

Сообщение Coviraylhik »

Всем спасибо кто принял участие в теме, определённый период создания своей программы я достиг, получилось устройство с четырмя термометрами, работают на одной шине, термометры скомбинированы в один МК по приведенным выше примерам, точность измерения 1°C и 0,1°C с датчиками DS18b20.
Изображение
Проверено в железе работает , просто работает, как и положено.
Изображение
Вывод; для начинающих после мигания светодиодами, будет очень просто разобратся с программой таких вот термометров.
В архиве протеус и прошивка термометра на 4 канала измерения.
Вложения
48_term.rar
(74.14 КБ) 872 скачивания
Некакого перимирия, Некаких мирных шагов навстречу и периговоров.
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 24, 2011 16:25:51
Откуда: Николаев

Сообщение TGU62 »

Доброго времени суток. Пересмотрел кучу информации по термостатам, но никак не могу найти то, что нужно. А именно, термостат с одним датчиком на Атмега8 с четырехразрядным семисегментным светодиодным индикатором. Если кто может, дайте пожалуйста схему и прошивку такого устройства.
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город

Сообщение Мастер Ломастер »

TGU62 писал(а):Доброго времени суток. Пересмотрел кучу информации по термостатам, но никак не могу найти то, что нужно. А именно, термостат с одним датчиком на Атмега8 с четырехразрядным семисегментным светодиодным индикатором. Если кто может, дайте пожалуйста схему и прошивку такого устройства.
вот этот термостат видели?
битва с дураками проиграна, победители торжествуют. слава победителям!
Контактная информация:
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 24, 2011 16:25:51
Откуда: Николаев

Сообщение TGU62 »

Видел. "Термостат: меньше не бывает" меня вполне устраивает, со схемой все понятно. А вот прошивку на него по ссылке найти не могу. Там только более новые версии и не для Атмеги8. Если можете дать ссылку на нужную прошивку, буду очень благодарен.
Родился
Сообщения: 3
Зарегистрирован: Чт ноя 24, 2011 16:25:51
Откуда: Николаев

Сообщение TGU62 »

Спасибо, все нашел. :)))
Потрогал лапой паяльник
Аватара пользователя
Сообщения: 374
Зарегистрирован: Ср сен 14, 2011 10:37:28
Откуда: Кострома

Сообщение marinkaest »

А ПИД термостат с автозахватом кто делал?
1602 ,М16, 18б20
:)
Контактная информация:
Ответить

Вернуться в «AVR»