Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Checksum error

Subnascent

New Member
Hello,
i am trying to do a code using a temperature and humidity sensor (DHT11), and i am getting checksum error as my output in LCD. i am using keil uv5 and proteus simulator
What is the error in this code?

C-like:
#include <stdio.h>
#include <reg52.h>
#include <intrins.h>
#define lcd_data P2
 
int i;
int temp=0;
unsigned char humidity=0;
unsigned char humidity_point=0;
unsigned char temperature=0;
unsigned char temp_point=0;
unsigned char check=0;
unsigned char h[]="00.0";
char a,b;
 
sbit DTH=P3^0;
sbit rs=P1^0; //reg select
sbit rw=P1^1; //rewrite
sbit en=P1^2;  //enable
 
void lcd_init();
void cmd(unsigned char a);
void dat(unsigned char b);
void show(unsigned char *s);
void lcd_delay();
 
void lcd_init()
{
    cmd(0x38);   //defining is first, the peripherals and the line
    cmd(0x0e); 
    cmd(0x01);
    cmd(0x06);  //entry mode - after refreshing we're ready to use it
    cmd(0x0c);  //defining cursor
    cmd(0x80);    // start from the first row first column
}
 
void cmd(unsigned char a)
{
    lcd_data=a;
    rs=0;   //registers select
    rw=0; // write mode
    en=1; //enabling writing to the registers, power should be on when in use
    lcd_delay();
    en=0;
}
 
void dat(unsigned char b)
{
    lcd_data=b;
    rs=1;
    rw=0;
    en=1;
      lcd_delay();
    en=0;
}
 
void show(unsigned char *s)
{
    while(*s) {
        dat(*s++);
    }
}
 
void lcd_delay(){
    int i;
    for (i=0;i<10000;i++){
    }
}
 
delay_ms(unsigned char val){
        if (val == 18){
            TMOD=0x01;
            TH0=0xB9;
            TL0=0xB0;
            TR0=1;
            while (TF0 == 0);
            TR0=0;
        }
        else if (val == 25){
            TMOD=0x01;
            TH0=0x9E;
            TL0=0x58;
            TR0=1;
            while (TF0 == 0);
            TR0=0;
        }
}
delay_us(unsigned char val){
    if (val == 40){
        TMOD=0x01;
        TH0=0xFF;
        TL0=0xD8;
        TR0=1;
        while (TF0 == 0);
        TR0=0;
    }
    else if (val == 35){
        TMOD=0x01;
        TH0=0xFF;
        TL0=0xDD;
        TR0=1;
        while (TF0 == 0);
        TR0=0;
    }
}
void set(){
    DTH=0;
    delay_ms(18);
    DTH=1;
    delay_us(40);
}
 
void response(){
    while (DTH==1);
    while (DTH==0);
    while (DTH==1);
}
 
unsigned char data_transmit(){
    unsigned char datas=0;
    for (i=0;i<8;i++){
        while (DTH==0);
        delay_us(40);
        if (DTH==1){
            datas = (1 << (7-i))|datas;
        }
        while (DTH == 1);
    }
    return datas;
}
 
void main(){
    lcd_init();
  
    while (1){
        set();
        response();
        humidity = data_transmit();
        humidity_point=data_transmit();
        temperature=data_transmit();
        temp_point=data_transmit();
        check=data_transmit();
        cmd(0x80);
        if (check == (humidity+humidity_point+temperature+temp_point)){
            show("humidity:");
            h[0]=(humidity/10)+48;
            h[1]=(humidity%10)+48;
            show(h);
        }
        else {
            cmd(0x80);
            show("Checksum Error!");
        }
        lcd_delay();
        cmd(0x01);
    }
}
 
I've never used a DHT11 yet, but the first thing I'd try as you have a display is to dump the five bytes you receive to the screen, in hexadecimal, so you can see the data being received & make sure it looks sensible?

I'd also suggest cleaning up the program a bit. It could be too slow in the simulator.

(I would probably use a shift register or byte array and get all the bits in one go, rather than separate calls for each byte).

Doing all 40 bits in one go, rather than multiple calls, should be faster.

You could speed up the bit read function by having another byte (unsigned char) variable, initialised to 0x80 at the start, then shift that right at the end of each loop.

You then have a ready-to-use bit to OR in for a one, without the (1 << (7-i)) offset & shift calculation. (Always try to avoid anything that needs run-time calculation, if there is an alternate).

And "data_transmit" to read data from something is just confusing?! o_O
 
I did this some years back.. I have the code in the repository somewhere, but its a bit of a mess.. When the "upgrade" was done loads of files went walkabout... I will try to find said code, but I'm sure it was on a 51 derivative albeit maybe asm..
 

Latest threads

New Articles From Microcontroller Tips

Back
Top