element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • About Us
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
Code Exchange
  • Technologies
  • More
Code Exchange
Forum Interfacing of SHT11 with PIC24f16KA102
  • Blog
  • Forum
  • Documents
  • Events
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join Code Exchange to participate - click to join for free!
Actions
  • Share
  • More
  • Cancel
Forum Thread Details
  • State Suggested Answer
  • Replies 13 replies
  • Answers 2 answers
  • Subscribers 48 subscribers
  • Views 2409 views
  • Users 0 members are here
Related

Interfacing of SHT11 with PIC24f16KA102

Former Member
Former Member over 11 years ago

Hi,

I have written the c code for I2C for interfacing the SHT11(temp sensor) and PIC24F16KA102. but i m not getting the acknowledge from the SHT11 when i m writing through pic.  i m pasting my code here. plz let me know where i m doing wrong if possible. thanks

 

#include <stdint.h>

#include <xc.h>

#include "main.h"

 

#include <p24Fxxxx.h>

// ICD Pin Placement Select (EMUC/EMUD share PGC3/PGD3)

//_FICD(ICS_PGx1)

/*

* File:   main.c

* Author: jalpa

*

* Created on 7 February, 2014, 10:11 AM

*/

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

//Include section

 

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

#include "p24F16KA102.h"

 

#include "spi.h"

#include "i2c.h"

#include <timer.h>

 

 

 

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

//Define section

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

// for input use  PORTBbits.RB7  notation and for output pin use LATBbits.LATB2.

//#define CE LATBbits.LATB2    //pin-6  // CE output pin, PORTB bit 2

 

 

//#define SDA_pin LATBbits.LATB9    //pin-22// Clock output pin, PORTB bit 11

//#define SCL_pin LATBbits.LATB8

//

//#define SDA_dir TRISBbits.TRISB9

//#define SCL_dir TRISBbits.TRISB8

 

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

 

//Declaration of variable

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

unsigned char msb;

unsigned char lsb;

unsigned char status;

 

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

//Declaration of functions

 

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

void i2c_init();

void reset_i2c_bus();

void delay_us(unsigned short us);

void i2c_start();

void i2c_restart();

char i2c_send_byte(int data);

char i2c_read_byte();

 

 

//#define SCK_dir TRISBbits.TRISB8

 

 

 

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

//Main function

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

 

void main(void)

{

 

 

 

   // AD1PCFGbits.PCFG0=1;

   // AD1PCFGbits.PCFG1=1;

 

   AD1PCFG =0XFF;

   //SCK_dir=0;

  

   i2c_init();

   i2c_start();

   delay_us(2000);

   status = i2c_send_byte(0x03);

   delay_us(10000);

   msb= i2c_read_byte();

   lsb= i2c_read_byte();

   reset_i2c_bus();

 

 

 

   

 

}

 

 

 

 

 

void i2c_init()

{

    int temp;

    I2C1BRG = 157;

    I2C1CONbits.I2CEN = 0;

    I2C1CONbits.DISSLW = 1;

    I2C1CONbits.I2CEN= 1;

    temp = I2C1RCV;

    reset_i2c_bus();

 

}

 

void reset_i2c_bus()  // reset is used before and after a packet i sent through the bus (release both sda and scl)

{

 

    int x=0;

 

    I2C1CONbits.PEN= 1;

 

    while(I2C1CONbits.PEN)

    {

 

        delay_us(1);

        x++;

        if(x>20) break;

 

    }

 

    I2C1CONbits.RCEN=0;

    IFS1bits.MI2C1IF=0;

    I2C1STATbits.IWCOL=0;

    I2C1STATbits.BCL=0;

 

    delay_us(10);

   

}

 

void i2c_start(void)

{

   int x = 0;

   I2C1CONbits.ACKDT = 0;    //Reset any previous Ack

   delay_us(10);

   I2C1CONbits.SEN = 1;    //Initiate Start condition

   Nop();

 

   //the hardware will automatically clear Start Bit

   //wait for automatic clear before proceding

   while (I2C1CONbits.SEN)

   {

      delay_us(1);

      x++;

      if (x > 20)

      break;

   }

    delay_us(2);

}

 

 

void i2c_restart(void)

