I2c with SHT25 TempHum sensor

Have just switched from bit banging an SHT7x sensor to an SHT25 sensor. After total failure to get readings by bitbanging the SHT25 (returned 11110000 or 00000000 when I tried to wait for a measurement) I tried i2c and still total failure. Have stripped back the code to simply read the register and every variation fails. What have I done? (Probs obv but I am not a coder, just trying to learn some squirrel for electric imp fun)

`// SHT25 TempHum Sensor
// Version KateIs@EndOfTether
// SHT25 Datasheet http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_SHT25_Datasheet_V3.pdf

//Read Reg Only 
function readReg()
{
        i2c.configure(CLOCK_SPEED_100_KHZ);
        local givenI2cAddress = 0x40; //Datasheet 7-bit 1000'000
        local ADDR = givenI2cAddress << 1;
        server.log(givenI2cAddress);
        server.log(ADDR);
        i2c.write(ADDR, "\\xe7");
        // Read Reg Command = "\\xe7" 1110’0111
        local data = i2c.read(ADDR, "", 2)
        server.log(data);
}
// Configure Pins
i2c <- hardware.i2c89;

//start
readReg();`

First, you don’t need to configure the I2C every time you run readReg(), so I would move i2c.configure(CLOCK_SPEED_100_KHZ); underneath i2c <- hardware.i2c89; if I were you.

Second, you can combine the write operation (I assume this is a register selection) with the read operation. So get rid of i2c.write(ADDR, ); and change the read line to:

local data = i2c.read(ADDR, "\\xe7", 1);

This processes and times the operation in the way I2C devices usually expect, ie. register address write followed by an immediate read, so may work better in this case too.

PS. I see from the datasheet that you’re reading the SHT25’s user register, which contains settings info. To read the temperature, you want:

local temp = i2c.read(ADDR, "\\xe3", 2);

Finally, I’d recommend you read through our short Developer Guide ‘I2C Explained’, which is aimed at folk who are new to programming and to electronics.

Thank you so much for the quick response.

I am still just getting (null : 0x0) readings - the register default is 0000’0010.

Does the line of code for the temperature read allow for the time for measurement to complete because it is expecting to see the SCL to release?

local temp = i2c.read(ADDR, “\xe3”, 2);

I tried changing the baud rate although there is no real hardware justification for this and I will need some specialist tools/help to diagnose whether the problem is with the board.

The i2c guide - like most of the help pages - is excellent even if my attempts at implementation remain shoddy!

The call to the sub-address “\xE3” holds the clock while the reading is taken, according to the datasheet, so you shouldn’t have to introduce a pause of your own.

One other thing, you do have suitable pull-up resistors on the bus? You should also call i2c.readerror() after the i2c.read() and check the returned value: anything negative indicates an error, and may help you diagnose the problem.

Will give this ago. There are supposed to be pull ups but I’m checking the schematics again…

It’s a -2 error - Timeout while selecting transmit mode. We have 10k pull ups on our schematic. But your comment made me check the hardware.voltage which is 1.8 (below the 2.1 minimum) so I think this might be the issue…

I would use the “no hold” trigger, and then delay in your code; blocking in the i2c handler gives nothing else a chance to run and will give i2c errors if the chip stretches SCL for too long.

What’s your power setup? 1.8v is obviously too low to run wifi, which is fine if you’re offline when you’re doing this work. If you’re using a nora-type design with imp002 you can always manually drive the power enable high without powering on wifi using https://electricimp.com/docs/api/imp/setpoweren/

Thanks for the tip on the timings.
It finally worked!!
In the interests of saving others pain:

`// SHT25 TempHum Sensor
//Version 23/09/15
// SHT25 Datasheet http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_SHT25_Datasheet_V3.pdf

function readReg()
{
        ledr.write(1);
        local givenI2cAddress = 0x40; //Datasheet 7-bit 1000'000
        local ADDR = givenI2cAddress << 1;
        // SHT25_CMD_RRSTATUS = "\\xe7"
        i2c.write(ADDR, "\\xfe");        // soft reset
        imp.sleep(0.015);               // soft reset takes less than 15 ms
        local data = i2c.read(ADDR, "\\xe7", 2);
        local error = i2c.readerror();
        i2c.write(ADDR, "\\xf3");        // trigger T measurement no hold master
        imp.sleep(0.1);                 // allow SHT25 time to measure
        local temp = i2c.read(ADDR, "", 2);
        local errort = i2c.readerror(); 
        i2c.write(ADDR, "\\xf5");        // trigger RH measurement no hold master
        imp.sleep(0.1);                 // allow SHT25 time to measure
        local hum = i2c.read(ADDR, "", 2);
        local errorh = i2c.readerror(); 
         if(errorh == -1)     // SDA still zero
        {
            i2c.disable();
            scl.configure(DIGITAL_OUT);
            scl.write(0);       // produce an extra clock pulse on SCL
            imp.sleep(0.0001);
            scl.write(1);
            imp.sleep(0.0001);
            scl.configure(DIGITAL_IN);
            i2c.configure(CLOCK_SPEED_100_KHZ);
       }
       server.log("device status:" + data[0] + "," + data[1]);
        server.log("status reading error:" + error);
        server.log("temperature reading:" + temp[0] + "," + temp[1]);
        server.log("temp reading error:" + errort);
        server.log("humidity reading:" + hum[0] + "," + hum[1]);
        server.log("humidity reading error:" + errorh);
        
        // test AD5243 digital pot
        local AD5243 = 0x5E;
        i2c.write(AD5243, "\\x00\\x79");        // set digital pot
        local dpot = i2c.read(AD5243, "", 1);
        local errord = i2c.readerror(); 
        server.log("dpot reading:" + dpot[0]);
        server.log("dpot reading error:" + errord);

        ledr.write(0);
        imp.wakeup(10, readReg);
}
// Configure Pins
i2c <- hardware.i2c89;
ledr <- hardware.pinE;
scl <- hardware.pin8;
// options for clock speed are 10 to 400 khz so number just needs to change in brackets _XX_
i2c.configure(CLOCK_SPEED_100_KHZ);
ledr.configure(DIGITAL_OUT);

//start
imp.wakeup(10, readReg);`

was looking for SHT code… came across this code on git…
arduino code for SHT25 can be found over here…