Опубликовано 2013-03-21 10:56:23 автором Ruslan

Управление микроклиматом в инкубаторе на AVR


Дело было так: решил мой кум заняться разведением с/х птицы, и пришел за советом ко мне, что и как бы все это организовать, автоматизировать весь процесс. Так как кум у меня отличный строитель и не очень разбирается в цифровой электронике и программировании, я взялся сделать ему для инкубатора электронику, которая бы следила за температурой в рабочей среде, переворачивала яйца несколько раз в день, охлаждала рабочую область инкубатора и считала время с начала выседки. И еще нужно было всю информацию выводить на семисегментный led-индикатор.Схема всего устройства електронная схема инкубатора. Устройство можно условно разделить на три блока.
  • Измерение температуры реализовано с помощю датчика ds18b20 цокольовка ds18b20 схема подключения к мк подключения  ds18b20 к мк и вывод ее на семисегментный индикатор
  • коммутации нагрузки в переменном токе, реализовано простое включение и отключения ламп накаливания с помошью симистора и симисторного оптодрайвера комутация нагрузки в переменном токе
  • коммутация и реверс двигателя постоянного тока, реализована на H мосте комутация реверс двигателя постоянного тока

Дальше нужно было разработать программу, чтобы управлять всем этим добром.


#include <mega8.h> 
#include <delay.h> 
#asm                                                    
                .equ __w1_port=0x12;   
                .equ __w1_bit=5 
#endasm 
//#include <1wire.h> 
#include <ds18b20.h> 
 
 
struct Ttime 
{ 
unsigned second:5; 
unsigned  minute:6; 
unsigned  hour:6; 
unsigned  day:5; 
 
}  time={0,0,0,0} ; 
  
 
unsigned char  nomer[]={0b01111101, 
0b00000101,0b01110011,0b01010111,0b00001111,0b01011110, 
0b01111110,0b01000101,0b01111111,0b01011111}; 
 
unsigned char segment[]={0b10011110,0b10011101,0b10011011,}; 
unsigned char i[3]={1,4,5},z=0; 
unsigned char g=0,stan=1;          
unsigned int showled[5];          
unsigned char napramok=0;           
     
unsigned char devices;         //переменная в которой количество присоеденённых датчиков  
unsigned int temp; 
unsigned char t_drob,t1,t2,t_int,t_min=378,t_max=379; 
    
void move_motor(  unsigned int  time,unsigned char shvid) 
   {               
   					int i; 
                      if  (napramok) 
                        {                          
                          TCCR1A=0x81;  
                          OCR1AL=shvid; 
                        }           
                      else 
                        {   
                          OCR1BL=shvid; 
                          TCCR1A=0x21;        
                        };     
                      for (  i=100; i<=time; i+=100)      
                          {       
                          	delay_ms(100);  
                            if  (PIND.7==0)   { TCCR1A=0x81;        napramok=1;  delay_ms(150); break;} 
                            if (PIND.4==0)    { TCCR1A=0x21;        napramok=0; delay_ms(150);  break; }              
                          } 
 
                          TCCR1A=0x01;                 
   } 
   
   
interrupt [TIM2_OVF] void timer2_ovf_isr(void) 
{      
   		  w1_init(); 
          w1_write(0xCC);  
          w1_write(0xBE); 
           
          t1=w1_read(); 
          t2=w1_read(); 
           
          w1_init(); 
          w1_write(0xCC); 
          w1_write(0x44); 
 
  
   if (++time.second==30)         
     {    
     	time.second=0;      
              
            if (  (showled[2]=++time.minute)==60)   
                {   
                	time.minute=0;        
                    move_motor(2600,160);  
 
                    if (   (showled[3]=++time.hour) ==24  )  
                                     {    
                                     	time.hour=0; 
                                     	showled[4]=  ++time.day;  
                                      }   
                }                         
     }                                    
} 
 
// Timer 0 overflow interrupt service routine 
interrupt [TIM0_OVF] void timer0_ovf_isr(void) 
{            
   PORTC=nomer[  i [z]  ]; 
   PORTD=segment[z] | (nomer[  i [z]  ] &  0b01000000  ) ; 
                         
   if (++z==3) z=g; 
} 
 
   
void out(unsigned int k) 
 {                                
  if (k<1000)  
     {     i[2]=k%10;                                       
            i[1]=(k/10)%10; 
            if (   i[0]=k/100     ){ TCCR0=0x03 ; g=0; } else   {  g=1+ !( i[1]); TCCR0=3+g;}                    
     } 
 }  
          
 
