Conversion Program C to program Basic Measure DTH22

General discussion on mikroBasic PRO for PIC.
Post Reply
Author
Message
Mairot
Posts: 12
Joined: 14 Nov 2010 23:56

Conversion Program C to program Basic Measure DTH22

#1 Post by Mairot » 21 Jul 2013 00:51

Hello.

I have a problem with a conversion of a program written c in a program written in BASIC for display(posting) of the values of a sensor of temperature and humidity DTH22.

The program writes it C work correctly, while that writes in BASIC do not work correctly. I have a doubt on the conversion of the functions(offices) CheckRepsonse and ReadByte.


I use PIC 18F252 with PLL and Quartz 8 MHZ : 32 MHZ.


Thank you for your help(assistant)

Bernard Mairot

program basic :

Code: Select all



program DTHxx

' Declarations section 
dim
  LCD_RS as sbit at RB0_bit
  LCD_EN as sbit at RB1_bit
  LCD_D7 as sbit at RB7_bit
  LCD_D6 as sbit at RB6_bit
  LCD_D5 as sbit at RB5_bit
  LCD_D4 as sbit at RB4_bit

dim
  LCD_RS_Direction as sbit at TRISB0_bit
  LCD_EN_Direction as sbit at TRISB1_bit
  LCD_D7_Direction as sbit at TRISB7_bit
  LCD_D6_Direction as sbit at TRISB6_bit
  LCD_D5_Direction as sbit at TRISB5_bit
  LCD_D4_Direction as sbit at TRISB4_bit
' End Lcd module connections
Dim
  message1 as string[12]
  message2 as string[12]
  check as byte
  TOUT,CheckSum,i,j,k,num as byte
  Dat as sbit at RB3_bit
  DataDir as sbit at TRISB3_bit
  message as string[6]
  T_Byte1,T_Byte2,RH_Byte1,RH_Byte2 as byte
  T, RH as word

sub procedure StartSignal()
  DataDir = 0     ' Data port is output
  Dat    = 0
  Delay_ms(20)    ' Low for at least 18us
  Dat    = 1
  Delay_us(25)    ' High for 20-40 us
  DataDir = 1     ' Data port is input
end sub

sub procedure interrupt
  if(PIR1.TMR2IF) then
   TOUT = 1
   T2CON.TMR2ON = 0   '  stop timer
   PIR1.TMR2IF  = 0   ' Clear TMR0 interrupt flag
  end if
end sub

sub function  CheckResponse() as Byte
  TOUT = 0
  TMR2 = 0
  T2CON.TMR2ON = 1      ' Start TMR2 while waiting for sensor response
  while((not Dat) and (not TOUT)) ' If there's no response within 256us, the Timer2 overflows
     if (TOUT) then
        CheckResponse=0
        Return
     else
        TMR2 = 0
        while(Dat and (not TOUT))
           if (TOUT) then
              CheckResponse =0
              return
           else
              T2CON.TMR2ON = 0
              checkResponse =1
              return
           end if
       wend
     end if
  wend
end sub

sub function ReadByte() as Byte
 num = 0
 DataDir = 1
 for i = 0 to 7
   while(not Dat)
      TMR2 = 0
      T2CON.TMR2ON = 1  ' Start TMR2 from 0 when a low to high data pulse
          while(Dat)    ' is detected, and wait until it falls low again.
             T2CON.TMR2ON = 0  ' Stop the TMR2 when the data pulse falls low.
             if(TMR2 > 60)then
                num = 1<<(7-i)   ' If time > 60us, Data is 1
             end if
         ReadByte=num
         return
         wend
   wend
 next i
 readByte=num
end sub



