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

    I2C sensor with WiPy2

    Scheduled Pinned Locked Moved WiPy 2&3
    wipy2.0i2csensor
    28 Posts 8 Posters 11.3k Views 8 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.
    • S Offline
      SesamProductions
      last edited by

      Hi!
      I'm trying to read a VL6180x distance sensor with my WiPy2.
      The WiPy detects the sensor and can read stuff from it, but the results doesn't really make sense.
      According to the datasheet, register 0 should contain a model ID = 0xB4. The first time I read it I get the correct value, but if I keep reading it after that I get random values. If I reboot the sensor, I can read the correct value again one time. The same thing goes for all other registers I've tried to read.
      The code I use to read:

      from machine import I2C
      i2c = I2C(0, I2C.MASTER)
      i2c.readfrom_mem(0x29, 0, 1)
      

      The sensor is on a breakout board with a voltage regulator, and there's nothing wrong with it, because if I connect it to an Arduino and do the same thing, it works perfectly. I've tried both to have the sensor connected directly to the WiPy, running it on 3.3V, and via a levelshifter, running it on 5V.
      I have also tried different baudrates, but with no change.
      What am I doing wrong?

      L I 2 Replies Last reply Reply Quote 0
      • L Offline
        livius @SesamProductions
        last edited by

        @SesamProductions
        which firmware

        os.uname()
        

        think about people first, then computers

        1 Reply Last reply Reply Quote 0
        • S Offline
          SesamProductions
          last edited by

          (sysname='WiPy', nodename='WiPy', release='1.7.2.b1', version='v1.8.6-650-g9bacbbd4 on 2017-06-09', machine='WiPy with ESP32')

          L 1 Reply Last reply Reply Quote 0
          • L Offline
            livius @SesamProductions
            last edited by livius

            @SesamProductions
            try upgrade to recent firmware because now i2c is hardware implementation not software as was previously
            https://forum.pycom.io/topic/1423/new-firmware-release-1-7-5-b2

            think about people first, then computers

            S 1 Reply Last reply Reply Quote 0
            • S Offline
              SesamProductions @livius
              last edited by

              @livius Thanks for the tip, I had not noticed that there were new firmwares out. Unfortunately it didn't help.
              Do I have to make any changes to my code with this?

              I have now tried this with two different WIPy2 borads with the most recent firmware. I have also tried with two different identical sensor boards, as well as three other i2c-devices, none gives any sensible output to the WiPy, but all work well with Arduinos.

              I did notice one thing that could possibly be relevant, although I have no idea how.
              This is a readout made just after reboot:

              >>> os.uname()
              (sysname='WiPy', nodename='WiPy', release='1.7.6.b1', version='v1.8.6-703-g5e80328a on 2017-07-05', machine='WiPy with ESP32')
              >>> from machine import I2C
              >>> i = I2C(0, I2C.MASTER)
              >>> i.scan()
              [41, 57, 87, 104]
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\xb4'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\x01'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\x03'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\x01'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\x02'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'r'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'C'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\xe9'
              >>> i.readfrom_mem(0x29, 0, 1)
              b'\xa0'
              

              The first response, b'\xb4', is the correct one, but should not change. The commands are sent about one second apart.
              The interesting thing is that the response sequence is always identical, with both sensors and both boards, it's always:
              b'\xb4'
              b'\x01'
              b'\x03'
              b'\x01'
              and so on.

              I have absolutely no idea what's wrong or what to try next and will appreciate any help!

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

                @SesamProductions So it looks as if instead just the first byte all registers of the first group are transferred. I wonder why you use i2c.readfrom_mem(), since this is not a memory device. I would expect that you first have to send the register address with i2c.writeto() and then read back the intended number of bytes with i2c.readfrom().

                S 1 Reply Last reply Reply Quote 0
                • S Offline
                  SesamProductions @robert-hh
                  last edited by

                  @robert-hh Thanks for that insight, that turned out to be exactly what's happening! And after doing a closer inspection in the datasheet I found this sentence:
                  "After the first data byte has been transferred, the index is automatically incremented by 1."
                  Now on to learning how to use that feature.

                  Regarding i2c.readfrom_mem()
                  I might have missunderstood how it works, but how can I read a specific device register without it?
                  The machine-module documentation says in connection to readfrom_mem:
                  "Some I2C devices act as a memory device (or set of registers)", and I interpreted that to mean that it's the function to use when targeting a specific register.
                  Is that instead referring to devices with some other register functionality?

                  I just now tried doing i2c.writeto(0x29, 0), which returned 1, and then i2c.readfrom(0x29, 1), but it didn't return any useful values, mostly zeroes but sometimes other values. If I understood your suggestion correct that should have given me the 'b4' I want.

                  L robert-hhR 2 Replies Last reply Reply Quote 0
                  • L Offline
                    livius @SesamProductions
                    last edited by

                    @SesamProductions
                    If you look at C library
                    you must do much more work to work with this sensor
                    https://github.com/pololu/vl6180x-arduino/blob/master/VL6180X.cpp

                    think about people first, then computers

                    1 Reply Last reply Reply Quote 0
                    • E Offline
                      Eric24
                      last edited by

                      @SesamProductions said in I2C sensor with WiPy2:

                      VL6180x

                      Yes, this is a fairly complex device that requires a lot of initialization (although I would think reading back the model ID could be done without init, but who knows). We used this driver: https://github.com/luciengaitskell/python-adafruit-vl6180x/blob/master/i2c/vl6180x.py

                      We've since moved on from using this sensor (it's a very interesting device, but it did not work well in our particular application), but I had no problem communicating with it. In fact, the only problems I've ever had with I2C on any pycom device was with the lack of clock stretching support on the software-based I2C (and now that hardware-based I2C is supported, that's no longer a problem).

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

                        @SesamProductions From the spec, I assume that the sequence should be:

                        i2c.writeto(0x29, b'\x00\x00')
                        i2c.readfrom(0x29, 1)
                        

                        The address for a read is a two byte value.

                        1 Reply Last reply Reply Quote 1
                        • I Offline
                          iotmaker
                          last edited by

                          I have it working like this

                          VL53L0X_REG_IDENTIFICATION_MODEL_ID=0xc0
                          VL53L0X_REG_IDENTIFICATION_REVISION_ID=0xc2
                          VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD=  0x50
                          VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD=0x70
                          VL53L0X_REG_SYSRANGE_START=0x00
                          VL53L0X_REG_RESULT_INTERRUPT_STATUS=0x13
                          VL53L0X_REG_RESULT_RANGE_STATUS=0x14
                          sensor= 0x29#I2C Address
                          
                          
                          print("Revision ID ")
                          print(i2c.readfrom_mem(sensor,VL53L0X_REG_IDENTIFICATION_REVISION_ID,1))
                          print("")
                          print("Device ID ")
                          print(i2c.readfrom_mem(sensor,VL53L0X_REG_IDENTIFICATION_MODEL_ID,1))
                          print("")
                          print("Pre Range config Period")
                          print(i2c.readfrom_mem(sensor,VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,1))
                          print("")
                          print("Final  Period")
                          print(i2c.readfrom_mem(sensor,VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,1))
                          
                          #To read first check the status
                          val=i2c.readfrom_mem(sensor,VL53L0X_REG_RESULT_RANGE_STATUS,1)
                          
                          #if val is equal to 64 then it read the distance 
                          
                          #read the value
                           datasensor=i2c.readfrom_mem(sensor,0x14,12)#Read sensor data
                              distance=datasensor[10]*256+datasensor[11]#combine integers
                          
                          

                          I have it working on the VL53L0X hope it helps

                          C J 3 Replies Last reply Reply Quote 0
                          • S Offline
                            SesamProductions @Eric24
                            last edited by

                            Thanks for the suggestions!

                            @robert-hh
                            YES! That is working! Thank you! I can now read data from registers in a controller way.
                            Unfortunately I'm now very confused about this. If the writeto function is used to tell the device what register I want to read, how do I write things to the registers? For instance to tell the device I want it to start measuring range.

                            @iotmaker
                            To me it looks like you're doing the exakt same thing I'm doing, and according to the short datasheet I found for your sensor, it should work similar to mine.
                            So why yours is working and mine is not is definitely beyond me.

                            @Eric24
                            When I've tried the sensor on the Arduino I've used the Adafruit library your linked code seem to be a python port of. I had myself not found that python version, so what I've done is my own python port of the Adafruit Arduino library. The problem is that in order to deal with all the complexities of the sensor and initialize it, I need to be able to read and write to registers, which is the part that isn't working.
                            The python-version you're linking to is using a module called smbus to deal with everything I'm having problems with. Where do I get that from? I didn't find any links for that on the github page, and import smbus is not working on my WiPy. Where you using it on a WiPy, or some other Pycom device?
                            I had not heard about smbus before and a quick google for it seem to indicate it's a different, but fairly similar, protocol than i2c. Was there a reason for using smbus instead of the builtin i2c?

                            robert-hhR E 2 Replies Last reply Reply Quote 0
                            • robert-hhR Offline
                              robert-hh @SesamProductions
                              last edited by robert-hh

                              @SesamProductions For writing to a register, just append the data for the register to the address in a single write.
                              About @iotmaker's comment. The VL53L0X device he uses requires just an 1 byte address just like the memory devices.

                              1 Reply Last reply Reply Quote 0
                              • E Offline
                                Eric24 @SesamProductions
                                last edited by

                                @SesamProductions I'm afraid I don't have any more information on that library. But smbus is just the I2C library for whatever hardware platform it was written for. You should be able to substitute pycom's I2C functions readfrom_mem and writeto_mem for b.read_byte_data and b.write_byte_data, respectively. But note, I've never actually tried to access 16-bit addresses using pycom's I2C functions. If they don't work, please do submit a bug report, and in that case, you should be able to accomplish the same thing using the writeto and readfrom method that @robert-hh suggested earlier.

                                1 Reply Last reply Reply Quote 0
                                • S Offline
                                  SesamProductions
                                  last edited by

                                  Great! Now I'm starting to understand this a bit!
                                  I can read and write stuff using @robert-hh's suggestions, and the sensor seem to output correct data. Now I just have to modify my library with new read/write methods.

                                  Thanks a lot for the help!

                                  C 1 Reply Last reply Reply Quote 0
                                  • C Offline
                                    chumelnicu @iotmaker
                                    last edited by

                                    @iotmaker Hello , can u tell me please what is maximum distance range?

                                    1 Reply Last reply Reply Quote 0
                                    • C Offline
                                      chumelnicu @iotmaker
                                      last edited by

                                      @iotmaker Hi , did u read distance using vl53l0x with this code? Wrking and long distance too? i mean 200cm?
                                      Thx!

                                      1 Reply Last reply Reply Quote 0
                                      • ledbelly2142L Offline
                                        ledbelly2142
                                        last edited by ledbelly2142

                                        @chumelnicu
                                        It's in the specification of the sensor, see HERE that the VL6180X can measure up to 20 cm.

                                        The VL53L0X will measure up to 2 Meters (6.6Ft) away. You can see it on a breakout board HERE

                                        Friends don't let friends run with scissors

                                        C 1 Reply Last reply Reply Quote 0
                                        • C Offline
                                          chumelnicu @ledbelly2142
                                          last edited by

                                          @ledbelly2142 I know the diference between VL6180X and VL53L0X ! The question has target other response and was for @iotmaker

                                          I did asked him if he managed to read the VL53L0X in long range mode (that mean 200cm)

                                          1 Reply Last reply Reply Quote 0
                                          • C Offline
                                            chumelnicu @SesamProductions
                                            last edited by

                                            @sesamproductions Did u manage to read VL53LX0 in long distance mode?

                                            Thx!

                                            1 Reply Last reply Reply Quote 0

                                            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
                                            • 1 / 2
                                            • First post
                                              Last post

                                            Pycom on Twitter

                                            Pycom