void main(void) 
{ 
// Port B initialization 
PORTB=0x00; 
DDRB=0b00000111; 
PORTB.0=1; 
  
// Port C initialization 
DDRC=0xff; 
PORTC=0x00; 
 
PORTD=0b10011000; 
DDRD=0b01000111; 
// Timer/Counter 0 initialization 
// Clock source: System Clock 
// Clock value: 0,977 kHz 
TCCR0=0x03; 
TCNT0=0x00; 
 
// Timer/Counter 1 initialization 
// Clock source: System Clock 
// Clock value: Timer1 Stopped 
// Mode: Normal top=0xFFFF 
// OC1A output: Discon. 
// OC1B output: Discon. 
// Noise Canceler: Off 
// Input Capture on Falling Edge 
// Timer1 Overflow Interrupt: Off 
// Input Capture Interrupt: Off 
// Compare A Match Interrupt: Off 
// Compare B Match Interrupt: Off 
  
TCCR1A=0x01; 
TCCR1B=0x0B; 
TCNT1H=0x00; 
TCNT1L=0x00; 
ICR1H=0x00; 
ICR1L=0x00; 
OCR1AH=0x00; 
OCR1AL=0x64; 
OCR1BH=0x00; 
OCR1BL=0x64; 
 
 
// Timer/Counter 2 initialization 
// Clock source: System Clock 
// Clock value: Timer2 Stopped 
// Mode: Normal top=0xFF 
// OC2 output: Disconnected 
ASSR=0x08; 
TCCR2=0x06; 
TCNT2=0x00; 
OCR2=0x00; 
 
// INT1: On 
// INT1 Mode: Low level 
MCUCR=0x00; 
 
// Timer(s)/Counter(s) Interrupt(s) initialization 
TIMSK=0x41; 
 
// Analog Comparator initialization 
// Analog Comparator: Off 
// Analog Comparator Input Capture by Timer/Counter 1: Off 
ACSR=0x80; 
SFIOR=0x00; 
      
ds18b20_init(0,20,40,DS18B20_11BIT_RES);  
 
#asm("sei")                    
                 
while(1){   
 
     if  (PIND.7==0)  {napramok=1;  move_motor(150,100);  } // 
     if (PIND.4==0)  {napramok=0;  move_motor(150,100);  } 
      
     delay_ms(150); // дребезг контактов 
                
     t_int=   (t1>>4) | ((t2 & 7)<<4); 
     t_drob=t1&15; 
     t_drob= (t_drob<<1) +  (t_drob<<3);  
     t_drob=t_drob>>4; 
                   
     showled[1]= (  (t_int<<1) +  (t_int<<3)  ) +t_drob; //получаем значение температуры 
                   
           
     if  (showled[1]<=374)   PORTB.0=0; 
     else   if (showled[1]>=376)    PORTB.0=1;   
             
     if (PIND.3==0)  
           {              
                    if ( (++stan==5) )   {  TIMSK^=0x01;  PORTC^=PORTC;  PORTD&=~(1<<6);   stan=0; } 
                    else TIMSK=0x41;  
            } 
         
     if  (stan)  out( showled[stan]  );   // выводим нужную величину из масива 
               
      }; 
} 



Работу устройства коротко можно описать так:

Микроконтроллер дает команду на включение датчика температуры, затем - команду на измерение температуры. Датчик измеряет температуру внутри прибора и записывает ее в свой внутренний регистр. Измерение температуры внутри инкубатора Измерение температуры внутри инкубатора Информация о температуре для удобства пользователя выводится на LED-дисплей. Микроконтроллер считывает данные из регистра датчика и преобразует их в нормальный вид. В программе заложены пределы изменения температуры, необходимые для нормальной работы прибора. Эти величины сравниваются с прочитанными, и в зависимости от этого, микроконтроллер делает соответствующие действия: включает или выключает лампы, которые обогревают прибор внутри. Вывод значения температуры на LED-дисплей Вывод значения температуры на LED-дисплей Контроллером включены лампы накаливания Контроллером включены лампы накаливания В связи с технологической необходимостью один раз в два часа контроллер включает электродвигатель для переворачивания яиц. Для этого контроллер подает ШИМ-сигнал (частотой 2 кНz) на определенное плечо Н-моста. Генерация ШИМ-сигнала выполнена с помощью таймера-счетчика, который работает в режиме «быстрый ШИМ». В программе для этого определенные значения записываются в регистры таймера-счетчика. Коэффициент заполнения импульсов регулирует мощность двигателя. Еще одна функция, которую можно выполнять с помощью Н-моста - это реверс двигателя. Это осуществляется путем включения различных плечей Н-моста, что делается программно. Для удобства пользователя реализован вывод на дисплей некоторой дополнительной информации, а именно: количество суток, часов и минут, в течение которых работает прибор. Через 21 сутки в инкубаторе появляются цыплята. В инкубаторе вылупляется цыпленок В инкубаторе вылупляется цыпленок

Комментарии - (5)

Добавить комментарий

Для отправки комментария вы должны авторизоваться.