main:
'   Main program 
  TRISB=%00001000      ' PORTB3 en Entrée CCP1
  PORTB=0
  LCD_Init()           ' Initialisation LCD
  Lcd_Out(1,1,"TEST DTHxx")
  delay_ms(500)
  Lcd_Cmd(_LCD_CLEAR)  ' Effacement LCD
  delay_ms(200)
  J=0
  K=0
  INTCON.GIE = 1   ' Enable global interrupt
  INTCON.PEIE = 1  ' Enable peripheral interrupt
  ' Configure Timer2 module
  PIE1.TMR2IE = 1  ' Enable Timer2 interrupt
  T2CON = 1        ' Prescaler 1:4, and Timer2 is off initially
  PIR1.TMR2IF =0   ' Clear TMR INT Flag bit
  TMR2 = 3
  Lcd_Init()
  Lcd_Cmd(_Lcd_Clear)
  Lcd_Cmd(_LCD_CURSOR_OFF)
  message1 = "Temp =  00.0 C"
  message2 = "RH   =  00.0 %"
while TRUE
    Delay_ms(2000)
    StartSignal
    check = CheckResponse
  if (not check) then
      Lcd_Cmd(_Lcd_Clear)
      Lcd_Out(3, 1, "No response")
      Lcd_Out(4, 1, "from the sensor")
      J=J+1
   else
      RH_Byte1 = ReadByte()
      RH_Byte2 = ReadByte()
      T_Byte1 = ReadByte()
      T_Byte2 = ReadByte()
      CheckSum = ReadByte()
  '   Check for error in Data reception
      if (CheckSum = ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) and 255)) then
         Lcd_Cmd(_Lcd_Clear)
         delay_ms(50)
         RH=(RH_Byte1*256)+RH_Byte2
         T=(T_Byte1*256)+T_Byte2
         message1[12] = 223 ' Degree symbol
         message1[8]=T/100 +48
         T=T mod 100
         message1[9]= T/10 +48
         message1[11]=T mod 10 +48
         message2[8]=RH/100 +48
         RH=RH mod 100
         message2[9]= RH/10 +48
         message2[11]= RH mod 10 +48
         delay_ms(10)
         Lcd_Out(1, 1, message1)
         Lcd_Out(2, 1, message2)
         K=K+1
         ByteToStr(K,message)
         Lcd_Out(1,16,message)
         ByteToStr(J,message)
         Lcd_Out(4,16,message)
     else
        Lcd_Cmd(_Lcd_Clear)
        Lcd_Out(3, 1, "Checksum Error!")
        Lcd_Out(4, 1, "Trying Again ...")
     end if
   end if
   delay_ms(500)
wend
end.
Program C :

Code: Select all



/*
 Project: Temperature and humidity measurements using DHT11
 MCU: PIC16F887
 Clock: 10.0MHz external crystal
 Board: UNI-DS6 board
 Date: Jan 10, 2012
 Written by: Rajendra Bhatt (http://www.embedded-lab.com)
*/


// LCD module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB1_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;

sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB1_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections

sbit Data at RB3_bit;
sbit DataDir at TRISB3_bit;
char message1[] = "Temp =  00.0 C";
char message2[] = "RH   =  00.0 %";
char message[6];
unsigned short TOUT = 0, CheckSum, i,j,k;
unsigned short T_Byte1,T_Byte2,RH_Byte1,RH_Byte2;
int T,RH;
float Te, Hu;

void StartSignal(){
  DataDir = 0;     // Data port is output
  Data    = 0;
  Delay_ms(20);    // Low for at least 18us
  Data    = 1;
  Delay_us(25);    // High for 20-40 us
  DataDir = 1;     // Data port is input

}

unsigned short CheckResponse(){
  TOUT = 0;
  TMR2 = 0;
  T2CON.TMR2ON = 1;      // Start TMR2 while waiting for sensor response
  while(!Data && !TOUT); // If there's no response within 256us, the Timer2 overflows
  if (TOUT) return 0;    // and exit
  else {
   TMR2 = 0;
   while(Data && !TOUT);
   if (TOUT) return 0;
   else {
    T2CON.TMR2ON = 0;
    return 1;
   }
  }
}

