Interfacing Sensirion SHT1x / SHT7x sensors

I have managed to interface the SDP5xx sensors, but they are ‘real’ i2c and the SHT75 uses a kind of bit-banging that looks like i2c but really isn’t.

I have added a pull-up resistor to the DATA line in line with the datasheet

In the attachment you can see the pattern on the scope, the blue is the clock (SCK) and the yellow the data. I was not able to pull-up the SCK a bit better and there is also no hint of a SCK pull-up in the datasheet. I’m using D2 and D3 b.t.w.

Any ideas appreciated!

Source is based on the example from the playground.

/*
 * Example code for SHT1x or SHT7x sensors demonstrating blocking calls
 * for temperature and humidity measurement in the setup routine and
 * non-blocking calls in the main loop.  The pin 13 LED is flashed as a
 * background task while temperature and humidity measurements are made.
 */

#include <Sensirion.h>

const uint8_t dataPin =  2;              // SHT serial data
const uint8_t sclkPin =  3;              // SHT serial clock
const uint8_t ledPin  = 13;              // Arduino built-in LED
const uint32_t TRHSTEP   = 500UL;       // Sensor query period
const uint32_t BLINKSTEP =  250UL;       // LED blink period

Sensirion sht = Sensirion(dataPin, sclkPin);

uint16_t rawData;
float temperature;
float humidity;
float dewpoint;

byte ledState = 0;
byte measActive = false;
byte measType = TEMP;

unsigned long trhMillis = 0;             // Time interval tracking
unsigned long blinkMillis = 0;

void setup() {
  SerialUSB.begin(9600);
  pinMode(ledPin, OUTPUT);
  delay(15);                             // Wait >= 11 ms before first cmd
// Demonstrate blocking calls
  sht.measTemp(&rawData);                // sht.meas(TEMP, &rawData, BLOCK)
  temperature = sht.calcTemp(rawData);
  sht.measHumi(&rawData);                // sht.meas(HUMI, &rawData, BLOCK)
  humidity = sht.calcHumi(rawData, temperature);
  dewpoint = sht.calcDewpoint(humidity, temperature);
  logData();
}

void loop() {
  unsigned long curMillis = millis();          // Get current time

  // Rapidly blink LED.  Blocking calls take too long to allow this.
  if (curMillis - blinkMillis >= BLINKSTEP) {  // Time to toggle the LED state?
    ledState ^= 1;
    digitalWrite(ledPin, ledState);
    blinkMillis = curMillis;
  }

  // Demonstrate non-blocking calls
  if (curMillis - trhMillis >= TRHSTEP) {      // Time for new measurements?
    measActive = true;
    measType = TEMP;
    sht.meas(TEMP, &rawData, NONBLOCK);        // Start temp measurement
    trhMillis = curMillis;
  }
  if (measActive && sht.measRdy()) {           // Note: no error checking
    if (measType == TEMP) {                    // Process temp or humi?
      measType = HUMI;
      temperature = sht.calcTemp(rawData);     // Convert raw sensor data
      sht.meas(HUMI, &rawData, NONBLOCK);      // Start humidity measurement
    } else {
      measActive = false;
      humidity = sht.calcHumi(rawData, temperature); // Convert raw sensor data
      dewpoint = sht.calcDewpoint(humidity, temperature);
      logData();
    }
  }
}

void logData() {
  SerialUSB.print("Temperature = ");   
  SerialUSB.print(temperature);
  SerialUSB.print(" C, Humidity = ");  
  SerialUSB.print(humidity);
  SerialUSB.print(" %, Dewpoint = ");  
  SerialUSB.print(dewpoint);
  SerialUSB.println(" C");
}

Result is always:
“Temperature = 615.25 C, Humidity = 0.10 %, Dewpoint = 116.91 C” which seems to be the default.

Solving it was easy, why do I always solve such a things only after posting a question while struggling for hours with the matter...

I thought the last resort would be to have a look at the library. I could not find anything called "Sensation.h" although it must be somewhere since the compiler isn't complaining.

I seemed to have installed SHT1x by Jonathan Oxer (2009). His example and library works very well with the M0.

Reading:
"Temperature: 23.0699996948C / 73.5799942017F. Humidity: 82.91%"

Seems to be reasonable, my calibrated Fluke 62 Max+ IR thermometer seems to agree with the temperature around the sensor next to my Macbook.

Look how precise the clock and data lines are at my scope (yellow is SCK):

Lessons learned:

  • always check your libraries first
  • the scope is a necessary tool to assess the state of such an issues
  • never give up :slight_smile: