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.4k 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.
    • 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
                              • J Offline
                                JasonTimmins @iotmaker
                                last edited by

                                @iotmaker Thanks for your code for the VL53L0X distance sensor. I've got the same configuration here and, although I can read the various registers you mention (Revision ID, Device ID, etc), I can't actually get a distance from the thing. VL53L0X_REG_RESULT_RANGE_STATUS is zero all the time and your 'distance' code gives zero too.

                                This looks like a fairly complex device, am I missing some kind of initialisation procedure?

                                Cheers
                                Jason.

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

                                  @JasonTimmins

                                  This is my full code

                                  just clean it up hehe

                                  from machine import UART
                                  from time import sleep_ms
                                  from network import Sigfox
                                  from machine import I2C
                                  import socket
                                  import pycom
                                  import re
                                  import binascii
                                  import ubinascii
                                  from machine import Pin
                                  import ustruct
                                  import time
                                  
                                  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
                                  
                                  
                                  ### Sigfox Stuff
                                  sigfox = Sigfox(mode=Sigfox.SIGFOX, rcz=Sigfox.RCZ2)
                                  
                                  # create a Sigfox socket
                                  s = socket.socket(socket.AF_SIGFOX, socket.SOCK_RAW)
                                  
                                  # print Sigfox Device ID
                                  print("Sigfox ID")
                                  print(binascii.hexlify(sigfox.id()))
                                  
                                  # print Sigfox PAC number
                                  print("Sigfox PAC")
                                  print(binascii.hexlify(sigfox.pac()))
                                  
                                  # make the socket blocking
                                  s.setblocking(True)
                                  
                                  # configure it as uplink only
                                  s.setsockopt(socket.SOL_SIGFOX, socket.SO_RX, False)
                                  
                                  #Sigfox Stuff
                                  pycom.heartbeat(False)
                                  ##RGB Colors
                                  red=0xff0000
                                  yellow=0xffff00
                                  green=0x00ff00
                                  blue=0x0000ff
                                  cyan=0x00feff
                                  purple=0xc442a1
                                  orange=0xff8b55
                                  dark=0x000000
                                  
                                  
                                  
                                  
                                  def ledtoggle(color):
                                      pycom.rgbled(color)
                                      sleep_ms(50)
                                      pycom.rgbled(dark)
                                      sleep_ms(50)
                                  
                                  def i2c_w(reg,val):
                                      i2c.writeto_mem(sensor,reg,bytes([val]))##Put device on standby mode
                                      sleep_ms(1)
                                  
                                  
                                  
                                  
                                  
                                  ## address 0x1D
                                  i2c = I2C(0)                         # create on bus 0
                                  i2c = I2C(0, I2C.MASTER)             # create and init as a master
                                  i2c.init(I2C.MASTER, baudrate=400000) # init as a master
                                  sleep_ms(30)
                                  
                                  print("I2C Scan for devices")
                                  print(i2c.scan())
                                  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))
                                  sleep_ms(30)
                                  print("")
                                  
                                  
                                  cnt=0
                                  val=0
                                  a=0
                                  while True:
                                  
                                      #print("Start Measuerment")
                                      i2c_w(VL53L0X_REG_SYSRANGE_START, 0x02)
                                  
                                      while (cnt < 100):
                                              #1 second waiting time max
                                  
                                          val=i2c.readfrom_mem(sensor,VL53L0X_REG_RESULT_RANGE_STATUS,1)
                                  
                                  
                                  
                                          if val==64:
                                              cnt=200
                                          cnt=cnt+1
                                  
                                      sleep_ms(30)
                                  
                                      datasensor=i2c.readfrom_mem(sensor,0x14,12)#Read sensor data
                                      distance=datasensor[10]*256+datasensor[11]#combine integers
                                      #print("distance")
                                      print(distance)
                                      if 100<=distance<=200:
                                              print('Sending Sigfox')
                                              s.send(bytes([datasensor[10], datasensor[11], 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]))
                                              ledtoggle(blue)
                                              ledtoggle(blue)
                                              ledtoggle(blue)
                                              ledtoggle(blue)
                                              print("By law it will sleep 20 seconds")
                                              time.sleep(20)
                                      ledtoggle(green)
                                      # for x in range(0,12):
                                      #     print(datasensor[x])
                                      #
                                      # print(datasensor)
                                  
                                      # print(datasensor[10])
                                      # print(datasensor[11])
                                      # print("")
                                      sleep_ms(1000)```
                                  J 1 Reply Last reply Reply Quote 0
                                  • J Offline
                                    JasonTimmins @iotmaker
                                    last edited by

                                    @iotmaker Thanks, that's got it working. I think I was missing...

                                    i2c_w(VL53L0X_REG_SYSRANGE_START, 0x02)

                                    It's now sitting here telling me how far my ceiling is above my desk!.. ~1690mm :-)

                                    I see a distance reading on 20mm quite often (30% of the time), why do you suppose that would be?

                                    Thanks again
                                    Jason.

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

                                      @jasontimmins

                                      Yes thats a bug i have on the code, have not dig into it yet on how to fix it.. But if you figure it out, please share :)

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

                                        @iotmaker , @JasonTimmins Maybe that could help

                                        https://github.com/adafruit/Adafruit_CircuitPython_VL53L0X/blob/master/adafruit_vl53l0x.py

                                        J 1 Reply Last reply Reply Quote 0
                                        • J Offline
                                          JasonTimmins @chumelnicu
                                          last edited by

                                          @chumelnicu This looks like a great library but I'm struggling to convert it to work on the Pycom device. Python is not my strong point. How different are Adafruit and Pycom devices?

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

                                            @jasontimmins Hi , I dont know i suppose is not very hard ... try to find similar conversions for other sensors from Adafruit i2c mode and apply to pycom microphyton ...

                                            Or maybe u should try to use i2c workflow from @iotmaker and rest of code and registers from Adafruit

                                            The single difference that i see is the i2c addressing mode.

                                            I dont know Python programming ...

                                            If u have any result pls share :)

                                            thx!

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

                                            Pycom on Twitter

                                            Pycom