unsigned short ReadByte(){
  unsigned short num = 0;
  DataDir = 1;
  for (i=0; i<8; i++){
   while(!Data);
   TMR2 = 0;
   T2CON.TMR2ON = 1;  // Start TMR2 from 0 when a low to high data pulse
   while(Data);       // is detected, and wait until it falls low again.
   T2CON.TMR2ON = 0;  // Stop the TMR2 when the data pulse falls low.
   if(TMR2 > 60) num |= 1<<(7-i);  // If time > 60us, Data is 1
   }
  return num;
}

void interrupt(){
  if(PIR1.TMR2IF){
   TOUT = 1;
   T2CON.TMR2ON = 0; // stop timer
   PIR1.TMR2IF  = 0; // Clear TMR0 interrupt flag
  }
}

void main() {
  unsigned short check;
  TRISB = 0b00001000;
  PORTB = 0;
  J=0;
  K=0;
  INTCON.GIE = 1;    //Enable global interrupt
  INTCON.PEIE = 1;   //Enable peripheral interrupt
  // Configure Timer2 module
  PIE1.TMR2IE = 1;  // Enable Timer2 interrupt
  T2CON = 1;        // Prescaler 1:4, and Timer2 is off initially
  PIR1.TMR2IF =0;   // Clear TMR INT Flag bit
  TMR2 = 3;
  Lcd_Init();
  Lcd_Cmd(_Lcd_Clear);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do{
    Delay_ms(2000);
    StartSignal();
    check = CheckResponse();
  if (!check) {
     Lcd_Cmd(_Lcd_Clear);
     Lcd_Out(3, 1, "No response");
     Lcd_Out(4, 1, "from the sensor");
     J=J++ ;
   }
   else{
    RH_Byte1 = ReadByte();
    RH_Byte2 = ReadByte();
    T_Byte1 = ReadByte();
    T_Byte2 = ReadByte();
    CheckSum = ReadByte();
    // Check for error in Data reception
    if (CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF))
    {
    Lcd_Cmd(_Lcd_Clear);
     delay_ms(50);
     RH=(RH_Byte1*256)+RH_Byte2;
     T=(T_Byte1*256)+T_Byte2;
     message1[12] = 223;     // Degree symbol
     message1[8]=T/100 +48;
     T=T%100;
     message1[9]= T/10 +48,
     message1[11]=T%10 +48;
     message2[8]=RH/100 +48;
     RH=RH%100;
     message2[9]= RH/10 +48,
     message2[11]= RH%10 +48;
     delay_ms(10);
     Lcd_Out(1, 1, message1);
     Lcd_Out(2, 1, message2);
     K=K++;
     }
   else{
    Lcd_Cmd(_Lcd_Clear);
    Lcd_Out(3, 1, "Checksum Error!");
    Lcd_Out(4, 1, "Trying Again ...");
   }
   }
 }while(1);
}
Last edited by Mairot on 21 Jul 2013 13:51, edited 3 times in total.

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Conversion Program C to program Basic Measure DTH22

#2 Post by janni » 21 Jul 2013 02:32

Could you use the Code tag when posting? (Mark the code, then press the "Code" button above editing window.) It's tiresome to analyse longer code fragments without any indents and on gray background.

pieadi
Posts: 30
Joined: 02 Jun 2012 18:46

Re: Conversion Program C to program Basic Measure DTH22

#3 Post by pieadi » 07 Oct 2014 07:21

MikroC code compatible with negative temperatures

Code: Select all

//'Test capteur température / humidité AM2302 (DTH22) le 06/10/2014
//PIC 18F2420 Quartz externe 4Mhz le 04/10/2014
//40 us = 40 pour 4MHz ou 80 pour 8MHz avec un prédiviseur de 1:1
// LCD module connections
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;
// End LCD module connections

