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.
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.
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/