-1

I tried to personalize shtxx library but there is a problem with this code.

When I run it lcd stuck on "Hello" but if I comment readHumi or readTemp in while, program runs with no problem.

Just when both is not commented program gets stuck on second one and it does not matter which one is first.

I have tested delay between them, try to read in one void and every thing i think should solve but not solved

#include <mega16.h>
#include <delay.h>
#include <stdio.h>
#include <alcd.h>

int temp,humi;
char buffer[16];

#define SCK PORTB.0
#define DATA PINB.1
#define DATAO PORTB.1
#define DATAD DDRB.1

void shtStart(void){
    DATAD = 1; //set B1 Output
    DATAO = 1; //set B1 High
    SCK = 0;   //set B0 Low
    SCK = 1;   //set B0 High
    DATAO = 0; //set B1 Low
    SCK = 0;   //set B0 Low
    SCK = 1;   //set B0 High
    DATAO = 1; //set B1 High
    SCK = 0;   //set B0 Low
    
}

char shtWrite(unsigned char Byte){
    unsigned char in, err = 0;
    DATAD = 1; //set B1 Output
    delay_us(5);
    for(in = 0b10000000; in > 0; in /= 2){
        SCK = 0;
        if(in & Byte) DATAO = 1; //send 1s
        else          DATAO = 0; //send 0s
        SCK = 1;
    }
    SCK = 0;
    DATAD = 0; //set B1 Input
    SCK = 1;
    err = DATA;
    SCK = 0;
    return(err);
}
unsigned char shtRead(unsigned char ack){
    unsigned char in, val = 0;
    DATAD = 0; //set B1 Input
    delay_us(5);
    for(in = 0b10000000; in > 0; in /= 2){
        SCK = 1;
        if (DATA) val = val | in; //save 1s
        SCK = 0;
    }
    DATAD = 1; //set B1 Output
    DATAO = !ack;
    SCK = 1;
    SCK = 0;
    return(val);    
}

int readTemp(){
    long int ttmp;
    unsigned char tlsb, tmsb;
    shtStart();
    shtWrite(0b00000011);
    while(DATA);
    tmsb = shtRead(1);
    tlsb = shtRead(1);
    ttmp = (((unsigned long) tmsb << 8) | (unsigned long) tlsb);
    return (-40 + 0.01 * ttmp) * 10;
}

int readHumi(){
    long int htmp;
    unsigned char hlsb, hmsb;
    shtStart();
    shtWrite(0b00000101);
    while(DATA);
    hmsb = shtRead(1);
    hlsb = shtRead(1);
    htmp = (((unsigned long) hmsb << 8) | (unsigned long) hlsb);
    return (-4 + (0.0405 * htmp) + (-2.8E-6 * (htmp * htmp))) * 10;
}

void main(void)
{
DDRA=(1<<DDA7) | (1<<DDA6) | (1<<DDA5) | (1<<DDA4) | (1<<DDA3) | (1<<DDA2) | (1<<DDA1) | (1<<DDA0);
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (1<<DDB0);
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (1<<PORTB1) | (0<<PORTB0);

lcd_init(16);
lcd_puts("Hello");

while (1)
      {
      humi = readHumi();
      temp = readTemp();
      lcd_clear();
      sprintf(buffer, "T= %d.%d" "\xdf" "C, ", temp / 10, temp % 10);
      lcd_puts(buffer);
      sprintf(buffer, "H= %d.%d", humi / 10, humi % 10);
      lcd_puts(buffer);
      delay_ms(500);
      }
}
bad_coder
  • 11,289
  • 20
  • 44
  • 72

2 Answers2

1

You always can add some more lcd_puts along the code to narrow the area, where program is halted.

When program is halted, often it means somewhere a dead loop happened. So, you have to pay close attention to all loops. For example in readHumi() there are basically only three loops:

  1. for(in = 0b10000000; in > 0; in /= 2) in shtWrite
  2. for(in = 0b10000000; in > 0; in /= 2) in shtRead

Those loops looks decent, they have an exit condition which always satisfied after 8 iteration.

But also you have a loop like this:

  1. while(DATA);

there is no exit condition, if sensor does not accept the command. Probably this halts your program.

The reason why sensor does not understand the command probably is in too small time between SCK rising and falling edges. According to the datasheet (page 6), the time between SCK falling and rising should be at least 100ns. If you're running 10+MHz, then the sequence

    SCK = 0;   //set B0 Low
    SCK = 1;   //set B0 High

can produce a pulse less than 100ns

Also, DDR for SCK pin is never initialized in your code.

AterLux
  • 4,566
  • 2
  • 10
  • 13
  • exactly in third loop (while) program is halted, i have added 1us delay after all port value changes and nothing changed (also 8MHz internal clock used), also i have initialized DDR for SCK with CodeWizard (1< – mohammad samiee Aug 12 '20 at 13:19
0

It solved with adding a sensor reset at the end of readHumi and readTemp functions:

shtStart();
shtWrite(0x1e);