martedì 14 marzo 2017

Lettura codice rom sensore di temperatura DS18B20 tramite PIC16F886

Lettura indirizzo sensore di temperatura DS18B20 tramite PIC16F886

Il progetto si propone di acquisire il codice rom del sensore di temperatura DS18B20 e di
visualizzarlo tramite terminale USART.
La conoscenza del codice rom è necessario quando su un bus 1-wire sono collegati piu sensori.
Il codice rom, costituito da 8 byte, rappresenta l'indirizzo del sensore.
L'hardware utilizzato è lo stesso presentato in questo progetto. Questo è lo schema elettrico.
Il sensore DS18B20 è collegato al pin RA5 del pic. Il programma caricato sul pic, interroga il
sensore e riceve il codice rom ad ogni reset (pulsante premuto e rilasciato). Il codice rom viene
inviato al PC tramite seriale e visualizzato tramite un terminale USART.Nel nostro caso si è
utilizzato Mikroelektronika Usart Terminal contenuto nei tool dell' IDE.

Adesso qualche foto:



PIC16F886 + DS18B20
foto 1
PIC12F1840
foto 2


interfaccia rs232 microcontrollori pic
foto 3
interfaccia rs232 microcontrollori pic
foto 4

















La foto 4 ritrae il Terminal USART di Mikroelektonika. Gli 8 byte evidenziati nel riquardo
receive rappresentano il codice rom del sensore.

Adesso passiamo al codice in Mikroc caricato sul pic :

/*******************************************************************************
MCU                : pic16f886
osc                : oscillatore interno impostato a 8 Mhz
realizzato da      : Ciro Marinelli
data               : 13/03/2017
********************************************************************************
*******************************************************************************/
#define OW_READ_ROM          0x33

//******************************************************************************
// variabili globali
//******************************************************************************
unsigned char *ID;
unsigned char a ;
//******************************************************************************
// dichiarazione funzioni
//******************************************************************************
void inizializza(void);
void OWReadRom(unsigned char *ID);
//******************************************************************************
// funzioni
//******************************************************************************
 void OWReadRom(unsigned char *ID)
     {
      OW_Reset(&porta,5);                     // resetto la linea one-wire
      OW_Write(&porta,5,OW_READ_ROM);         // invio il comando readrom
      for(a=0; a<8; a++)                      // ciclo per leggere gli 8 byte restituiti dal dispositivo
         {
         ID[a]=OW_Read(&porta,5);             // memorizzo i byte ricevuti
         }
     }

//*****funzione impostazioni iniziali PIC***************************************
void init_pic(void)
{
 OSCCON = 0X70;                      // imposto l'oscillatore interno a 8MHz
 trisa = 0x00;                       // imposta porta come output
 trisb = 0x00;                       // imposta portb come output
 trisc = 0x00;                       // imposta portc come output
 porta = 0x00;                       // azzera porta
 portb = 0x00;                       // azzera portb
 portc = 0x00;                       // azzera portc
 ansel=0x00;                         // disabilito gli ingressi analogici
 anselh=0x00;                        //
 c1on_bit=0x00;                      // disabilito i comparatori
 c2on_bit=0x00;                      //
 UART1_Init(9600);                   // inizializza il modulo seriale 1 a 9600 baud
 delay_ms(1000);
}
//*****funzione principale******************************************************
void main()
{
 init_pic();
 OWReadRom(ID);
 if (UART1_Tx_Idle() == 1)
  {
   UART1_Write(ID[0]);
   UART1_Write(ID[1]);
   UART1_Write(ID[2]);
   UART1_Write(ID[3]);
   UART1_Write(ID[4]);
   UART1_Write(ID[5]);
   UART1_Write(ID[6]);
   UART1_Write(ID[7]);
   }
}

sabato 4 marzo 2017

Ottimizzazione hardware PIC12F1480 e DHT22

Ottimizzazione hardware PIC12F1480 e DHT22

Per snellire la parte Hardware di questo progetto si è intervenuto eliminando l'interfaccia rs232 auto
costruita sostituendola con un adattatore SERIALE/USB del tipo FTD1232, facilmente reperibile in
rete a pochi euro.
quest'adattatore può comunicare con dispositivi alimentati sia a 5Vcc che a 3.3Vcc. Nel nostro
caso usiamo un'alimentazione di 5Vcc, quindi spostiamo l'apposito jumper presente sulla scheda
verso i 5Vcc.
Ecco lo schema elettrico.
Come si vede i collegamenti tra il PIC e l'interfaccia FTD1232 si riduce a quattro fili, due per
l'alimentazione e due per i dati (TX, RX).

Per rendere compatto l' hardware si è realizzato una scheda d'interfaccia tra PIC e FTD132, come
si vede dalle seguenti immagini.





interfaccia pic FTD1232
scheda interfaccia lato rame
scheda interfaccia pic FTD1232
scheda interfaccia lato componenti



scheda FTD1232
scheda FTD1232 lato componenti
Scheda FTD1232
scheda FTD1232 lato rame


microcontrollore PIC12F1840 DHT22
scheda madre con DHT22
PIC12F1840 DHT22 FTD1232
scheda madre + DHT22 + adattatore FTD1232


PIC12F1840 DHT22 FTD1232
scheda madre + DHT22 + adattatore FTD1232
PIC12F1840 DHT22 FTD1232
scheda madre + DHT22 + adattatore FTD1232





mercoledì 1 marzo 2017

Acquisizione temperatura e umidità con PIC12F1480 e DHT22

Acquisizione temperatura e umidità con PIC12F1480 e DHT22

Il progetto si propone di acquisire temperatura e umidità dell'ambiente circostante e d' inviare i dati al
pc dove vengono visualizzati tramite un software realizzato in C#. Quest'ultimo permette la
visualizzazione dei dati in real-time ed il salvataggio per eventuali elaborazioni
iniziamo analizzando lo schema elettrico.

Dallo schema elettrico si nota che il tutto si riduce a pochissimi componenti. Per ridurre le
dimensioni della scheda e risparmiare componenti, si è deciso di non implementare il circuito ICSP.
Sul pin MCRL del microcontrollore si nota la solita configurazione per il reset. la resistenza da 10KΩ
garantisce i 5V durante il normale funzionamento, mentre la resistenza da 100Ω insieme al contatto
collegato a massa resetta il PIC.
Il condensatore da 100nF filtra i disturbi provenienti dall'alimentazione.
Il sensore DHT22 prevede il condensatore da 100nF per il filtraggio dell'alimentazione e la resistenza
di pull-up da 10KΩ sulla linea dati.

Per comunicare con il PC è stato creata l'interfaccia rs232 costituita dal chip MAX232 con i relativi
quattro condensatori da 10mF e la resistenza di pull-up da 1KΩ posta sulla linea TX del PIC.
Il circuito viene alimentato tramite la porta USB del PC.

La visualizzazione a video dei parametri è affidata al software T-RH appositamente creato per questo
hardware e scaricabile qui.
Per far funzionare il software è necessario che sul pc sia installato NET Framework.
Attenzione, se durante l'esecuzione il software visualizza valori senza la virgola, bisogna andare a
sostituire la virgola con il punto in pannello di controllo/ lingua/ cambia ora, data e formato dei numeri/.
Adesso qualche foto della realizzazione:




PIC12F1840
scheda madre lato componenti
PIC12F1840
scheda madre lato piste


interfaccia rs232 microcontrollori pic
scheda rs232 lato componenti
interfaccia rs232 microcontrollori pic
scheda rs232 lato piste


PIC12F1840 DHT22
scheda madre con DHT22
PIC12F1840 DHT22
scheda madre + rs232 + DHT22


software temperatura umidità
Software T-RH
software temperatura umidità DHT22
Esempio di curve

































Di seguito il codice in mikroC:




/******************************************************************************

MCU                : PIC12F1840
osc                  : oscillatore interno impostato a 8 Mhz
realizzato da     : Ciro marinelli
data                 : 18/01/2017

NOTE:


******************************************************************************/

/*******variabili globali*****************************************************/


unsigned char  Check, T_byte1, T_byte2, RH_byte1, RH_byte2;
unsigned Temp, RH, Sum;
char *text_1 = " 00.0", *text_2 = " 00.0";

//*****configura connessioni sensore********************************************

sbit Data at RA5_bit;
sbit DataDir at TRISA5_bit;

//*****funzione inizio comunicazione col sensore********************************

void StartSignal()
{
 DataDir = 0;     // imposta RA5 come output
 Data    = 0;     // imposta RA5 a zero
 Delay_ms(20);    // attendi 20 millisecondi
 Data    = 1;     // imposta RA5 a uno
 Delay_us(30);    // attendi 30 microsecondi
 DataDir = 1;     // imposta RA5 come input
}

//*****funzione risposta sensore************************************************

void CheckResponse()
{
 Check = 0;
 delay_us(40);
 if (Data == 0)
  {
   delay_us(80);
   if (Data == 1)
    {
    Check = 1;
    delay_us(40);
    }
  }
}

//*****funzione leggi dati******************************************************

char ReadData()
{
 char i, j;
 for(j = 0; j < 8; j++)
   {
    while(!Data);                //Attendo che PORTA.F5 va alto
    delay_us(30);
    if(!Data)
     {
      i&= ~(1<<(7 - j));
     }
     else
        {
         i|= (1 << (7 - j));
         while(Data);            //Attendo che PORTA.F5 va basso
        }
   }
 return i;
}
//*****funzione DHT22***********************************************************