{

   int x = 0;

 

   I2C1CONbits.RSEN = 1;    //Initiate restart condition

   Nop();

 

   //the hardware will automatically clear restart bit

   //wait for automatic clear before proceding

   while (I2C1CONbits.RSEN)

   {

      delay_us(1);

      x++;

      if (x > 20)    break;

   }

 

   delay_us(2);

}

 

 

char i2c_send_byte(int data)

{

   int i;

 

   while (I2C1STATbits.TBF) { }

   IFS1bits.MI2C1IF = 0; // Clear Interrupt

   I2C1TRN = data; // load the outgoing data byte

 

   // wait for transmission

   for (i=0; i<500; i++)

   {

      if (!I2C1STATbits.TRSTAT) break;

      delay_us(1);

 

      }

      if (i == 500) {

      return(1);

   }

 

   // Check for NO_ACK from slave, abort if not found

   if (I2C1STATbits.ACKSTAT == 1)

   {

      reset_i2c_bus();   //error

      return(1);

   }

 

   delay_us(2);

   return(0);

}

 

char i2c_read_byte(void)    //does not reset bus!!!

{

   int i = 0;

   char data = 0;

 

   //set I2C module to receive

   I2C1CONbits.RCEN = 1;

 

   //if no response, break

   while (!I2C1STATbits.RBF)

   {

      i++;

      if (i > 2000) break;

   }

 

   //get data from I2CRCV register

   data = I2C1RCV;

 

   //set ACK to high

   I2C1CONbits.ACKEN = 1;

 

   //wait before exiting

   delay_us(10);

 

   //return data

   return data;

}

 

 

 

void delay_us(unsigned short us)

{

  unsigned short i;

 

  // TIMER1 Period = PR1 x 2 x Tosc x Prescale second

  // TIMER1 Period = 145 x 2 x 1/32000000 x 1 = 9 us // practically coming 12us

 

  PR1=145;                      // Maximum Counter

  T1CON=0x0000;            // TIMER1 Off, Prescale 1:1 using the internal clock

  for (i=0; i < us;i++) {

    TMR1=0;                     // Reset TIMER1 Counter

    IFS0bits.T1IF=0;            // Clear TIMER1 Interrupt Flag

    T1CONbits.TON=1;            // Turn On TIMER1

    while(IFS0bits.T1IF != 1);  // Wait until TMR1 > PR1 (Overflow)

    T1CONbits.TON=0;            // Turn Off TIMER1

  }

 

}

  • Sign in to reply
  • Cancel