sbit Data at RA0_bit;
sbit DataDir at TRISA0_bit;
char message1[] = "Temp = 00.0 C";
char message2[] = "RH   = 00.0 %";
unsigned short TOUT = 0, CheckSum, i;
unsigned short T_Byte1, T_Byte2, RH_Byte1, RH_Byte2;
unsigned int Vt, Vh;
void StartSignal(){
  DataDir = 0;     // Data port is output
  Data    = 0;
  Delay_ms(25);    // Low for at least 18us
  Data    = 1;
  Delay_us(30);    // High for 20-40 us
  DataDir = 1;     // Data port is input
}

unsigned short CheckResponse(){
  TOUT = 0;
  TMR2 = 0;
  T2CON.TMR2ON = 1;      // Start TMR2 while waiting for sensor response
  while(!Data && !TOUT); // If there's no response within 256us, the Timer2 overflows
    //uart1_write(TOUT);

    if (TOUT) return 0;    // and exit
     else
   {
     TMR2 = 0;
       while(Data && !TOUT);
        if (TOUT) return 0;
        else
       {
        T2CON.TMR2ON = 0;
         return 1;
       }
   }
}

 unsigned short ReadByte(){
   unsigned short num = 0, t;
    DataDir = 1;
   for (i=0; i<8; i++)
   {
     while(!Data);
      TMR2 = 0;
      T2CON.TMR2ON = 1;  // Start TMR2 from 0 when a low to high data pulse
       while(Data);       // is detected, and wait until it falls low again.
       T2CON.TMR2ON = 0;               // Stop Timer2
       if(TMR2 > 80) num |= 1<<(7-i);  // If time > 40us, Data is 1
   }
      return num;
 }
void interrupt(){
  if(PIR1.TMR2IF){
   TOUT = 1;
   T2CON.TMR2ON = 0; // stop timer
   PIR1.TMR2IF  = 0; // Clear TMR0 interrupt flag
  }
}
void main() {
  unsigned short check;
  TRISA = 0b00100001;
  ADCON1 = 0b00001111; //Port A en digital
  INTCON.GIE = 1;    //Enable global interrupt
  INTCON.PEIE = 1;   //Enable peripheral interrupt
  // Configure Timer2 module
  PIE1.TMR2IE = 1;  // Enable Timer2 interrupt
  T2CON = 0;        // Prescaler 1:1, and Timer2 is off initially
  PIR1.TMR2IF =0;   // Clear TMR INT Flag bit
  TMR2 = 0;
  Lcd_Init();
  Lcd_Cmd(_Lcd_Clear);
  Lcd_Cmd(_LCD_CURSOR_OFF);

  do {
    Delay_ms(1000);
    StartSignal();
    check = CheckResponse();
    if (!check) {
     Lcd_Cmd(_Lcd_Clear);
     Lcd_Out(1, 1, "Pas de reponse");
     Lcd_Out(2, 1, "  du capteur");
    }
    else{
     RH_Byte1 = ReadByte();
     RH_Byte2 = ReadByte();
     T_Byte1 = ReadByte();
     T_Byte2 = ReadByte();
     CheckSum = ReadByte();
     // contrôle checksum
     if (CheckSum == ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) & 0xFF))
        {
        if ((T_Byte1 && 128) == 1)               //Test si négatif
        {                                        //Temp. négative
        T_Byte1 = T_Byte1 - 128;                 //Masque bit 7
        Vt = (T_Byte1 * 256) + T_Byte2;
        message1[6]  = 45;                       //Signe moins
        message1[7]  = (Vt / 100) + 48;          //Dizaine
        message1[8]  = ((Vt % 100) / 10) + 48;   //Unité
        }
        else
        {                                        //Temp. positive
        Vt = (T_Byte1 * 256) + T_Byte2;
        message1[6]  = 32;
        message1[7]  = (Vt / 100) + 48;          //Dizaine
        message1[8]  = ((Vt % 100) / 10) + 48;   //Unité
        }
        message1[10] = (Vt % 10) + 48;           //Décimale
        message1[11] = 223;                      //Symbole degré
       Vh = (RH_Byte1*256) + RH_Byte2;           //Hum.(expl. 647 pour 64.7%)
        message2[7]  = (Vh / 100) + 48;          //Dizaine
        message2[8]  = ((Vh % 100) / 10) + 48 ;  //Unité
        message2[10] = (Vh % 10) + 48 ;          //Décimale
      Lcd_Cmd(_Lcd_Clear);
      Lcd_Out(1, 1, message1);
      Lcd_Out(2, 1, message2);
      }
      else{
       Lcd_Cmd(_Lcd_Clear);
       Lcd_Out(1, 1, "Erreur Checksum !");
      }
    }
  }while(1);
}
Last edited by pieadi on 12 Oct 2014 09:45, edited 2 times in total.

pieadi
Posts: 30
Joined: 02 Jun 2012 18:46

Re: Conversion Program C to program Basic Measure DTH22

#4 Post by pieadi » 08 Oct 2014 09:18

MikroBasic code compatible with negative temperatures

Code: Select all

program Dth2302_MikroBasic1
'Test capteur température / humidité AM2302 (DTH22) le 08/10/2014
'PIC 18F2420 Quartz externe 8 MHz
'Init LCD
dim LCD_RS as sbit at RB4_bit
    LCD_EN as sbit at RB5_bit
    LCD_D4 as sbit at RB0_bit
    LCD_D5 as sbit at RB1_bit
    LCD_D6 as sbit at RB2_bit
    LCD_D7 as sbit at RB3_bit
    LCD_RS_Direction as sbit at TRISB4_bit
    LCD_EN_Direction as sbit at TRISB5_bit
    LCD_D4_Direction as sbit at TRISB0_bit
    LCD_D5_Direction as sbit at TRISB1_bit
    LCD_D6_Direction as sbit at TRISB2_bit
    LCD_D7_Direction as sbit at TRISB3_bit
  Data1 as sbit at RA0_bit                        'Entrée sur RA0
  DataDir as sbit at TRISA0_bit                   'Direction entrée Ra0
  dim message1, message2 as string[13]
  dim DepTmr2 , CheckSum, i, num, Signe as byte
  dim T_Byte1, T_Byte2, RH_Byte1, RH_Byte2,T_Byte11 as byte
  dim Vt,Vh as word
  dim t1, t2 as string[6]
 sub procedure interrupt                         'Interruption Timer2
  if(PIR1.TMR2IF)=1 then
   DepTmr2 = 1
   T2CON.TMR2ON = 0                              'Raz Timer2
   PIR1.TMR2IF  = 0                              'Raz interrupt flag
  end if
 end sub
 Sub procedure AppelCapteur()                     'Appel capteur
   DataDir = 0                                   'Ra0 en sortie
   Data1 = 0                                     'Envoi 0 vers capteur
   Delay_ms(25)                                  'Attente 25 ms
   Data1 = 1                                     'Envoi 1 vers le capteur
   Delay_us(30)                                  'Attente30 us
   DataDir = 1                                   'Ra0 en entrée
 end sub
 sub function ReponseCapteur() as byte           'Teste la réponse du capteur
  DepTmr2 = 0
  TMR2 = 0
  T2CON.TMR2ON = 1                               'Timer 2 enable
  while((Data1 = 0) and (not(DepTmr2)))          'Test état bas < débord T2
  wend
   if DepTmr2 = 1  then
    result =  0                                  'Etat bas trop long
   else
    TMR2 = 0
   end if
     while((Data1 = 1) and (not(DepTmr2)))       'Test état haut < débord. T2
     wend
      if DepTmr2 = 1 then
       result =0                                 'Etat haut trop long
      else
       T2CON.TMR2ON = 0
       result = 1                                'Etat haut OK
      end if
 end sub
 sub function ReadByte() as byte                 'Lecture capteur
 num = 0
 TRISA = 1
 for i = 0 to 7
  while(Data1 = 0)                               'Détection front montant
  wend
   TMR2 = 0                                      'Raz Timer 2
   T2CON.TMR2ON = 1                              'Start Timer 2
    while(Data1 = 1)                             'Détection front descendent
    wend
     T2CON.TMR2ON = 0                            'Arrêt Timer 2
     if(TMR2 > 80) then  num = num or (1<<(7-i)) end if '40 -> 4MHz ou 80 -> 8MHz
 next i
 result = num
 end sub
Main:
  TRISA = 1                                          'RA0 en entrée
  PORTA = 0
  ADCON1 = $0F                                       'Port A en digital
   INTCON.GIE = 1                                    'Enable global interrupt
   INTCON.PEIE = 1                                   'Enable peripheral interrupt
   PIE1.TMR2IE = 1                                   'Enable Timer2 interrupt
   T2CON = 0                                         'Prescaler 1:1
   PIR1.TMR2IF = 0                                   'Clear TMR INT Flag bit
   TMR2 = 0
    Lcd_Init()
    Lcd_Cmd(_Lcd_Clear)
    Lcd_Cmd(_LCD_CURSOR_OFF)
    message1 = "Temp = 00.0 C"
    message2 = "RH   = 00.0 %"
  while TRUE                                         'Boucle infinie
    Delay_ms(2000)
     AppelCapteur()                                  'Appel du capteur
    if ReponseCapteur() = 0 then                     'Test si réponse du capteur
      Lcd_Cmd(_Lcd_Clear)                            'Pas de réponse du capteur
      Lcd_Out(1, 1, "Pas de reponse")
      Lcd_Out(2, 1, "  du capteur")
     else
     RH_Byte1 = ReadByte()                           'Lecture octet fort Hum.
     RH_Byte2 = ReadByte()                           'Lecture octet faible Hum.
     T_Byte1 = ReadByte()                            'Lecture octet fort Temp.
     T_Byte2 = ReadByte()                            'Lecture octet faible Temp.
     CheckSum = ReadByte()
     if (CheckSum = ((RH_Byte1 + RH_Byte2 + T_Byte1 + T_Byte2) and 0xFF)) then
        if testbit(T_Byte1,7) = 1 then               'Test si négatif
         T_Byte1 = T_Byte1 - 128                     'Masque bit 7
         Vt = (T_Byte1 * 256) + T_Byte2              'Temp.(expl. 215 pour -21.5°)
         message1[6]  = 45                           'Signe moins
         message1[7]  = (Vt div 100) + 48            'Dizaine
         message1[8]  = ((Vt mod 100) / 10) + 48     'Unité
        else
         Vt = (T_Byte1 * 256) + T_Byte2              'Temp.(expl. 215 pour 21.5°)

         message1[6]  = 32                           'Signe espace
         message1[7]  = (Vt div 100) + 48            'Dizaine
         message1[8]  = ((Vt mod 100) / 10) + 48     'Unité
        end if
        message1[10] = (Vt mod 10) + 48              'Décimale
        message1[11] = 223                           'Symbole degré
       Vh = (RH_Byte1*256) + RH_Byte2                'Hum.(expl. 647 pour 64.7%)
        message2[7]  = (Vh div 100) + 48             'Dizaine
        message2[8]  = ((Vh mod 100) / 10) + 48      'Unité
        message2[10] = (Vh mod 10) + 48              'Décimale
         Lcd_Cmd(_Lcd_Clear)
         Lcd_Out(1, 1, message1)
         Lcd_Out(2, 1, message2)
       else
        Lcd_Cmd(_Lcd_Clear)
        Lcd_Out(1, 1, "Erreur Checksum !")
     end if
    end if
   wend
end.

Post Reply

Return to “mikroBasic PRO for PIC General”