Si7051 Sensor Code I2C Arduino-->Particle Help? [SOLVED]

Hi, all! I have a very small bit of i2c code that works great on an Arduino Uno (so I know hooking up the sensor is fine, pull-up resistors, etc are all good) but the same code isn’t working at all on the Photon. I’m not terribly i2c savvy, could someone check and see if I’ve missed something obvious?

Arduino Code

#include <Wire.h>

void setup() {
  Wire.begin();

  Wire.beginTransmission(0x40);
  Wire.write(0xE6);
  Wire.write(0x0);
  Wire.endTransmission();
  
  Serial.begin(9600);
  Serial.println("ClosedCube Si7051 Arduino Test");
}

void loop() {
  Wire.beginTransmission(0x40);
  Wire.write(0xF3);
  Wire.write(0x40);
  Wire.write(0x40);
  Wire.write(0x40);
  Wire.endTransmission();

  delay(10);

  Wire.requestFrom(0x40, (uint8_t)2);

  byte msb = Wire.read();
  byte lsb = Wire.read();
    
  uint16_t val = msb << 8 | lsb;

  float temperature = (175.72*val) / 65536 - 46.85;
  Serial.print("msb= ");
  Serial.println(msb);
  Serial.print("lsb= ");
  Serial.println(lsb);
  Serial.print("val=");
  Serial.println(val);
  Serial.print("T=");
  Serial.print(temperature);
  Serial.println("C");
  
  delay(2000);

}

Serial [Uno] Output:
msb= 101
lsb= 92
val=25948
T=22.72C


#include "math.h"
#include "application.h"



void setup() {
    Wire.begin();

	Wire.beginTransmission(0x40);
	Wire.write(0xE6);
	Wire.write(0x0);
	Wire.endTransmission();
	
	Serial.begin(9600);
	Serial.println("ClosedCube Si7051 Arduino Test");
}

void loop() {
    Wire.beginTransmission(0x40);
	Wire.write(0xF3);
	Wire.write(0x40);
	Wire.write(0x40);
	Wire.write(0x40);
	Wire.endTransmission();

	delay(100);

	Wire.requestFrom(0x40, (uint8_t)2);

	byte msb = Wire.read();
	byte lsb = Wire.read();
    
	uint16_t val = msb << 8 | lsb;

	float temperature = (175.72*val) / 65536 - 46.85;
	Serial.print("msb= ");
    Serial.println(msb);
    Serial.print("lsb= ");
    Serial.println(lsb);
    Serial.print("val=");
    Serial.println(val);
    Serial.print("T=");
    Serial.print(temperature);
    Serial.println("C");
  
    delay(2000);

}

Serial [Photon] Output:
msb= 255
lsb= 255
val=65535
T=128.87C


If it’s something super subtle in how i2c on the Photon works, I do have an oscilloscope/analyzer I can learn to hook up. Many thanks for any comments!

I'll still ask for your exact hookup description.

And you may add a delay between your request and the first Wire.read()

1 Like

Thanks, ScruffR!

I’m using the breakout board from ClosedCube. The above code is based on their library on github.

Photon-------Si7051(board):
3v3--------VDD
D1--------SCL (10k pull-up resistor to VDD included on board)
D0--------SDA (10k pull-up resistor to VDD included on board)
GND--------GND

Arduino Uno--------Si7051(board):
3v3---------VDD
A5--------SCL (10k pull-up resistor to VDD included on board)
A4--------SDA (10k pull-up resistor to VDD included on board)
GND--------GND

Have you added the delay (e.g. 5ms)?
Does that change anything?

The 10k pull-ups might be a bit weak. How about adding another set of 10k resistors in parallel?

I know you already have a temp sensor but if you ever want to upgrade then I would suggest this one: https://www.adafruit.com/products/2857

There is a working library for this sensor for the Photon & Electron ready to go also.

Tried different delay values (5ms-25ms) without success.

...
Wire.requestFrom(0x40, (uint8_t)2);
delay(10); \\tested 5ms, 10ms, 15ms, 20ms, 25ms still getting same output as before = 255's

byte msb = Wire.read();
...

I’ll try lowering the effective pull-up resistances later today.

Thanks for the suggestion about the humidity + temperature sensor. This Si7051 sensor is rated +/-0.1C for temperature and is a bit smaller than the Adafruit board. I’m planning on burying it inside a small heating/cooling plate, and so size and resolution and only needing to read temperature brought me to this sensor. Properly done, I would use an RTD or thermister, but I’m happier not having to read the analog values carefully. :smile:

Here is a contactless temp sensor that we also have a library for : https://www.adafruit.com/products/1747

Looking at the datasheet I don’t really see a reason for sending those 0x40 commands

  Wire.beginTransmission(0x40);
  Wire.write(0xF3);
  Wire.write(0x40);
  Wire.write(0x40);
  Wire.write(0x40);
  Wire.endTransmission();

Where do they come from?

1 Like

Thanks for digging deep into it, ScruffR!
These were in the original code from ClosedCube (as Wire.write(_address)). I was confused, too, and don’t know why they were included exactly, but left in because it was working in Arduino/Uno.

Your comments have helped me fix it! :slight_smile:

Looking again at the datasheet it shows a 10+ ms time for the 14bit temperature conversion. A combination of waiting 15ms and getting rid of the extra Wire.write(0x40) commands works and the code is below. I’ll test for a while and then maybe try to learn how to make this into a library for public use on Particle.

/*******************
For use with ClosedCube Si7051 breakout board

Photon-------Si7051(board):
3v3--------VDD
D1--------SCL (10k pull-up resistor to VDD included on board)
D0--------SDA (10k pull-up resistor to VDD included on board)
GND--------GND
******************/


#include "math.h"
#include "application.h"



void setup() {
    Wire.begin();

	Wire.beginTransmission(0x40);
	Wire.write(0xE6);
	Wire.write(0x0);
	Wire.endTransmission();
	
	Serial.begin(9600);
	Serial.println("ClosedCube Si7051 Arduino Test");
}

void loop() {
    Wire.beginTransmission(0x40); 
	Wire.write(0xF3); //calling for Si7051 to make a temperature measurement
	//Wire.write(0x40); extra writes not needed - were included in original Arduino sketch but cause issues in Particle
	//Wire.write(0x40);
	//Wire.write(0x40);
	Wire.endTransmission();

	delay(15); //14 bit temperature conversion needs 10+ms time to complete.

	Wire.requestFrom(0x40, (uint8_t)2);
    delay(25);
	byte msb = Wire.read();
	byte lsb = Wire.read();
    
	uint16_t val = msb << 8 | lsb;

	float temperature = (175.72*val) / 65536 - 46.85;
	Serial.print("msb= ");
    Serial.println(msb);
    Serial.print("lsb= ");
    Serial.println(lsb);
    Serial.print("val=");
    Serial.println(val);
    Serial.print("T=");
    Serial.print(temperature);
    Serial.println("C");
  
    delay(2000);

}
1 Like

Ha! 'Also works fine (on an Uno) if those extra writes are omitted in the Arduino code.

1 Like

Hello.

I’ve been trying to use this sensor with my Arduino Mega and I don’t seem to make it work.

Even with this code, i get all the time the same outputs:

msb= 255
lsb= 255
val=65535
T=128.87C

The sensor’s datasheet suggests an application circuit which I also made to measure the temperature. So it means I added there as well 2 10kOhm resistors.

What am I doing wrong? I need help!
Thanks in advance

Hello @AlvaroR20 and welcome to the Particle community. The focus of this forum is to discuss matters related to Particle. While questions about Arduino or other platforms may be answered, they are not the main focus and are often not encouraged.

You may or may not be aware of the Arduino Forum. It’s probably a better place to ask Arduino specific questions.

However, could you elaborate on your circuit?

If you’re using the breakout board that already has the I2C pullup resistors included I don’t think you should add any resistors.

I posted here because it is one of the few places where I found any information about Arduino/Particle related things about the sensor I am having troubles with.

The circuit is the one shown below:
image

I am having the same output with and without those 2 10k resistors.

Have you tried the sample code above from @mtmentat - it should work on your Arduino ?

When you have I2C issues one of the first debugging steps should be to run a I2C scanner to checke whether the device is seen on the interface at all and whether the used address is correct.

2 Likes

I tried both commenting and not the Wire.write(0x40) lines and I have the same results. I double checked the address and it’s 0x40 indeed.

Have you run a scanner as @ScruffR suggested ? This way you will at least know the device is connected ok and responding at a basic level