[SOLVED] ATmega32 & SHT1x proto Board

Status
Not open for further replies.

north2012

Member level 3
Joined
Apr 1, 2013
Messages
63
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,288
Visit site
Activity points
1,813
Hi all,

I am working with system which consists of Atmega32 mcu and SHT1x Proto Board. I adapted code from examples for AVR but but with no success. I tested code on simulation and on hardware with same results (see attached picture).
My code is
Code:
// LCD module connections
sbit LCD_RS at PORTC2_bit;
sbit LCD_EN at PORTC3_bit;
sbit LCD_D4 at PORTC4_bit;
sbit LCD_D5 at PORTC5_bit;
sbit LCD_D6 at PORTC6_bit;
sbit LCD_D7 at PORTC7_bit;

sbit LCD_RS_Direction at DDC2_bit;
sbit LCD_EN_Direction at DDC3_bit;
sbit LCD_D4_Direction at DDC4_bit;
sbit LCD_D5_Direction at DDC5_bit;
sbit LCD_D6_Direction at DDC6_bit;
sbit LCD_D7_Direction at DDC7_bit;
// End LCD module connections

//SHT11 connections
sbit SDA at PORTA7_bit;                     // Serial data pin
sbit SCL at PORTA6_bit;                     // Serial clock pin

sbit SDA_Direction at DDA7_bit;        // Serial data direction pin
sbit SCL_Direction at DDA6_bit;        // Serial clock direction pin

// Constants for calculating temperature and humidity
const unsigned int C1 = 400;             // -4
const unsigned int C2 = 405;             // 0.0405  (405 * 10^-4)
const unsigned short C3 = 28;            // -2.8 * 10^-6  (28 * 10^-7)
const unsigned int D1 = 4000;            // -40
const unsigned short D2 = 1;             // 0.01

unsigned short i, j;
long int temp, k, SOt, SOrh, Ta_res, Rh_res;
char Ta[16] = "Ta = 000.00    ";
char Rh[16] = "Rh = 000.00    ";

void SHT_Reset() {
  SCL = 0;                               // SCL low
  SDA_Direction = 0;                     // define SDA as input
  for (i = 1; i <= 18; i++)              // repeat 18 times
    SCL = ~SCL;                          // invert SCL
}

void Transmission_Start() {
  SDA_Direction = 0;                     // define SDA as input
  SCL = 1;                               // SCL high
  Delay_us(1);                           // 1us delay
  SDA_Direction = 1;                     // define SDA as output
  SDA = 0;                               // SDA low
  Delay_us(1);                           // 1us delay
  SCL = 0;                               // SCL low
  Delay_us(1);                           // 1us delay
  SCL = 1;                               // SCL high
  Delay_us(1);                           // 1us delay
  SDA_Direction = 0;                     // define SDA as input
  Delay_us(1);                           // 1us delay
  SCL = 0;                               // SCL low
}

// MCU ACK
void MCU_ACK() {
  SDA_Direction = 1;     // define SDA as output
  SDA = 0;               // SDA low
  SCL = 1;               // SCL high
  Delay_us(1);           // 1us delay
  SCL = 0;               // SCL low
  Delay_us(1);           // 1us delay
  SDA_Direction = 0;     // define SDA as input
}

// This function returns temperature or humidity, depends on command
long int Measure(short num) {
  j = num;                           // j = command (0x03 or 0x05)
  SHT_Reset();                       // procedure for reseting SHT11
  Transmission_Start();              // procedure for starting transmission
  k = 0;                             // k = 0
  SDA_Direction = 1;                 // define SDA as output
  SCL = 0;                           // SCL low
  for(i = 1; i <= 8; i++) {          // repeat 8 times
    if (j.F7 == 1)                   // if bit 7 = 1
     SDA_Direction = 0;              // define SDA as input
    else {                           // else (if bit 7 = 0)
     SDA_Direction = 1;              // define SDA as output
     SDA = 0;                        // SDA low
   }
    Delay_us(1);                     // 1us delay
    SCL = 1;                         // SCL high
    Delay_us(1);                     // 1us delay
    SCL = 0;                         // SCL low
    j = j << 1;                         // move contents of j one place left
  }

  SDA_Direction = 0;                 // define SDA as input
  SCL = 1;                           // SCL high
  Delay_us(1);                       // 1us delay
  SCL = 0;                           // SCL low
  Delay_us(1);                       // 1us delay
  while (SDA == 1)                   // while SDA is high, do nothing
    Delay_us(1);                     // 1us delay

  for (i = 1; i <=16; i++) {         // repeat 16 times
    k = k << 1;                         // move contents of k one place left
    SCL = 1;                         // SCL high
    if (SDA == 1)                    // if SDA is high
    k = k | 0x0001;
    SCL = 0;
    if (i == 8)                      // if counter i = 8 then
      MCU_ACK();                     // MCU acknowledge
  }
  return k;                          // returns contents of k
}

void main()
{
  ADCSRA = 0x00;
  ACME_bit = 0;

  SCL_Direction = 1;                 // SCL is output
  LCD_Init();                        // init LCD on PORTB (for EasyPIC3 or lower)
  LCD_Cmd(_LCD_CURSOR_OFF);          // turns of LCD cursor

  LCD_Out(1, 7, "SHT11");            // write text on first row, seventh column
  LCD_Out(2, 2, "Made by MikroE");   // write text on second row, second column
  Delay_ms(2000);                    // delay 2 sec
  LCD_Cmd(_LCD_CLEAR);               // clear LCD

  Ta[11] = 178;                      // If you see greek alpha letter try typing 178 instead of 223
  Ta[12] = 'C';                      // 'C' character

  Rh[11] = '%';                      // '%' character

  while (1) {
     // Measuring temperature
    SOt = Measure(0x03);             // function for measuring (command 0x03 is for temperature)

     // Measuring humidity
    SOrh = Measure(0x05);            // function for measuring (command 0x05 is for humidity)
   
// Calculating temperature
// Ta_res = D1 + D2 * SOt
    if(SOt > D1)                     // if temperature is positive
      Ta_res = SOt * D2 - D1;        // calculate temperature
    else                             // else (if temperature is negative)
      Ta_res = D1 - SOt * D2;        // calculate temperature

// Calculating humidity
// Rh_res = C1 + C2 * SOrh + C3 * SOrh^2
    temp = SOrh * SOrh * C3 / 100000;             // calculate humidity
    Rh_res = SOrh * C2 / 100 - temp - C1;         // calculate humidity

// Preparing temperature for LCD
    Ta[5] = Ta_res / 10000 + 48;                  // example: Ta[5] = 12345 / 10000 = 1, 1 + 48 = '1' - ASCII
    Ta[6] = Ta_res % 10000 / 1000 + 48;           // example: Ta[6] = 12345 % 10000 = 2345, Ta[6] = 2345 / 1000 = 2, 2 + 48 = '2' - ASCII
    Ta[7] = Ta_res % 1000 / 100 + 48;             // example: Ta[7] = 12345 % 1000 = 345, Ta[7] = 345 / 100 = 3, 3 + 48 = '3' - ASCII
    Ta[9] = Ta_res % 100 / 10 + 48;               // example: Ta[9] = 12345 % 100 = 45, Ta[9] = 45 / 10 = 4, 4 + 48 = '4' - ASCII
    Ta[10] = Ta_res % 10 + 48;                    // example: Ta[10] = 12345 % 10 = 5, 5 + 48 = '5' - ASCII

// Preparing humidity for LCD
    Rh[5] = Rh_res / 10000 + 48;                  // example: Rh[5] = 12345 / 10000 = 1, 1 + 48 = '1' - ASCII
    Rh[6] = Rh_res % 10000 / 1000 + 48;           // example: Rh[6] = 12345 % 10000 = 2345, Rh[6] = 2345 / 1000 = 2, 2 + 48 = '2' - ASCII
    Rh[7] = Rh_res % 1000 / 100 + 48;             // example: Rh[7] = 12345 % 1000 = 345, Rh[7] = 345 / 100 = 3, 3 + 48 = '3' - ASCII
    Rh[9] = Rh_res % 100 / 10 + 48;               // example: Rh[9] = 12345 % 100 = 45, Rh[9] = 45 / 10 = 4, 4 + 48 = '4' - ASCII
    Rh[10] = Rh_res % 10 + 48;                    // example: Rh[10] = 12345 % 10 = 5, 5 + 48 = '5' - ASCII

// delete unnecessary digits (zeros)
    if (Ta[5] == '0')                             // if Ta[5] = '0' then
      Ta[5] = ' ';                                // insert blank character to Ta[5]
    if (Ta[5] == ' ' && Ta[6] == '0')             // if Ta[5] is blank and Ta[6] = '0' then
      Ta[6] = ' ';                                // insert blank character to Ta[6]

    if (Rh[5] == '0')                             // if Ta[5] = '0' then
      Rh[5] = ' ';                                // insert blank character to Ta[5]
    if (Rh[5] == ' ' && Rh[6] == '0')             // if Ta[5] is blank and Ta[6] = '0' then
      Rh[6] = ' ';                                // insert blank character to Ta[6]

// Display temperature on LCD
    Lcd_Out(1, 1, Ta);                            // display temperature on first row, i column

// Display humidity on LCD
    Lcd_Out(2, 1, Rh);                            // display humidity on second row, i column

    Delay_ms(700);                                // delay 700ms
  }
}



Does anyone can see where is the problem?
Thanks in advance.
 

I bought SHt1x Proto Board from mikroElektronika. They provided an example for PIC mcu written in microC PRO for PIC. I made revision of that code in microC PRO for AVR (that is code above) but it does not work. That means that on LCD display I received results just as shown on attached picture. When I attached oscilloscope there are impulses on both lines- SDA and SCK. I made both, simulation and test on real hardware but with same result. It is very difficult to find some example in c for atmega+sht11 to compare codes. I found one source code written in BASCOM for AVR, I loaded hex and it works perfectly in both- simulation and on hardware, so I believe that there are no hardware problems in my system.
 

Re: ATmega32 &amp;amp; SHT1x proto Board

i dont use microc.. so i can't help with its library functions...
but i can help you with avr studio...

- - - Updated - - -

it seems that your sht1x device communicate via i2c protocol...

find proper sequence to operate it... (means data frame and command frames)
they should be given in its datasheet...

also compare your code with original one... better post original one here..

- - - Updated - - -

ok i found something in above posted program... not sure if microc support this kind of syntex or not... but let me tell you...

basically sfr's of avr are not bit addressable so you can't set or clear individual bit as you do in pic or 8051.
you have to change whole 8 bit value of it..

here you are toggling only one bit (that is "sbit SCL at PORTA6_bit;"), so it is technically wrong..
in avr studio i can't write like this... (but don't know if microc allows it)

GOOGLE "AVR BIT MANIPULATION"
and learn how you can toggle individual pins in avr..
 

Re: ATmega32 &amp;amp; SHT1x proto Board

As the interface on the SHT11 is not true I2C I had to bit bang it. For that reason I used "sbit SCL at PORTA6_bit;"... As I said, program is compiled successfully.
 

Here is the working code for ATmega32 with SHT1x.
Code:
// LCD module connections
sbit LCD_RS at PORTC2_bit;
sbit LCD_EN at PORTC3_bit;
sbit LCD_D4 at PORTC4_bit;
sbit LCD_D5 at PORTC5_bit;
sbit LCD_D6 at PORTC6_bit;
sbit LCD_D7 at PORTC7_bit;

sbit LCD_RS_Direction at DDC2_bit;
sbit LCD_EN_Direction at DDC3_bit;
sbit LCD_D4_Direction at DDC4_bit;
sbit LCD_D5_Direction at DDC5_bit;
sbit LCD_D6_Direction at DDC6_bit;
sbit LCD_D7_Direction at DDC7_bit;
// End LCD module connections

//SHT11 connections
sbit SDA at PORTA7_bit;                     // Serial data pin
[B]sbit SDA_R at PINA7_bit;                     // Serial data pin[/B]

sbit SCL at PORTA6_bit;                     // Serial clock pin

sbit SDA_Direction at DDA7_bit;        // Serial data direction pin
sbit SCL_Direction at DDA6_bit;        // Serial clock direction pin

// Constants for calculating temperature and humidity
const unsigned int C1 = 400;             // -4
const unsigned int C2 = 405;             // 0.0405  (405 * 10^-4)
const unsigned short C3 = 28;            // -2.8 * 10^-6  (28 * 10^-7)
const unsigned int D1 = 4000;            // -40
const unsigned short D2 = 1;             // 0.01

unsigned short i, j;
long int temp, k, SOt, SOrh, Ta_res, Rh_res;
char Ta[16] = "Ta = 000.00    ";
char Rh[16] = "Rh = 000.00    ";

void SHT_Reset() {
  SCL = 0;                               // SCL low
  SDA_Direction = 0;                     // define SDA as input
  for (i = 1; i <= 18; i++)              // repeat 18 times
    SCL = ~SCL;                          // invert SCL
}

void Transmission_Start() {
  SDA_Direction = 0;                     // define SDA as input
  SCL = 1;                               // SCL high
  Delay_us(1);                           // 1us delay
  SDA_Direction = 1;                     // define SDA as output
  SDA = 0;                               // SDA low
  Delay_us(1);                           // 1us delay
  SCL = 0;                               // SCL low
  Delay_us(1);                           // 1us delay
  SCL = 1;                               // SCL high
  Delay_us(1);                           // 1us delay
  SDA_Direction = 0;                     // define SDA as input
  Delay_us(1);                           // 1us delay
  SCL = 0;                               // SCL low
}

// MCU ACK
void MCU_ACK() {
  SDA_Direction = 1;     // define SDA as output
  SDA = 0;               // SDA low
  SCL = 1;               // SCL high
  Delay_us(1);           // 1us delay
  SCL = 0;               // SCL low
  Delay_us(1);           // 1us delay
  SDA_Direction = 0;     // define SDA as input
}

// This function returns temperature or humidity, depends on command
long int Measure(short num) {
  j = num;                           // j = command (0x03 or 0x05)
  SHT_Reset();                       // procedure for reseting SHT11
  Transmission_Start();              // procedure for starting transmission
  k = 0;                             // k = 0
  SDA_Direction = 1;                 // define SDA as output
  SCL = 0;                           // SCL low
  for(i = 1; i <= 8; i++) {          // repeat 8 times
    if (j.F7 == 1)                   // if bit 7 = 1
     SDA_Direction = 0;              // define SDA as input
    else {                           // else (if bit 7 = 0)
     SDA_Direction = 1;              // define SDA as output
     SDA = 0;                        // SDA low
   }
    Delay_us(1);                     // 1us delay
    SCL = 1;                         // SCL high
    Delay_us(1);                     // 1us delay
    SCL = 0;                         // SCL low
    j = j << 1;                         // move contents of j one place left
  }

  SDA_Direction = 0;                 // define SDA as input
  SCL = 1;                           // SCL high
  Delay_us(1);                       // 1us delay
  SCL = 0;                           // SCL low
  Delay_us(1);                       // 1us delay
 [B] while (SDA_R == 1)                   // while SDA is high, do nothing[/B]
    Delay_us(1);                     // 1us delay

  for (i = 1; i <=16; i++) {         // repeat 16 times
    k = k << 1;                         // move contents of k one place left
    SCL = 1;                         // SCL high
  [B]  if (SDA_R == 1)                    // if SDA is high[/B]
    k = k | 0x0001;
    SCL = 0;
    if (i == 8)                      // if counter i = 8 then
      MCU_ACK();                     // MCU acknowledge
  }
  return k;                          // returns contents of k
}

