SI7021 I2C pin setup (SOLVED)
-
Hi there,
I would like to use a SI7021 sensor. I found this code which suppose to work, but I can't find where does the I2C pin setup happening. So where could a I change the code to use GPIO06 and 07?
Thank you in advance :)
-
@robert-hh Awsome! Thank you
-
@tttadam I extended the class SI7021 a little bit. It also waits now for max 100ms time for the device to return a value, but returns earlier if values are returned. A documentation is added too.
https://github.com/robert-hh/SI7021
-
@tttadam That's very good. When trying to read before the conversion is done you get an I2C bus error. The strange thing is, that according to the data sheet 25ms is already a safe value. The maximum conversion time according to the data sheet is 12 ms for RH at 12 bit resolution.
I found no robust way to scan the device for a "conversion ready" state.
-
-
@tttadam It is interesting that readRH() seemed to have worked, since the code fails at readTemp(). Try two things:
a) use only readRH
b) increase the sleep_ms(25) to sleep_ms(50).
-
@robert-hh Well I formatted the flash, then restarted the device.
Than uploded SI7021.py, an empyt boot file, and a main.py with 6 line of code. But still no luck...Uploading project (main folder)... Not safe booting, disabled in settings Reading file status Failed to read project status, uploading all files Creating dir lib [1/3] Writing file boot.py [2/3] Writing file lib/SI7021.py [3/3] Writing file main.py Upload done, resetting board... OKets Jun 8 2016 00:22:57 rst:0x7 (TG0WDT_SYS_RESET),boot:0x33 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff8028,len:8 load:0x3fff8030,len:1728 load:0x4009fa00,len:0 load:0x4009fa00,len:14584 entry 0x400a059c [64] Traceback (most recent call last): File "main.py", line 6, in <module> File "/flash/lib/SI7021.py", line 32, in readTemp OSError: I2C bus error Pycom MicroPython 1.18.1.r1 [v1.8.6-849-b0520f1] on 2018-08-29; LoPy4 with ESP32 Type "help()" for more information.
my main.py:
from machine import I2C from SI7021 import SI7021 i2c=I2C(0, I2C.MASTER) print(i2c.scan()) m = SI7021(i2c) print(m.readRH(), m.readTemp())
my boot.py, is just comment
and my SI7021 is like this:
from time import sleep_ms from machine import Pin, I2C # Default Address SI7021_I2C_DEFAULT_ADDR = 0x40 # Commands CMD_MEASURE_RELATIVE_HUMIDITY_HOLD_MASTER_MODE = 0xE5 CMD_MEASURE_RELATIVE_HUMIDITY = 0xF5 CMD_MEASURE_TEMPERATURE_HOLD_MASTER_MODE = 0xE3 CMD_MEASURE_TEMPERATURE = 0xF3 CMD_READ_TEMPERATURE_VALUE_FROM_PREVIOUS_RH_MEASUREMENT = 0xE0 CMD_RESET = 0xFE CMD_WRITE_RH_T_USER_REGISTER_1 = 0xE6 CMD_READ_RH_T_USER_REGISTER_1 = 0xE7 CMD_WRITE_HEATER_CONTROL_REGISTER = 0x51 CMD_READ_HEATER_CONTROL_REGISTER = 0x11 class SI7021(object): def __init__(self, i2c=None): self.i2c = i2c self.addr = SI7021_I2C_DEFAULT_ADDR self.cbuffer = bytearray(2) self.cbuffer[1] = 0x00 def write_command(self, command_byte): self.i2c.writeto(self.addr, command_byte) def readTemp(self): self.write_command(CMD_MEASURE_TEMPERATURE) sleep_ms(25) temp = self.i2c.readfrom(self.addr,3) temp2 = temp[0] << 8 temp2 = temp2 | temp[1] return (175.72 * temp2 / 65536) - 46.85 def readRH(self): self.write_command(CMD_MEASURE_RELATIVE_HUMIDITY) sleep_ms(25) rh = self.i2c.readfrom(self.addr, 3) rh2 = rh[0] << 8 rh2 = rh2 | rh[1] return (125 * rh2 / 65536) - 6
-
@tttadam When you update the firmware, then you have in the advanced section the option to erase the file system. Other method from the REPL prompt:
import uos uos.mkfs("/flash")
And then reboot.
-
@robert-hh Can I do a factory reset somehow? Delete everything from the device.
-
@tttadam Please check that there is only one copy of SI7021.py installed on your device. When working with pymakr, that may happen. Please use simple tools like ftp for the check. And yes, the version I posted works. No, I do not think that your device is defect. And it is well protected. Ans since it responds well to scan(), the wiring is also fine. So the code or code set-up is most probably the problem.
-
Traceback (most recent call last): File "main.py", line 6, in <module> File "/flash/lib/SI7021.py", line 32, in readTemp OSError: I2C bus error
still the same. If it's working on your side, than my sensor must be dead.
-
@tttadam Don't care about the baud rate. Here is works well at the default baud rate (I purchased I device for testing). This is the class code which works:
from time import sleep_ms from machine import Pin, I2C # Default Address SI7021_I2C_DEFAULT_ADDR = 0x40 # Commands CMD_MEASURE_RELATIVE_HUMIDITY_HOLD_MASTER_MODE = 0xE5 CMD_MEASURE_RELATIVE_HUMIDITY = 0xF5 CMD_MEASURE_TEMPERATURE_HOLD_MASTER_MODE = 0xE3 CMD_MEASURE_TEMPERATURE = 0xF3 CMD_READ_TEMPERATURE_VALUE_FROM_PREVIOUS_RH_MEASUREMENT = 0xE0 CMD_RESET = 0xFE CMD_WRITE_RH_T_USER_REGISTER_1 = 0xE6 CMD_READ_RH_T_USER_REGISTER_1 = 0xE7 CMD_WRITE_HEATER_CONTROL_REGISTER = 0x51 CMD_READ_HEATER_CONTROL_REGISTER = 0x11 class SI7021(object): def __init__(self, i2c=None): self.i2c = i2c self.addr = SI7021_I2C_DEFAULT_ADDR self.cbuffer = bytearray(2) self.cbuffer[1] = 0x00 def write_command(self, command_byte): self.i2c.writeto(self.addr, command_byte) def readTemp(self): self.write_command(CMD_MEASURE_TEMPERATURE) sleep_ms(25) temp = self.i2c.readfrom(self.addr,3) temp2 = temp[0] << 8 temp2 = temp2 | temp[1] return (175.72 * temp2 / 65536) - 46.85 def readRH(self): self.write_command(CMD_MEASURE_RELATIVE_HUMIDITY) sleep_ms(25) rh = self.i2c.readfrom(self.addr, 3) rh2 = rh[0] << 8 rh2 = rh2 | rh[1] return (125 * rh2 / 65536) - 6
It is called with:
from machine import I2C i2c=I2C(0, I2C.MASTER) from SI7021 import SI7021 m = SI7021(i2c) print(m.readRH(), m.readTemp())
Device connected at P9 = SDA and P10 = SCL, Vin at 3.3V
-
@robert-hh well I ran my little baudrate finder again with modflyed write_command method.
But I got tha same result, exept it frozed at 2964 baud.I am not sure what am I missing.
-
@tttadam The board looks fine. Not additional resistors required. In the SI7021 class there is a function call write_command. Change that function into:
def write_command(self, command_byte): self.i2c.writeto(self.addr, command_byte)
-
@robert-hh Sorry But it is not clear for me. What sould I change in SI7021.py file?
Thnak you
-
@robert-hh 1sorry for the delay.
I took pictures of the sensors.
https://photos.app.goo.gl/d1p1NSwZaXU41QbK8
-
@nespressif @tttadam I just verified that change to write_command(), and it works.
Setting: Vin of the SI7021 module at 3.3V, not external pull-up resistors.
-
This post is deleted!
-
@robert-hh I'm sorry, but I don't understand what you want me to do. I've already tried creating a SI7021(i2c) class object and I get that error. Maybe that's how it works, I'll try it:
def write_command(self, command_byte): #self.cbuffer[0] = command_byte self.i2c.writeto(self.addr, command_byte)
-
@nespressif The difference is in writing the command. In your example, you are writing a single int value,
i2c.writeto(0x40, 0xf3) #read temp no hold
wheras in the class it is two bytes, where the first byte contains the command, and the second a zero.def write_command(self, command_byte): self.cbuffer[0] = command_byte self.i2c.writeto(self.addr, self.cbuffer)
Since you have a suitable device at hand, could you try to change the class accordingly. e.g. like below:
def readTemp(self): self.i2c.writeto(self.addr, CMD_MEASURE_TEMPERATURE) sleep_ms(25) temp = self.i2c.readfrom(self.addr,3) temp2 = temp[0] << 8 temp2 = temp2 | temp[1] return (175.72 * temp2 / 65536) - 46.85