void DHT22(void)
{
      StartSignal();
      CheckResponse();
      if(Check == 1)
       {
        RH_byte1 = ReadData();
        RH_byte2 = ReadData();
        T_byte1 = ReadData();
        T_byte2 = ReadData();
        Sum = ReadData();
        if(Sum == ((RH_byte1+RH_byte2+T_byte1+T_byte2) & 0XFF))
         {
          Temp = T_byte1;
          Temp = (Temp << 8) | T_byte2;
          RH = RH_byte1;
          RH = (RH << 8) | RH_byte2;
          if (Temp > 0X8000)
           {
            Temp = Temp & 0X7FFF;
            text_1[0]="-";
           }
            else
               {
                text_1[0]="";
               }
              
            text_1[1] = (RH / 100) % 10 + 48;
            text_1[2] = (RH / 10) % 10 + 48;
            text_1[4] =  RH % 10 + 48;
            text_2[1] = (Temp / 100) % 10+48;
            text_2[2] = (Temp / 10) % 10+48;
            text_2[4] = Temp % 10 + 48;

            if (UART1_Tx_Idle() == 1)
             {
              UART1_Write_Text("H");
              UART1_Write(text_1[1]);
              UART1_Write(text_1[2]);
              UART1_Write(text_1[3]);
              UART1_Write(text_1[4]);
              UART1_Write_Text("T");
              UART1_Write(text_2[1]);
              UART1_Write(text_2[2]);
              UART1_Write(text_2[3]);
              UART1_Write(text_2[4]);
              UART1_Write_Text("_");
              }
          }
       }
          delay_ms(2000);
}

//*****funzione impostazione pic************************************************

void init_pic(void)
{
 osccon=0X70;                     // imposta l'oscillatore interno a 8MHz  "01110000"
 ansela=0x00;                     // disabilito gli ingressi analogici
 adcon0=0x00;                     // spengo il convertitore A/D
 trisa=0x00;                      // imposta porta come output
 porta=0x00;                      // azzera porta
 UART1_Init(9600);                // Initialize UART module at 9600 bps
}
//*****funzione principale******************************************************

void main()
{
 init_pic();
 while(1)
     {
      DHT22();
     }
}

martedì 21 febbraio 2017

Temperatura e umidità con pic16F886 e DHT22

Temperatura e umidità con pic16F886 e DHT22

Il progetto consiste nel rilevare temperatura e umidità relativa (RH) dell’ambiente circostante.
Il microcontrollore PIC16F886 dialoga con il sensore DHT22 e visualizza le due grandezze sul
display LCD 16x2.
Senza soffermarsi sulle caratteristiche dei due componenti principali, verranno di seguito descritti
lo schema elettrico e il codice caricato sul microcontrollore.
Partiamo dallo schema elettrico


Tutti i particolari descritti in seguito, necessari alla realizzazione del circuito, si possono facilmente
reperire:
Le due resistenze (10kΩ, 100Ω) servono per resettare il micro.
Il diodo 1N4148 entra in gioco quando usiamo ICSP.
I cinque condensatori da 100nF filtrano i disturbi provenienti dall’alimentazione.
Il clock è generato dall’oscillatore interno impostato a 8Mhz. Questa soluzione permette di
risparmiare tre componenti (il quarzo da 8 Mhz e i due condensatori da 22pF) e guadagnare due pin I/O.
Il modulo LCD (controller HD44780) è collegato al micro con un BUS a 6 fili. La resistenza da 100Ω
limita la corrente per il circuito di retroilluminazione e il trimmer da 10kΩ si occupa di regolare
il contrasto.
Il sensore DHT22 è collegato al micro con un solo filo e la resistenza di pull-up da 4,7kΩ garantisce
“l’uno logico” sulla linea dati.
Come si nota dallo schema non è previsto nessun circuito d’alimentazione, infatti è possibile alimentare
tutto tramite la porta USB del PC. Questa scelta deriva da un possibile ampliamento del progetto
(comunicazione col PC).




scheda madre lato componenti
scheda madre lato componenti
scheda madre lato piste
scheda madre lato piste


sensore con scheda lato componenti
sensore con scheda lato componenti


sensore con scheda lato piste
sensore con scheda lato piste


sensore su scheda
sensore su scheda


LCD e scheda
LCD e scheda


LCD collegato alla scheda
LCD collegato alla scheda


progetto funzionale pic16f886 dht22 lcd
progetto funzionante






















Finalmente siamo arrivati alla parte più importante del progetto....... , la creazione del codice
che darà vita all'hardware.
Il firmware è stato realizzato con mikroc pro ed è stato caricato sul pic utilizando il programmatore
PICKIT3 e come software MPLAB IPE.

Ecco il codice:


/*******************************************************************************

MCU                : pic16f886
osc                   : oscillatore interno impostato a 8 Mhz
realizzato da    : Ciro Marinelli
data                  : 19/12/2016

NOTE:

*******************************************************************************/


//*****configura connessioni LCD************************************************

sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;

//*****configura connessioni sensore********************************************

sbit Data at RA5_bit;
sbit DataDir at TRISA5_bit;

//*****dichiarazione variabili globali******************************************

 unsigned char  Check, T_byte1, T_byte2, RH_byte1, RH_byte2, Ch ;
 unsigned int Temp, RH, Sum, n=0 ;

//*****funzione inizio comunicazione col sensore********************************

void StartSignal()
{
 DataDir = 0;           // imposta RA5 come output
 Data    = 0;            // imposta RA5 a zero
 Delay_ms(20);       // attendi 20 millisecondi
 Data    = 1;           // imposta RA5 a uno
 Delay_us(30);       // attendi 30 microsecondi
 DataDir = 1;         // imposta RA5 come input
}

//*****funzione risposta sensore************************************************

void CheckResponse()
{
 Check = 0;
 delay_us(40);
 if (Data == 0)
  {
   delay_us(80);
   if (Data == 1)
    {
    Check = 1;  
    delay_us(40);
    }
  }
}

//*****funzione leggi dati******************************************************

char ReadData()
{
 char i, j;
 for(j = 0; j < 8; j++)
   {
    while(!Data);               //Attendo che PORTA.F5 va alto
    delay_us(30);
    if(!Data)
     {
      i&= ~(1<<(7 - j)); 
     }
     else
        {
         i|= (1 << (7 - j)); 
         while(Data);          //Attendo che PORTA.F5 va basso
        }
   }
 return i;
}

//*****funzione DHT22***********************************************************

void DHT22(void)
{
      StartSignal();
      CheckResponse();
      if(Check == 1)
       {
        RH_byte1 = ReadData();
        RH_byte2 = ReadData();
        T_byte1 = ReadData();
        T_byte2 = ReadData();
        Sum = ReadData();
        if(Sum == ((RH_byte1+RH_byte2+T_byte1+T_byte2) & 0XFF))
         {
          Temp = T_byte1;
          Temp = (Temp << 8) | T_byte2;
          RH = RH_byte1;
          RH = (RH << 8) | RH_byte2;
          if(n)
           {
            Lcd_Cmd(_LCD_CURSOR_OFF);       
            Lcd_Cmd(_LCD_CLEAR);            
            n=0;
           }
          Lcd_Out(1, 2, "Temp :   .   C ");
          Lcd_Out(2, 2, "RH   :   .  %  ");
          if (Temp > 0X8000)                                   // verifico se la temperatura è negativa
           {
            Lcd_Out(1, 8, "-");
            Temp = Temp & 0X7FFF;
           }

            LCD_Chr(1, 9, 48 + ((Temp / 100) % 10));
            LCD_Chr(1, 10, 48 + ((Temp / 10) % 10));
            LCD_Chr(1, 12, 48 + (Temp % 10));
            LCD_Chr(1, 14, 223);
            LCD_Chr(2, 9, 48 + ((RH / 100) % 10));
            LCD_Chr(2, 10, 48 + ((RH / 10) % 10));
            LCD_Chr(2, 12, 48 + (RH % 10));
          }
          else
             {
              Lcd_Cmd(_LCD_CURSOR_OFF);       
              Lcd_Cmd(_LCD_CLEAR);            
              Lcd_Out(1, 1, "Check sum error");
              n=1;
             }
       }
       else
          {
           Lcd_Cmd(_LCD_CURSOR_OFF);       
           Lcd_Cmd(_LCD_CLEAR);            
           Lcd_Out(1, 1, "il sensore");
           Lcd_Out(2, 1, "non risponde");
           n=1;
          }
          delay_ms(2000);
}

//*****funzione impostazioni iniziali PIC***************************************

void init_pic(void)
{
 OSCCON = 0X70;                      // imposto l'oscillatore interno a 8MHz
 trisa = 0x00;                                 // imposta porta come output
 trisb = 0x00;                                // imposta portb come output
 trisc = 0x00;                                // imposta portc come output
 porta = 0x00;                              // azzera porta
 portb = 0x00;                              // azzera portb
 portc = 0x00;                              // azzera portc
 ansel=0x00;                                // disabilito gli ingressi analogici
 anselh=0x00;                              //
 c1on_bit=0x00;                          // disabilito i comparatori
 c2on_bit=0x00;                          //
 Lcd_Init();
 Lcd_Cmd(_LCD_CURSOR_OFF);          
 Lcd_Cmd(_LCD_CLEAR);               
 delay_ms(2000);                    
}
//*****funzione principale******************************************************

void main()
{
 init_pic();
 while(1)
     {
      DHT22();
     }
}