Top Replies

  • Former Member
    Former Member over 11 years ago in reply to gihu +1
    Hi, thanks Actually i checked the the clock configuration earlier through as u said by LED blinking Code. and for FRCPLL and keeping CLKDIV=0x0000; i m getting Fcy=16MHz. I have checked it by putting different…
  • Former Member
    0 Former Member over 11 years ago in reply to gihu

    hi,
    i came to know from the SHT11 data sheet is ...

    The sensor

    cannot be addressed by I2C protocol; however, the sensor

    can be connected to an I2C bus without interference with

    other devices connected to the bus. The controller must

    switch between the protocols.

     

    i m getting error in the following code. I have taken this code from the one of the post of mikroelectronika (viewtopic.php?f=13&t=13803&start=15) and I have modified only the pins used for SDA and SCL and commented the code for LCD. But i m getting error when i interface PIC24F16KA102 with SHT11 click board. i m pasting my code here. plz help in debugging this problem. i am debugging the following code using MPLABX IDE, C16 compiler. i m getting error in main programme at the following point.



    if(error!=0)
    {
    s_connectionreset(); //in case of an error: connection reset
    }


    /**************************************************************************************************
    * Project name:
    SHT11_driver
    * Copyright:
    (c) Mikroelektronika, 2011.
    * Revision History:
    20111122:
    - initial release (DA and JK);
    * Description:
    This code contains functions for communication with SHT1x temperature and humidity sensor.
    http://www.sensirion.com/en/pdf/product ... -SHT1x.pdf

    * Test configuration:
    SW: mikroC PRO for PIC
    http://www.mikroe.com/eng/products/view ... o-for-pic/
    **************************************************************************************************/

    /*******************************************************************************************************************/
    #include "p24F16KA102.h"
    #include <timer.h>
    #include <math.h>
    typedef union
    { unsigned int i;
    float f;
    } value;


    //------------------------------------------------------------------------------
    // modul-var
    //------------------------------------------------------------------------------
    //enum {TEMP,HUMI};

    //#include "initlcd.h"

    #define TEMP 0
    #define HUMI 1

    #define PORT_COND TRISBbits.TRISB9 //data port condition: input/output
    #define DATA PORTBbits.RB9 //SHT11 DATA pin
    #define SCK PORTBbits.RB8 //STH11 SCK pin
    #define noACK 0
    #define ACK 1
    //adr command r/w
    #define STATUS_REG_W 0x06 //000 0011 0
    #define STATUS_REG_R 0x07 //000 0011 1
    #define MEASURE_TEMP 0x03 //000 0001 1
    #define MEASURE_HUMI 0x05 //000 0010 1
    #define RESET 0x1e //000 1111 0

    #define MEMORY_ADDRESS 0xA0


    // char* Out_temp()
    // {
    // char str[]="Temp:" absolute MEMORY_ADDRESS;
    // return str;
    // }
    //
    // char* Out_humi()
    // {
    // char str[]="Humi:" absolute MEMORY_ADDRESS;
    // return str;
    // }


    //------------------------------------------------------------------------------
    char s_write_byte(unsigned char value)
    //------------------------------------------------------------------------------
    // writes a byte on the Sensibus and checks the acknowledge
    {
    unsigned char i,error=0;

    PORT_COND = 0; //SHT11 WRITE


    for (i=0x80;i>0;i/=2) //shift bit for masking
    { if (i & value) DATA=1; //masking value with i , write to SENSI-BUS
    else DATA=0;
    SCK=1; //clk for SENSI-BUS
    delay_us(5); //pulswith approx. 5 us
    SCK=0;
    }

    DATA=1; //release DATA-line

    PORT_COND = 1; //SHT11 READ


    delay_us(2);

    SCK=1; //clk #9 for ack
    error=DATA; //check ack (DATA will be pulled down by SHT11)
    SCK=0;
    return error; //error=1 in case of no acknowledge
    }


    //----------------------------------------------------------------------------------
    char s_read_byte(unsigned char ack)
    //----------------------------------------------------------------------------------
    // reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
    {
    unsigned char i,val=0;

    PORT_COND = 1; //SHT11 READ


    DATA=1; //release DATA-line

    for (i=0x80;i>0;i/=2) //shift bit for masking
    { SCK=1; //clk for SENSI-BUS

    if (DATA) val=(val | i); //read bit
    SCK=0;
    }

    DATA=!ack; //in case of "ack==1" pull down DATA-Line
    SCK=1; //clk #9 for ack
    delay_us(5); //pulswith approx. 5 us
    SCK=0;
    DATA=1; //release DATA-line
    return val;
    }


    //----------------------------------------------------------------------------------
    void s_transstart(void)
    //----------------------------------------------------------------------------------
    // generates a transmission start
    // _____ ________
    // DATA: |_______|
    // ___ ___
    // SCK : ___| |___| |______
    {
    PORT_COND = 0; //SHT11 WRITE

    DATA=1; SCK=0; //Initial state
    delay_us(2);
    SCK=1;
    delay_us(2);
    DATA=0;
    delay_us(2);
    SCK=0;
    delay_us(5);
    SCK=1;
    delay_us(2);
    DATA=1;
    delay_us(2);
    SCK=0;
    }


    //----------------------------------------------------------------------------------
    void s_connectionreset(void)
    //----------------------------------------------------------------------------------
    // communication reset: DATA-line=1 and at least 9 SCK cycles followed by transstart
    // _____________________________________________________ ________
    // DATA: |_______|
    // _ _ _ _ _ _ _ _ _ ___ ___
    // SCK : __| |__| |__| |__| |__| |__| |__| |__| |__| |______| |___| |______
    {
    unsigned char i;

    PORT_COND = 0; //SHT11 WRITE


    DATA=1; SCK=0; //Initial state

    for(i=0;i<9;i++) //9 SCK cycles
    { SCK=1;
    SCK=0;
    }

    s_transstart(); //transmission start
    }


    //----------------------------------------------------------------------------------
    char s_softreset(void)
    //----------------------------------------------------------------------------------
    // resets the sensor by a softreset
    {
    unsigned char error=0;

    s_connectionreset(); //reset communication

    error+=s_write_byte(RESET); //send RESET-command to sensor
    return error; //error=1 in case of no response form the sensor
    }


    //----------------------------------------------------------------------------------
    char s_read_statusreg(unsigned char *p_value, unsigned char *p_checksum)
    //----------------------------------------------------------------------------------
    // reads the status register with checksum (8-bit)
    {
    unsigned char error=0;

    s_transstart(); //transmission start

    error=s_write_byte(STATUS_REG_R); //send command to sensor

    *p_value=s_read_byte(ACK); //read status register (8-bit)
    *p_checksum=s_read_byte(noACK); //read checksum (8-bit)

    return error; //error=1 in case of no response form the sensor
    }


    //----------------------------------------------------------------------------------
    char s_write_statusreg(unsigned char *p_value)
    //----------------------------------------------------------------------------------
    // writes the status register with checksum (8-bit)
    {
    unsigned char error=0;

    s_transstart(); //transmission start

    error+=s_write_byte(STATUS_REG_W);//send command to sensor
    error+=s_write_byte(*p_value); //send value of status register

    return error; //error>=1 in case of no response form the sensor
    }


    //----------------------------------------------------------------------------------
    char s_measure(unsigned char *p_value, unsigned char *p_checksum, unsigned char mode)
    //----------------------------------------------------------------------------------
    // makes a measurement (humidity/temperature) with checksum
    {
    unsigned error=0;
    unsigned int i;

    s_transstart(); //transmission start

    switch(mode)
    { //send command to sensor
    case TEMP : error+=s_write_byte(MEASURE_TEMP); break; //temp
    case HUMI : error+=s_write_byte(MEASURE_HUMI); break; //humidity
    default : break;
    }

    PORT_COND = 1; //SHT11 READ


    for (i=0;i<65535;i++) if(DATA==0) break; //wait until sensor has finished the measurement

    if(DATA) error+=1; // or timeout (~2 sec.) is reached

    *(p_value+1)=s_read_byte(ACK); //read the second byte (LSB)
    *(p_value) =s_read_byte(ACK); //read the first byte (MSB)



    *p_checksum =s_read_byte(noACK); //read checksum

    return error;
    }

    /*
    //----------------------------------------------------------------------------------
    void init_uart()
    //----------------------------------------------------------------------------------
    // Initializes the UART so the final data can be sent away, e.g. to a PC
    //9600 bps @ 11.059 MHz
    { SCON = 0x52;
    TMOD = 0x20;
    TCON = 0x69;
    TH1 = 0xfd;
    }
    */

    //----------------------------------------------------------------------------------------
    void calc_sth11(float *p_humidity ,float *p_temperature)
    //----------------------------------------------------------------------------------------
    // calculates temperature [C] and humidity [%RH]
    // input : humi [Ticks] (12 bit)
    // temp [Ticks] (14 bit)
    // output: humi [%RH]
    // temp [C]
    { const float C1=-4.0; // for 12 Bit
    const float C2= 0.0405; // for 12 Bit
    const float C3=-0.0000028; // for 12 Bit
    const float T1=0.01; // for 14 Bit @ 5V
    const float T2=0.00008; // for 14 Bit @ 5V
    float rh=*p_humidity; // rh: Humidity [Ticks] 12 Bit
    float t=*p_temperature; // t: Temperature [Ticks] 14 Bit
    float rh_lin; // rh_lin: Humidity linear
    float rh_true; // rh_true: Temperature compensated humidity
    float t_C; // t_C : Temperature [C]

    t_C=t*0.01-40; //calc. Temperature from ticks to [C]

    rh_lin=C3*rh*rh + C2*rh + C1; //calc. Humidity from ticks to [%RH]

    rh_true=(t_C-25)*(T1+T2*rh)+rh_lin; //calc. Temperature compensated humidity [%RH]

    if(rh_true>100)rh_true=100; //cut if the value is outside of

    if(rh_true<0.1)rh_true=0.1; //the physical possible range

    *p_temperature=t_C; //return temperature [C]
    *p_humidity=rh_true; //return humidity[%RH]
    }


    //--------------------------------------------------------------------
    float calc_dewpoint(float h,float t)
    //--------------------------------------------------------------------
    // calculates dew point
    // input: humidity [%RH], temperature [C]
    // output: dew point [C]
    { float k,dew_point ;

    k = (log10(h)-2)/0.4343 + (17.62*t)/(243.12+t);

    dew_point = 243.12*k/(17.62-k);

    return dew_point;
    }

    //----------------------------------------------------------------------------------
    void main()
    //----------------------------------------------------------------------------------
    // sample program that shows how to use SHT11 functions
    // 1. connection reset
    // 2. measure humidity [ticks](12 bit) and temperature [ticks](14 bit)
    // 3. calculate humidity [%RH] and temperature [C]
    // 4. calculate dew point [C]
    // 5. print temperature, humidity, dew point


    //AD1PCFGbits.PCFG0=1;
    //AD1PCFGbits.PCFG1=1;
    {
    AD1PCFG =0XFFFF;
    //AD1PCFGbits.PCFG10=1;



    value humi_val,temp_val;

    float dew_point;
    unsigned char error,checksum;
    //unsigned int i;

    char temp[13];
    char humi[13];


    // Initlcd(); //Initialize LCD

    s_connectionreset();
    delay_ms(20);

    while(1)
    {

    error=0;

    error+=s_measure((unsigned char*) &humi_val.i,&checksum,HUMI);
    //measure humidity

    error+=s_measure((unsigned char*) &temp_val.i,&checksum,TEMP);
    //measure temperature

    if(error!=0)
    {
    s_connectionreset(); //in case of an error: connection reset
    }
    else
    {
    humi_val.f=(float)humi_val.i; //converts integer to float
    temp_val.f=(float)temp_val.i; //converts integer to float

    calc_sth11(&humi_val.f,&temp_val.f); //calculate humidity, temperature

    dew_point=calc_dewpoint(humi_val.f,temp_val.f); //calculate dew point

    //send final data to serial interface (UART)

    // Lcd8_Out(1,1,Out_temp());
    // Lcd8_Out(2,1,Out_humi());
    //
    // FloatToStr(temp_val.f, temp);
    // Lcd8_Out(1,6,temp);
    //
    // FloatToStr(humi_val.f, humi);
    // Lcd8_Out(2,6,humi);


    }
    //----------wait approx. 0.8s to avoid heating up SHTxx----------------------
    //-----------------------------------------------------------------------------------
    delay_ms(1000);

    }

    }


    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • gihu
    0 gihu over 11 years ago in reply to Former Member

    Sorry jalpa I did not either realize that the sensor is not I2C... image

     

    Check this:

    - Put a break point in line:

          error=DATA; //check ack (DATA will be pulled down by SHT11)

    Check Data value in the physical Line SDA,

         if 'low', sensor is responding, so put a break point in line

                   if(DATA) error+=1; // or timeout (~2 sec.) is reached

                   Check what was the reason of exit the previous loop, i gets 65536 or D==0, if i gets 65536 the sensor does not end the measurement (remember using Pull-up resistor)

     

         if 'high', sensor is not responding:

                   - Can you debug your code step by step? (in MPLAB I recommend you using F7 step into, because it is the shortest step). If yes run again the code from the begining, and when start the transmission of the command:

     

    for (i=0x80;i>0;i/=2) //shift bit for masking

    { if (i & value) DATA=1; //masking value with i , write to SENSI-BUS

    else DATA=0;

    SCK=1; //clk for SENSI-BUS

    delay_us(5); //pulswith approx. 5 us

    SCK=0;

    }


    check every time that the status of both lines SCK and SDA are what you are expecting. When the command is sent keep on stepping and check the status of SDA when you get to line

    error=DATA; //check ack (DATA will be pulled down by SHT11),

    If now SDA is low means that sensor works, so maybe it is timing problem,

     

    Check this, and let us know what you get.

     

    Sorry for not giving a more concise answer but without the board and the sensor is difficult to try the code...image

     

    Regards.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
  • Former Member
    0 Former Member over 10 years ago in reply to Former Member

    hi..

    i am using the pic24f16ka102 and temperature sensore tmp75 i got the same problem that i got the acknowledge for address but did'nt get the acknowledgement for data

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • Verify Answer
    • Cancel
<
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2025 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube