Sensirion SFM3000 I2C problem
Posted: Mon Sep 09, 2019 12:18 pm
Hi All,
I'm trying to connect flow sensor model SFM3000 to ESP32 using I2C.
I tried to do it using Arduino and everything was OK.
but the problem with micropython that I'm receiving error bytes from the sensor.
This is the datasheet for sensor and I2C description
https://www.sensirion.com/en/download-c ... low-meter/
and this is my micropython code:
--------------------------------------------------------------------------------------------------
from machine import Pin, I2C
from time import sleep
# construct spi
i2c = I2C(scl=Pin(32),sda=Pin(33),freq=400000)
sleep(1)
# send 0x2000 to soft reset sensor and wait 3 sec
re = bytearray([0x20,0x00])
i2c.writeto(0x40,re)
sleep(3)
#scan for the sensor address
print(i2c.scan())
#Initialize Sensor send 0x1000 to sensor to start continuous measurement
start = bytearray([0x10,0x00])
print(i2c.writeto(64,start))
sleep(2)
#start measurements
while True:
buf=bytearray(3)
i2c.readfrom_into(0x40,buf)
print(buf)
sleep(1)
"
------------------------------------------------------------------------------------------------------
the output is sometimes 2 bytes or 3 bytes and it's incorrect
"
bytearray(b'}\x04\xbf')
bytearray(b'|\xf8\xb4')
bytearray(b'}\x04\xbf')
bytearray(b'}\x108')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'|\xfcp')
bytearray(b'}\x08\xc2')
bytearray(b'}\x04\xbf')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'}\x08\xc2')
bytearray(b'|\xf8\xb4')
bytearray(b'|\xf8\xb4')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'|\xf8\xb4')
"
-------------------------------------------------------------------------------------------------------
for arduino I used this code
"
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
int a = 0;
int b = 0;
int c = 0;
delay(1000);
Wire.beginTransmission(byte(0x40)); // transmit to device #064 (0x40)
Wire.write(byte(0x10)); //
Wire.write(byte(0x00)); //
Wire.endTransmission();
delay(5);
// the first two measurements are always wrong print just to debug
Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.println(a);
Serial.println(b);
Serial.println(c);
delay(5);
Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.print(a);
Serial.print(b);
Serial.println(c);
delay(5);
}
uint8_t crc8(const uint8_t data, uint8_t crc) {
crc ^= data;
for ( uint8_t i = 8; i; --i ) {
crc = ( crc & 0x80 )
? (crc << 1) ^ 0x31
: (crc << 1);
}
return crc;
}
void loop() {
int offset = 32000; // Offset for the sensor
float scale = 140.0; // Scale factor for Air and N2 is 140.0, O2 is 142.8
Wire.requestFrom(0x40, 3); // read 3 bytes from device with address 0x40
uint16_t a = Wire.read(); // first received byte stored here. The variable "uint16_t" can hold 2 bytes, this will be relevant later
Serial.println(a);
uint8_t b = Wire.read(); // second received byte stored here
Serial.println(b);
uint8_t crc = Wire.read(); // crc value stored here
Serial.println(crc);
uint8_t mycrc = 0xFF; // initialize crc variable
mycrc = crc8(a, mycrc); // let first byte through CRC calculation
mycrc = crc8(b, mycrc); // and the second byte too
if (mycrc != crc) { // check if the calculated and the received CRC byte matches
}
a = (a << 8) | b; // combine the two received bytes to a 16bit integer value
float Flow = ((float)a - offset) / scale;
Serial.println(a); // print the raw data from the sensor to the serial interface
Serial.println(Flow); // print the calculated flow to the serial interface
delay(25);
}
---------------------------------------------------------------------------------------------------------
sorry I don't know how to add code to the post
I'm trying to connect flow sensor model SFM3000 to ESP32 using I2C.
I tried to do it using Arduino and everything was OK.
but the problem with micropython that I'm receiving error bytes from the sensor.
This is the datasheet for sensor and I2C description
https://www.sensirion.com/en/download-c ... low-meter/
and this is my micropython code:
--------------------------------------------------------------------------------------------------
from machine import Pin, I2C
from time import sleep
# construct spi
i2c = I2C(scl=Pin(32),sda=Pin(33),freq=400000)
sleep(1)
# send 0x2000 to soft reset sensor and wait 3 sec
re = bytearray([0x20,0x00])
i2c.writeto(0x40,re)
sleep(3)
#scan for the sensor address
print(i2c.scan())
#Initialize Sensor send 0x1000 to sensor to start continuous measurement
start = bytearray([0x10,0x00])
print(i2c.writeto(64,start))
sleep(2)
#start measurements
while True:
buf=bytearray(3)
i2c.readfrom_into(0x40,buf)
print(buf)
sleep(1)
"
------------------------------------------------------------------------------------------------------
the output is sometimes 2 bytes or 3 bytes and it's incorrect
"
bytearray(b'}\x04\xbf')
bytearray(b'|\xf8\xb4')
bytearray(b'}\x04\xbf')
bytearray(b'}\x108')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'|\xfcp')
bytearray(b'}\x08\xc2')
bytearray(b'}\x04\xbf')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'}\x08\xc2')
bytearray(b'|\xf8\xb4')
bytearray(b'|\xf8\xb4')
bytearray(b'}\x00{')
bytearray(b'}\x00{')
bytearray(b'|\xf8\xb4')
"
-------------------------------------------------------------------------------------------------------
for arduino I used this code
"
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
int a = 0;
int b = 0;
int c = 0;
delay(1000);
Wire.beginTransmission(byte(0x40)); // transmit to device #064 (0x40)
Wire.write(byte(0x10)); //
Wire.write(byte(0x00)); //
Wire.endTransmission();
delay(5);
// the first two measurements are always wrong print just to debug
Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.println(a);
Serial.println(b);
Serial.println(c);
delay(5);
Wire.requestFrom(0x40, 3); //
a = Wire.read(); // first received byte stored here
b = Wire.read(); // second received byte stored here
c = Wire.read(); // third received byte stored here
Wire.endTransmission();
Serial.print(a);
Serial.print(b);
Serial.println(c);
delay(5);
}
uint8_t crc8(const uint8_t data, uint8_t crc) {
crc ^= data;
for ( uint8_t i = 8; i; --i ) {
crc = ( crc & 0x80 )
? (crc << 1) ^ 0x31
: (crc << 1);
}
return crc;
}
void loop() {
int offset = 32000; // Offset for the sensor
float scale = 140.0; // Scale factor for Air and N2 is 140.0, O2 is 142.8
Wire.requestFrom(0x40, 3); // read 3 bytes from device with address 0x40
uint16_t a = Wire.read(); // first received byte stored here. The variable "uint16_t" can hold 2 bytes, this will be relevant later
Serial.println(a);
uint8_t b = Wire.read(); // second received byte stored here
Serial.println(b);
uint8_t crc = Wire.read(); // crc value stored here
Serial.println(crc);
uint8_t mycrc = 0xFF; // initialize crc variable
mycrc = crc8(a, mycrc); // let first byte through CRC calculation
mycrc = crc8(b, mycrc); // and the second byte too
if (mycrc != crc) { // check if the calculated and the received CRC byte matches
}
a = (a << 8) | b; // combine the two received bytes to a 16bit integer value
float Flow = ((float)a - offset) / scale;
Serial.println(a); // print the raw data from the sensor to the serial interface
Serial.println(Flow); // print the calculated flow to the serial interface
delay(25);
}
---------------------------------------------------------------------------------------------------------
sorry I don't know how to add code to the post