void main()
{
  ADCSRA = 0x00;
  ACME_bit = 0;

  SCL_Direction = 1;                 // SCL is output
  LCD_Init();                        // init LCD on PORTB (for EasyPIC3 or lower)
  LCD_Cmd(_LCD_CURSOR_OFF);          // turns of LCD cursor

  LCD_Out(1, 7, "SHT11");            // write text on first row, seventh column
  LCD_Out(2, 2, "Made by MikroE");   // write text on second row, second column
  Delay_ms(2000);                    // delay 2 sec
  LCD_Cmd(_LCD_CLEAR);               // clear LCD

  Ta[11] = 178;                      // If you see greek alpha letter try typing 178 instead of 223
  Ta[12] = 'C';                      // 'C' character

  Rh[11] = '%';                      // '%' character

  while (1) {
     // Measuring temperature
    SOt = Measure(0x03);             // function for measuring (command 0x03 is for temperature)

     // Measuring humidity
    SOrh = Measure(0x05);            // function for measuring (command 0x05 is for humidity)

// Calculating temperature
// Ta_res = D1 + D2 * SOt
    if(SOt > D1)                     // if temperature is positive
      Ta_res = SOt * D2 - D1;        // calculate temperature
    else                             // else (if temperature is negative)
      Ta_res = D1 - SOt * D2;        // calculate temperature

// Calculating humidity
// Rh_res = C1 + C2 * SOrh + C3 * SOrh^2
    temp = SOrh * SOrh * C3 / 100000;             // calculate humidity
    Rh_res = SOrh * C2 / 100 - temp - C1;         // calculate humidity

// Preparing temperature for LCD
    Ta[5] = Ta_res / 10000 + 48;                  // example: Ta[5] = 12345 / 10000 = 1, 1 + 48 = '1' - ASCII
    Ta[6] = Ta_res % 10000 / 1000 + 48;           // example: Ta[6] = 12345 % 10000 = 2345, Ta[6] = 2345 / 1000 = 2, 2 + 48 = '2' - ASCII
    Ta[7] = Ta_res % 1000 / 100 + 48;             // example: Ta[7] = 12345 % 1000 = 345, Ta[7] = 345 / 100 = 3, 3 + 48 = '3' - ASCII
    Ta[9] = Ta_res % 100 / 10 + 48;               // example: Ta[9] = 12345 % 100 = 45, Ta[9] = 45 / 10 = 4, 4 + 48 = '4' - ASCII
    Ta[10] = Ta_res % 10 + 48;                    // example: Ta[10] = 12345 % 10 = 5, 5 + 48 = '5' - ASCII

// Preparing humidity for LCD
    Rh[5] = Rh_res / 10000 + 48;                  // example: Rh[5] = 12345 / 10000 = 1, 1 + 48 = '1' - ASCII
    Rh[6] = Rh_res % 10000 / 1000 + 48;           // example: Rh[6] = 12345 % 10000 = 2345, Rh[6] = 2345 / 1000 = 2, 2 + 48 = '2' - ASCII
    Rh[7] = Rh_res % 1000 / 100 + 48;             // example: Rh[7] = 12345 % 1000 = 345, Rh[7] = 345 / 100 = 3, 3 + 48 = '3' - ASCII
    Rh[9] = Rh_res % 100 / 10 + 48;               // example: Rh[9] = 12345 % 100 = 45, Rh[9] = 45 / 10 = 4, 4 + 48 = '4' - ASCII
    Rh[10] = Rh_res % 10 + 48;                    // example: Rh[10] = 12345 % 10 = 5, 5 + 48 = '5' - ASCII

// delete unnecessary digits (zeros)
    if (Ta[5] == '0')                             // if Ta[5] = '0' then
      Ta[5] = ' ';                                // insert blank character to Ta[5]
    if (Ta[5] == ' ' && Ta[6] == '0')             // if Ta[5] is blank and Ta[6] = '0' then
      Ta[6] = ' ';                                // insert blank character to Ta[6]

    if (Rh[5] == '0')                             // if Ta[5] = '0' then
      Rh[5] = ' ';                                // insert blank character to Ta[5]
    if (Rh[5] == ' ' && Rh[6] == '0')             // if Ta[5] is blank and Ta[6] = '0' then
      Rh[6] = ' ';                                // insert blank character to Ta[6]

// Display temperature on LCD
    Lcd_Out(1, 1, Ta);                            // display temperature on first row, i column

// Display humidity on LCD
    Lcd_Out(2, 1, Rh);                            // display humidity on second row, i column

    Delay_ms(1000);                                // delay 700ms
  }
}

Regards.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…