Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    SI7021 I2C pin setup (SOLVED)

    Scheduled Pinned Locked Moved MicroPython
    micropythonsi7021i2c
    59 Posts 4 Posters 13.2k Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • robert-hhR Offline
      robert-hh @tttadam
      last edited by

      @tttadam You do not have to re-create the i2c object. You can call i2c.init() to change the parameters. And I still do not know why you create the Pin objects separately. You just have to name them when creating the I2C object:

      bus = I2C(0, I2C.MASTER, baudrate=baud, pins=("P9","P10"))
      The init method of i2c will initialize the Pin objects.

      T 1 Reply Last reply Reply Quote 1
      • T Offline
        tttadam @robert-hh
        last edited by

        @robert-hh

        Okay I modified the code as you recomended it.
        But I got the same error on every baudrate.
        Here is the csv, but nothing intresting in it: http://www.filedropper.com/data_11

        import pycom
        from machine import I2C, Pin
        from SI7021 import SI7021
        import time
        
        expledpin = Pin('G16', mode=Pin.OUT)
        buttonpin = Pin('G17', mode= Pin.IN, pull=Pin.PULL_UP)
        i2c = I2C(0, pins=("P9","P10"))
        start = True
        while start:
            if buttonpin() == 0:
                start = False
            
        
        with open("/sd/data.csv", 'a')as ds: 
            expledpin.value(1)
            for baud in range(1, 115200):
                pycom.rgbled(0x0000FF)
                i2c.init(I2C.MASTER, baudrate=baud)
                sensor = SI7021(i2c=i2c)
                try:
                    print(sensor.readTemp()) 
                    ds.write("\n\r;;"+str(sensor.readTemp())) 
                    pycom.rgbled(0x00FF00)
                except OSError as er:
                    pycom.rgbled(0xFF0000)
                    expledpin.value(0)
                    ds.write("\n\r"+str(repr(er))+";"+str(baud)+";")
                    expledpin.value(1)
        
                time.sleep(0.001)
                pycom.rgbled(0x000000)
            
            ds.close()
        
        
        robert-hhR 1 Reply Last reply Reply Quote 0
        • robert-hhR Offline
          robert-hh @tttadam
          last edited by

          @tttadam That#s strange, especially since i2c.scan() works, which also needs I2c communication. You could try to add an i2c.scan in the test after the i2c.init, just to confirm that it works. And yes, you do not need every baud rate. You can go back to a value like 100000.
          I faintly recall a link to the SI7021 driver you are using, but cannot find it any more.

          E 1 Reply Last reply Reply Quote 1
          • E Offline
            Eric73 @robert-hh
            last edited by Eric73

            @robert-hh link you looking for is in tilte https://forum.pycom.io/topic/648/si7021-i2c-sensor not ?

            @ttadam Have you add pysical pull up resistor on SDA and SCL to 3.3V (4.7K or 1K value) ? Even if you set software pull up to the pin definitions, when you call i2c.init i dont know if pin your specify are not setup as pure opendrain by i2c library, so perhaps a test can with pull up can be done ?

            T robert-hhR 2 Replies Last reply Reply Quote 1
            • T Offline
              tttadam @Eric73
              last edited by

              @eric73 I am using a 1k resistor both on SDA and SCL.
              The program takes much more time to run because of the i2c.scan().... But I will write ehen I have the result.

              robert-hhR 1 Reply Last reply Reply Quote 0
              • robert-hhR Offline
                robert-hh @Eric73
                last edited by

                @eric73 @tttadam So is it this code:

                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.cbuffer[0] = command_byte
                    self.i2c.writeto(self.addr, self.cbuffer)
                
                  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
                

                Form the first glance, it looks Ok and compatible to Pycom's MicroPython.

                1 Reply Last reply Reply Quote 1
                • robert-hhR Offline
                  robert-hh @tttadam
                  last edited by

                  @tttadam 1K is too low. The usual recommendation is 4.7 k. But that should not change the figure. The question is, whether i2c.scan() returns [64] also in the context of your main code.
                  If yes, then the port & wires & I2C protocol are OK, and we have to look at the SI7021 module.

                  T 1 Reply Last reply Reply Quote 1
                  • T Offline
                    tttadam @robert-hh
                    last edited by

                    @robert-hh Okay, I will get bigger resistors, and replace the sensor.
                    Thank you for the help.

                    robert-hhR 1 Reply Last reply Reply Quote 0
                    • robert-hhR Offline
                      robert-hh @tttadam
                      last edited by robert-hh

                      @tttadam I searched a little bit for a module that looks like yours. I found one, and in the backside pictures I see some resistors, which most likely are 10k pull-up resistors, and a three terminal device, which is according to the print-out a LM6206N3 3.3V voltage regulator. The pull-up resistors seem to be connected to 5V. Being 10k, that should not hurt the pycom device, and you do not need external pull-up resistors. And the 5V were OK for your device.
                      0_1539111519069_SI7021.jpg
                      Edit: I see also a dual level shifter, which is intended to connect a 5V side at the micro to the 3.3 V side of the sensor. It is a single FET transistor level shifter.

                      T 1 Reply Last reply Reply Quote 1
                      • T Offline
                        tttadam @robert-hh
                        last edited by

                        @robert-hh Well I just ran the code again(from 5V without resistors), but I got OS error for every baud rate from 1 to 10000. So I think something most be wrong with this sensor.

                        E 1 Reply Last reply Reply Quote 0
                        • E Offline
                          Eric73 @tttadam
                          last edited by

                          @tttadam Single transistor level shifter ? A single transistor is an inverter gate, your SDA and SCL signal will be inverted. Please note that i2c is an opendrain bus with pull up. Your SI7021 can be powered by +5V (if its identical to the one showed by robert-hh) but have you checked is your board have 5V-3.3V regulator and have you checked what is SDA and SCL voltage level when you just power SI7021? In SI7021 datasheet absolute maximum rating for SDA and SCL is 3.3V, i have doubts that a SI7021 board have +5V pull-up on SDA and SCL....without power any of the two board, please check your wire continuity with multimeter if you can.

                          robert-hhR 1 Reply Last reply Reply Quote 1
                          • robert-hhR Offline
                            robert-hh @Eric73
                            last edited by robert-hh

                            @eric73 said in SI7021 I2C pin setup:

                            Single transistor level shifter ?

                            Yes. there is a standard circuit doing this with single MosFET transistor, used by all cheap level shifter. Principle below. LV is low voltage, HV is high voltage, Lx and Hx are the low & high voltage logic. And you see the pull-up resistors on both sides:
                            0_1539239103613_shifter.jpg
                            P.S.: You could make a picture of the back side of the sensor, just to clarify @Eric73 's question.

                            T 1 Reply Last reply Reply Quote 2
                            • nespressifN Offline
                              nespressif
                              last edited by

                              Hello everyone, I have tested with an HTU21d sensor that is very similar to the SI7021 and with the SI7021 class I also get the "I2C bus error". However with the code in the main.py, it works perfectly, and without external resistances, I do not understand why I get the error with the class, if everything seems to be fine.
                              I use this one:

                              from machine import I2C
                              import time
                              
                              i2c = I2C(0, I2C.MASTER)
                              print(i2c.scan()) #I get [64] is 0x40
                              
                              i2c.writeto(0x40, 0xf3) #read temp no hold
                              time.sleep_ms(25) 
                              temp = i2c.readfrom(0x40, 3)
                              temp2 = temp[0] << 8
                              temp2 = temp2 | temp[1]
                              print((175.72 * temp2 / 65536) - 46.85) 
                              

                              I hope it helps you, Regards

                              robert-hhR 1 Reply Last reply Reply Quote 2
                              • robert-hhR Offline
                                robert-hh @nespressif
                                last edited by robert-hh

                                @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
                                
                                nespressifN 1 Reply Last reply Reply Quote 1
                                • nespressifN Offline
                                  nespressif @robert-hh
                                  last edited by

                                  @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)
                                  
                                  robert-hhR 2 Replies Last reply Reply Quote 1
                                  • robert-hhR Offline
                                    robert-hh @nespressif
                                    last edited by

                                    This post is deleted!
                                    1 Reply Last reply Reply Quote 0
                                    • robert-hhR Offline
                                      robert-hh @nespressif
                                      last edited by

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

                                      T 1 Reply Last reply Reply Quote 1
                                      • T Offline
                                        tttadam @robert-hh
                                        last edited by

                                        @robert-hh 1sorry for the delay.
                                        I took pictures of the sensors.
                                        https://photos.app.goo.gl/d1p1NSwZaXU41QbK8

                                        1 Reply Last reply Reply Quote 0
                                        • T Offline
                                          tttadam @robert-hh
                                          last edited by

                                          @robert-hh Sorry But it is not clear for me. What sould I change in SI7021.py file?
                                          Thnak you

                                          robert-hhR 1 Reply Last reply Reply Quote 0
                                          • robert-hhR Offline
                                            robert-hh @tttadam
                                            last edited by

                                            @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)
                                            
                                            T 1 Reply Last reply Reply Quote 1

                                            Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                            Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                            With your input, this post could be even better 💗

                                            Register Login
                                            • 1
                                            • 2
                                            • 3
                                            • 2 / 3
                                            • First post
                                              Last post

                                            Pycom on Twitter

                                            Pycom