This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52832 and SHT11 GPIO bit bang

Hello,

I'm trying to use this code https://github.com/kimyd/SHT1X_on_nrf51822 to communicate with an SHT11 sensor via GPIO pins.  I have a Saleae hooked up an can see the pulses and everything looks okay until the command ACK stage.  The data pin is never pulled low indicating the sensor did not receive the command.  I know the sensor is good as it works find with a RPi using python.

Is there something I need to configure on the GPIO data pin to allow it to be both input and output (I'm just going with S0S1 for the drive).

Any tips/pointers would be greatly appreciated.

Thanks.

Parents
  • Hi,

    Have you compared the logic analyzer trace with the known good sequence you get when using the RPi?

    The SHT11 need a pull up resistor on the DATA line, so you have to enable the internal pull-up resistor in the nRF (unless you have an external pull-up resistor, SHT11 spec states it should be about 10 kΩ). That said, this does not seem to be the problem if the data pin stays always high.

  • Hi Einar,

    Yes, I've compared them and the only difference I can see is that the data line never goes low after the command is entered.  I'm using a Parallax part that has a pull-up integrated (only 4.7K) and I've tried the code with both NOPULL and PULLUP on the input (no difference).  Attached is a scope trace that shows the data line not going low.

    So basically the above is clock on top and data on bottom.  There are 9 pulses with data high (reset), a transmit start sequence and then a code word (5 for humidity). the  ack pulse (9th pulse) does not result in the data line going low. so the rest of the data/clock pulses are basically garbage (all ones).

    The wire diagram shows:

    And this setup works great on a Pi + Python without any additional resistors (don't need the clock pull down).  So I think I'm basically clueless as to how the GPIO pins on the 52832 are supposed to work.  The clock pin is set to output all the time but the data pin flips between input and output.  Is there some special configuration I need to get this to work properly (i.e. is there an extra settle delay when flipping between input and output?).

    Any suggestions would be greatly appreciated.

  • Hi,

    It is a little bit difficult to read the clock and data lines together, but I think i see the same bit pattern you describe. Would it be possible to upload a plot with higher time resolution to make it easier to see the relative timing of the clock and data edges?

    Your description covers about the first half of the graph, and the rest you say is garbage. But the data line is pulled low at one point there, is done by the nRF (your bit ganging SW)?

  • Hi Einar,

    Here's another capture (maybe better) with some timing ticks

    Some more information:

    I'm using pins 11 & 12 (11 SHT_DATA, 12 SHT_SCK)

    here is the code snipped for writing the command (note TICK, SETTLE and DATA_IN are macros for:

    #define TICK nrf_delay_us(125)

    #define DATA_IN nrf_gpio_cfg(SHT_DATA, NRF_GPIO_PIN_PULLUP)

    #define SETTLE nrf_delay_us(2)

    static char s_write_byte(unsigned char value) { 
      
      unsigned char i,error=0;  
    
      // start trans
      nrf_gpio_cfg_output(SHT_DATA);   
      nrf_gpio_pin_clear(SHT_SCK);                   //Initial state
      nrf_gpio_pin_set(SHT_DATA); 
      TICK;
      nrf_gpio_pin_set(SHT_SCK);
      TICK;
      nrf_gpio_pin_clear(SHT_DATA);
      TICK;
      nrf_gpio_pin_clear(SHT_SCK);  
      TICK; 
      nrf_gpio_pin_set(SHT_SCK);
      TICK;
      nrf_gpio_pin_set(SHT_DATA);		   
      TICK;
      nrf_gpio_pin_clear(SHT_SCK); 
      TICK;
      
      nrf_gpio_pin_clear(SHT_DATA);
      TICK;
    
      //shift bit for masking
      for (i=0x80;i>0;i/=2) { 
        if (i&value) { 
          nrf_gpio_pin_set(SHT_DATA); 
        } else {
          nrf_gpio_pin_clear(SHT_DATA);
        }
    
        nrf_gpio_pin_set(SHT_SCK);   
        TICK;
        nrf_gpio_pin_clear(SHT_SCK);
        TICK;
      }
      
      // release data line
      nrf_gpio_pin_set(SHT_DATA);
      SETTLE;
      
      nrf_gpio_pin_set(SHT_SCK);                            //clk #9 for ack 
      TICK;
      DATA_IN;
      error = nrf_gpio_pin_read(SHT_DATA);	
      nrf_gpio_pin_clear(SHT_SCK);
        
      return error;                     //ack=1 in case of no acknowledge
    }
    

Reply
  • Hi Einar,

    Here's another capture (maybe better) with some timing ticks

    Some more information:

    I'm using pins 11 & 12 (11 SHT_DATA, 12 SHT_SCK)

    here is the code snipped for writing the command (note TICK, SETTLE and DATA_IN are macros for:

    #define TICK nrf_delay_us(125)

    #define DATA_IN nrf_gpio_cfg(SHT_DATA, NRF_GPIO_PIN_PULLUP)

    #define SETTLE nrf_delay_us(2)

    static char s_write_byte(unsigned char value) { 
      
      unsigned char i,error=0;  
    
      // start trans
      nrf_gpio_cfg_output(SHT_DATA);   
      nrf_gpio_pin_clear(SHT_SCK);                   //Initial state
      nrf_gpio_pin_set(SHT_DATA); 
      TICK;
      nrf_gpio_pin_set(SHT_SCK);
      TICK;
      nrf_gpio_pin_clear(SHT_DATA);
      TICK;
      nrf_gpio_pin_clear(SHT_SCK);  
      TICK; 
      nrf_gpio_pin_set(SHT_SCK);
      TICK;
      nrf_gpio_pin_set(SHT_DATA);		   
      TICK;
      nrf_gpio_pin_clear(SHT_SCK); 
      TICK;
      
      nrf_gpio_pin_clear(SHT_DATA);
      TICK;
    
      //shift bit for masking
      for (i=0x80;i>0;i/=2) { 
        if (i&value) { 
          nrf_gpio_pin_set(SHT_DATA); 
        } else {
          nrf_gpio_pin_clear(SHT_DATA);
        }
    
        nrf_gpio_pin_set(SHT_SCK);   
        TICK;
        nrf_gpio_pin_clear(SHT_SCK);
        TICK;
      }
      
      // release data line
      nrf_gpio_pin_set(SHT_DATA);
      SETTLE;
      
      nrf_gpio_pin_set(SHT_SCK);                            //clk #9 for ack 
      TICK;
      DATA_IN;
      error = nrf_gpio_pin_read(SHT_DATA);	
      nrf_gpio_pin_clear(SHT_SCK);
        
      return error;                     //ack=1 in case of no acknowledge
    }
    

Children
No Data
Related