Menu

VL53L0X Library - State of development

2020-05-13
2020-05-25
1 2 > >> (Page 1 of 2)
  • David Briscoe

    David Briscoe - 2020-05-13

    Hi,
    First time poster and user of GCBasic. I usually program PIC MCU's using CCS C compiler. I would like to try GCBasic to protype my code and then port it over to CCS (or vice versa as CCS has some cod that may work OK, I have yet to try it)
    Does this code from here

    https://github.com/Anobium/Great-Cow-BASIC-Library-Development/tree/master/VL53L0X

    work?

    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''
    '''@author
    '''@licence
    '''@version
    '''@date
    '''********************************************************************************
    
    ; ----- Configuration
          #chip mega328p,16
          #option explicit
    
    ; ----- Define Hardware settings
          ' Define I2C settings
          #define HI2C_BAUD_RATE 400
          #define HI2C_DATA PORTC.5
          #define HI2C_CLOCK PORTC.4
          'I2C pins need to be input for SSP module when used on Microchip device, so, uncomment if you port to a PIC
        '  Dir HI2C_DATA in
        '  Dir HI2C_CLOCK in
          HI2CMode Master
    
         ' THIS CONFIG OF THE SERIAL PORT WORKS WITH A  MAX232 (or equiv) THEN TO PC
         ' USART settings - CHANGE PORTS if required
         #define USART_BAUD_RATE 9600
         Dir PORTc.6 Out
         Dir PORTc.7 In
         #define USART_DELAY 5 ms
         #define SerSendDelayms 10
         #define USART_BLOCKING
    
    
    '''********************************************************************************
        'Wait post programming to connect terminal to USB port
        wait 2500 ms
        HSerPrintCRLF
        HSerPrint "Test sensor VL53L0x v20/02/19 by Anobium"
        HSerPrintCRLF 1
    
    '    #startup init_verVL53, 100
    
            HSerPrint "               Default      From Device"
            HSerPrintCRLF
        rd_byte_verVL53( VL53Dev, 0xC2, VL52ByteValue )
            HSerPrint "Revision ID     0x10           0x"
            HSerPrint hex(VL52ByteValue)
            HSerPrintCRLF
    
        rd_byte_verVL53( VL53Dev, 0xC0, VL52ByteValue )
            HSerPrint "Device ID       0xEE           0x"
            HSerPrint hex(VL52ByteValue)
            HSerPrintCRLF
    
        rd_byte_verVL53( VL53Dev, 0xC1, VL52ByteValue )
            HSerPrint "Address 0xC1    0xAA           0x"
            HSerPrint hex(VL52ByteValue)
            HSerPrintCRLF
    
        rd_word_verVL53( VL53Dev, 0x51, VL52WordValue )
            HSerPrint "Address 0x51    ????           0x"
            HSerPrint hex(VL52WordValue_h)
            HSerPrint hex(VL52WordValue)
            HSerPrintCRLF
    
        rd_word_verVL53( VL53Dev, 0x61, VL52WordValue )
            HSerPrint "Address 0x61    ????           0x"
            HSerPrint hex(VL52WordValue_h)
            HSerPrint hex(VL52WordValue)
            HSerPrintCRLF
    
    
    
    
        #define VL53Dev 0x52
        dim VL52ByteValue as byte
        dim VL52WordValue as word
    
    
        sub init_verVL53
    
        end sub
    
        sub rd_byte_verVL53( in VL53Dev as byte, in VL53Addr as byte, out VL53ByteVal as byte )
          ;read a single byte from an address
          #ifdef HI2C_DATA
              do
                HI2CReStart                              ;generate a start signal
                HI2CSend(VL53Dev)                       ;inidcate a write
              loop While HI2CAckPollState
              HI2CSend(VL53Addr)
              HI2CReStart
              HI2CSend(VL53Dev or 1)                   ;set the read flag
              HI2CReceive(VL53ByteVal, NACK)           ;read one byte and conclude
              HI2CStop
          #endif
    
          #ifdef I2C_DATA
              I2CStart                              ;generate a start signal
              I2CSend(VL53Dev)                       ;inidcate a write
              I2CSend(VL53Addr)
              I2CReStart
              I2CSend(VL53Dev or 1)                   ;set the read flag
              I2CReceive(VL53ByteVal, NACK)           ;read one byte and conclude
              I2CStop
              I2CAckPoll(VL53Dev)                ;wait for buffer write
          #endif
    
        end sub
    
    
        sub rd_word_verVL53( in VL53Dev as byte, in VL53Addr as byte, out VL53WordVal as word )
          ;read a single byte from an address
          #ifdef HI2C_DATA
              do
                HI2CReStart                              ;generate a start signal
                HI2CSend(VL53Dev)                       ;inidcate a write
              loop While HI2CAckPollState
              HI2CSend(VL53Addr)
              HI2CReStart
              HI2CSend(VL53Dev or 1)                   ;set the read flag
              HI2CReceive(VL53WordVal_h)           ;read one byte and conclude
              HI2CReceive(VL53WordVal, NACK)           ;read one byte and conclude
              HI2CStop
          #endif
    
          #ifdef I2C_DATA
              I2CStart                              ;generate a start signal
              I2CSend(VL53Dev)                       ;inidcate a write
              I2CSend(VL53Addr)
              I2CReStart
              I2CSend(VL53Dev or 1)                   ;set the read flag
              I2CReceive(VL53WordVal_h)           ;read one byte and conclude
              I2CReceive(VL53WordVal, NACK)           ;read one byte and conclude
              I2CStop
              I2CAckPoll(VL53Dev)                ;wait for buffer write
          #endif
    
        end sub
    

    I'm trying to prototype it on a PIC16F1847 but i'll try it on an Arduino UNO or Nano. I know I will have to change the port pins accordingly.

    Why is the subroutine init_verVL53 empty? How would I use this code to read a value from the VL53L0X?
    Thanks

    PS Sorry about the title. Tried to change it but cant. If someone CAN change it to "Does this VL53LOX code work" that would be good. Thanks

     

    Last edit: David Briscoe 2020-05-13
  • Anobium

    Anobium - 2020-05-13

    Welcome David,

    Re the github.com/Anobium/Great-Cow-BASIC-Library-Development/tree/master/VL53L0X code. It was a development that I have not found time to complete, however, the code you list is a prototype.

    As this is a development library the empty subroutine init_verVL53 is valid when this is moved into a Great Cow BASIC library. With Great Cow BASIC we can develop libraries as main line code then move across to a library - this ensure variable etc are all valid.

    To read a value use the methods:

    rd_byte_verVL53( I2C device address, memory address , TargetOutByteValue )
    rd_word_verVL53( I2C device address, memory address , TargetOutWordValue )
    

    Two examples where the constant VL53Dev equates to 0x53, and, constants 0xC1 & 0X51 are the addresses and the variables have been defined.
    ~~~

    rd_byte_verVL53( VL53Dev, 0xC1, VL52ByteValue )
    HSerPrint "Address 0xC1 0xAA 0x"
    HSerPrint hex(VL52ByteValue)
    HSerPrintCRLF

    rd_word_verVL53( VL53Dev, 0x51, VL52WordValue )
    HSerPrint "Address 0x51 ???? 0x"
    HSerPrint hex(VL52WordValue_h)
    HSerPrint hex(VL52WordValue)
    HSerPrintCRLF
    ~~~

    I guess that you can use this with other linkers not something I have time to do as I use Great Cow BASIC for all projects now.


    Hope this helps.

     
  • Anobium

    Anobium - 2020-05-13

    @David. I should add. I do not remember that state of the development. And, this will need testing. I cannot assure that this works.

     
  • George Towler

    George Towler - 2020-05-13

    I've used a couple of ST devices and they tend to be pretty good but they try to force you to use their API, I really don't know why.
    For example, to get good results from VL53bla you must install a bunch of Private settings that I have massive difficulties converting from C to basic.

     

    Last edit: George Towler 2020-05-13
    • Anobium

      Anobium - 2020-05-13

      @George. Not so sure it is so hard with Great Cow BASIC. If we can port the LUT tables for the e-Papers (which we large and seemingly complex) - I would expect these parts to be similar complexity. I have gathered up a number of good resources so get the job done.

      But, this sensor is low priority at the moment, for me. Getting the next release out is key.

       
  • stan cartwright

    stan cartwright - 2020-05-13

    Is this c?

    import smbus
    import struct
    import time
    
    def bswap(val):
        return struct.unpack('<H', struct.pack('>H', val))[0]
    def mread_word_data(adr, reg):
        return bswap(bus.read_word_data(adr, reg))
    def mwrite_word_data(adr, reg, data):
        return bus.write_word_data(adr, reg, bswap(data))
    def makeuint16(lsb, msb):
        return ((msb & 0xFF) << 8)  | (lsb & 0xFF)
    def VL53L0X_decode_vcsel_period(vcsel_period_reg):
    # Converts the encoded VCSEL period register value into the real
    # period in PLL clocks
        vcsel_period_pclks = (vcsel_period_reg + 1) << 1;
        return vcsel_period_pclks;
    
    
    
    VL53L0X_REG_IDENTIFICATION_MODEL_ID     = 0x00c0
    VL53L0X_REG_IDENTIFICATION_REVISION_ID      = 0x00c2
    VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD   = 0x0050
    VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD = 0x0070
    VL53L0X_REG_SYSRANGE_START          = 0x000
    
    VL53L0X_REG_RESULT_INTERRUPT_STATUS         = 0x0013
    VL53L0X_REG_RESULT_RANGE_STATUS         = 0x0014
    
    
    address = 0x29
    
    bus = smbus.SMBus(1)
    
    val1 = bus.read_byte_data(address, VL53L0X_REG_IDENTIFICATION_REVISION_ID)
    print "Revision ID: " + hex(val1)
    val1 = bus.read_byte_data(address, VL53L0X_REG_IDENTIFICATION_MODEL_ID)
    print "Device ID: " + hex(val1)
    #   case VL53L0X_VCSEL_PERIOD_PRE_RANGE:
    #       Status = VL53L0X_RdByte(Dev,
    #           VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD,
    #           &vcsel_period_reg);
    val1 = bus.read_byte_data(address, VL53L0X_REG_PRE_RANGE_CONFIG_VCSEL_PERIOD)
    print "PRE_RANGE_CONFIG_VCSEL_PERIOD=" + hex(val1) + " decode: " + str(VL53L0X_decode_vcsel_period(val1))
    
    
    #   case VL53L0X_VCSEL_PERIOD_FINAL_RANGE:
    #       Status = VL53L0X_RdByte(Dev,
    #           VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD,
    #           &vcsel_period_reg);
    
    val1 = bus.read_byte_data(address, VL53L0X_REG_FINAL_RANGE_CONFIG_VCSEL_PERIOD)
    print "FINAL_RANGE_CONFIG_VCSEL_PERIOD=" + hex(val1) + " decode: " + str(VL53L0X_decode_vcsel_period(val1))
    
    #       Status = VL53L0X_WrByte(Dev, VL53L0X_REG_SYSRANGE_START, 0x01);
    val1 = bus.write_byte_data(address, VL53L0X_REG_SYSRANGE_START, 0x01)
    
    #       Status = VL53L0X_RdByte(Dev, VL53L0X_REG_RESULT_RANGE_STATUS,
    #           &SysRangeStatusRegister);
    #       if (Status == VL53L0X_ERROR_NONE) {
    #           if (SysRangeStatusRegister & 0x01)
    #               *pMeasurementDataReady = 1;
    #           else
    #               *pMeasurementDataReady = 0;
    #       }
    cnt = 0
    while (cnt < 100): # 1 second waiting time max
        time.sleep(0.010)
        val = bus.read_byte_data(address, VL53L0X_REG_RESULT_RANGE_STATUS)
        if (val & 0x01):
            break
        cnt += 1
    
    if (val & 0x01):
        print "ready"
    else:
        print "not ready"
    
    #   Status = VL53L0X_ReadMulti(Dev, 0x14, localBuffer, 12);
    data = bus.read_i2c_block_data(address, 0x14, 12)
    print data
    print "ambient count " + str(makeuint16(data[7], data[6]))
    print "signal count " + str(makeuint16(data[9], data[8]))
    #       tmpuint16 = VL53L0X_MAKEUINT16(localBuffer[11], localBuffer[10]);
    print "distance " + str(makeuint16(data[11], data[10]))
    
    DeviceRangeStatusInternal = ((data[0] & 0x78) >> 3)
    print DeviceRangeStatusInternal
    
     
  • stan cartwright

    stan cartwright - 2020-05-13

    I found a picaxe basic version and tried unsuccessfully to convert it. Picaxe basic is commented out.

    ;vl53l0x converted from picaxe
    #chip mega328p, 16
    #option Explicit
    #define W_ADDRESS 0x52
    #define R_ADDRESS 0x53
    #define HI2C_BAUD_RATE 400
    #define HI2C_DATA PORTC.4
    #define HI2C_CLOCK PORTC.5
    HI2CMode Master
    
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING
    #define USART_DELAY 10 ms
    
    'VL53L0x Registers Write and Read
    'No.  Command Return value  Description
    '1    0XA0    BYTE1,BYTE2   Word output mode, the output distance is (BYTE1 < 8) &BYTE2;
    '                       the conversion to 10 is the actual measurement distance, the unit is mm
    '2    0XA1    BYTE1,BYTE2   VL53L0X initialization (initialization time is 500mS)
    '3    0XB0    0XB0      The module baud rate is set to 9600, and it takes effect in time (default)
    '4    0XB1    0XB1      The module baud rate is set to 19200, and it takes effect in time
    '5    0XB2    0XB2      The module baud rate is set to 115200, and it takes effect in time
    '6    0XC0    0XC0      Set up as a long distance measurement mode (default)
    '7    0XC1    0XC1      Set up as a high-speed measurement model
    '8    0XC2    0XC2      Set to high precision measurement mode (measurement interval is greater than 180mS)
    '9    0XD0    0XD0      Set XSHUT to high level, module work normally and initialize module
    '10         0XD1          0XD1      Setting XSHUT to low level, VL53L0X closes
    '11         0XF0            BYTE1--BYTE4          Current baud rate (MSB)
    '                     BYTE5  0X00 long distance mode                                                    0X01 high speed measurement mode
    '                            0X02 high precision measurement mode
    '                     BYTE6  The status of the current XSHUT
    dim da(12) as byte
    'Symbol Da1        = b10
    'Symbol Da2        = b11
    'Symbol Da3        = b12
    'Symbol Da4        = b13
    'Symbol Da5        = b14
    'Symbol Da6        = b15
    'Symbol Da7        = b16
    'Symbol Da8        = b17
    'Symbol Da9        = b18
    'Symbol Da10       = b19
    'Symbol Da11       = b20
    'Symbol Da12       = b21
    '
    'Symbol devError   = b22
    'Symbol datoVL   = b23
    'Symbol Distance   = w12
    'Symbol Signal   = w13
    'Symbol SPAD     = w14
    'Symbol Ambient    = w15
    dim devError,datoVL,tmp,addr,ctr as byte
    dim Distance,Signal,SPAD,Ambient as word
    
    ;hi2csetup I2CMASTER, $52, i2cfast, i2cbyte
    
    do
    ;  hi2cin $C0,(b0)
    ;HI2CStart
    ;HI2CSend(W_ADDRESS)
    
    ;HI2CReStart
    ;HI2CSend(W_ADDRESS+1)               ;indicate a read operation
    HI2CSend(0xc0)
    HI2CReceive tmp
    HI2CStop
    ;  sertxd (b0,cr,lf) ' EE
    hserprint str(tmp)
    ;  pause 10
    wait 10 ms
    
    ;  hi2cin $C1,(b0)
    HI2CStart
    ;HI2CSend(W_ADDRESS)
    
    ;HI2CReStart
    ;HI2CSend(W_ADDRESS+1)               ;indicate a read operation
    HI2CSend(0xc1)
    HI2CReceive tmp, NACK
    HI2CStop
    
    ;  sertxd (b0,cr,lf) ' AA
    hserprint str(tmp)
    ;  pause 10
    wait 10 ms
    
    ;  hi2cin $C2,(b0)
    HI2CStart
    ;HI2CSend(W_ADDRESS)
    
    ;HI2CReStart
    ;HI2CSend(W_ADDRESS+1)               ;indicate a read operation
    HI2CSend(0xc2)
    HI2CReceive tmp
    HI2CStop
    
    ;  sertxd (b0,cr,lf) ' 10
    hserprint str(tmp)
    ;  pause 1000
    wait 1 s
    
    ' Soft reset
    ;hi2cout $89,($01)
    HI2CStart
    ;hi2cSEND W_ADDRESS
    hi2cSEND 0x89
    hi2cSEND 1
    HI2CStop
    ;pause 200
    wait 200 ms
    
    
    'Sys range start
    ;hi2cout $00,($01)
    HI2CStart
    hi2cSEND W_ADDRESS
    hi2cSEND ( 0 )
    hi2cSEND ( 1 )
    HI2CStop
    ;pause 50
    
    
    'Read 12 raw data of Sensor:
    ;hi2cin $14,(da1,da2,da3,da4,da5,da6,da7,da8,da9,da10,da11,da12)
      HI2CStart
    'Request value
    HI2CSend(W_ADDRESS)
    
    ;HI2CReStart
    HI2CSend(W_ADDRESS+1)               ;indicate a read operation
    HI2CSend(0x14)
    For tmp=1 to 12
      HI2CReceive da( tmp ), ACK
    next tmp
    ;HI2CReceive da( 12  ), NACK
    HI2CStop
    
    ;sertxd (#da1," ",#da2," ",#da3," ",#da4," ",#da5," ",#da6," ",#da7," ",#da8," ",#da9," ",#da10," ",#da11," ",#da12,cr,lf)
    for ctr=1 to 12
      hserprint str(da(ctr))+" , "
    next ctr
    hserprintcrlf
    'Resolve sensor errors
    devError = (Da(1) and 0x78)/8 ;>> 3 ' // Check for errors
    hserprint "Status: "
    ;sertxd("Status: ")
    ;hserprint str(tmp)
    ;If devError = $00 Then  sertxd ("Data OK!") : endif  ' No device error
    If devError = 0 Then hserprint "Data OK!"
    ;If devError = $01 Then  sertxd ("VCSEL CONTINUITY TEST FAILURE!") : endif
    If devError = 1 Then hserprint "VCSEL CONTINUITY TEST FAILURE!"
    ;If devError = $02 Then  sertxd ("VCSEL WATCHDOG TEST FAILURE!") : endif
    If devError = 2 Then hserprint "VCSEL WATCHDOG TEST FAILURE!"
    ;If devError = $03 Then  sertxd ("NO VHV VALUE FOUND!") : endif
    If devError = 3 Then hserprint "NO VHV VALUE FOUND!"
    ;If devError = $04 Then  sertxd ("MSRC NO TARGET!") : endif
    If devError = 4 Then hserprint "MSRC NO TARGET!"
    ;If devError = $05 Then  sertxd ("SNR CHECK!") : endif
    If devError = 5 Then hserprint "SNR CHECK!"
    ;If devError = $06 Then  sertxd ("RANGE PHASE CHECK!") : endif
    If devError = 6 Then hserprint "RANGE PHASE CHECK!"
    ;If devError = $07 Then  sertxd ("SIGMA THRESHOLD CHECK!") : endif
    If devError = 7 Then hserprint "SIGMA THRESHOLD CHECK!"
    ;If devError = $08 Then  sertxd ("TCC!"): endif
    If devError = 8 Then hserprint "TCC!"
    ;If devError = $09 Then  sertxd ("PHASE CONSISTENCY!") : endif
    If devError = 9 Then hserprint "PHASE CONSISTENCY!"
    ;If devError = $0A Then  sertxd ("MIN CLIP!" ): endif
    If devError = 10 Then hserprint "MIN CLIP!"
    ;If devError = $0B Then  sertxd ("RANGE COMPLETE!") : endif
    If devError = 11 Then hserprint "RANGE COMPLETE!"
    ;If devError = $0C Then  sertxd ("ALGO UNDERFLOW!") : endif
    If devError = 12 Then hserprint "ALGO UNDERFLOW!"
    ;If devError = $0D Then  sertxd ("ALGO OVERFLOW!") : endif
    If devError = 13 Then hserprint "ALGO OVERFLOW!"
    ;If devError = $0E Then  sertxd ("RANGE IGNORE THRESHOLD!") : endif
    If devError = 14 Then hserprint "RANGE IGNORE THRESHOLD!"
    
    ;sertxd (" (",devError,")",cr,lf)
    hserprint "devError= "+str(devError)
    hserprintcrlf
    
    'Resolve info of sensor VL53L0x:
      'If devError = $00 or devError = $06 update Distance
      'If devError = $00 Or devError = $06Then
    Distance=Da(11)*256+Da(12)
    'endif
      'Effective SPAD Return Count
    SPAD = Da(3) + Da(4) /255
      'Signal Rate
    Signal = Da(7)*256+Da(8)
      'Ambient Rate
    Ambient= Da(9)*256+Da(10)
    
    'Send terminal info:
    ;sertxd ( "Distance: ", #Distance," mm",13,10 )
    hserprint "Distance: "+str(Distance)+" mm"
    hserprintcrlf
    ;sertxd ("Ambient ", #Ambient,"mc/s",13,10 )
    hserprint "Ambient "+str(Ambient)+" mc/s"
    hserprintcrlf
    ;sertxd ( "Signal Rate = ",#Signal,"mc/s",13,10 )
    hserprint "Signal Rate = "+str(Signal)+" mc/s"
    hserprintcrlf
    ;sertxd ( "SPAD = ",#SPAD,13,10 )
    hserprint "SPAD = "+str(SPAD)
    hserprintcrlf
    
    loop
    
     
    • Anobium

      Anobium - 2020-05-13

      Looks are GitHub please Stan. I have that source as a resource in the Resources folder.

       
  • stan cartwright

    stan cartwright - 2020-05-14

    Will do.
    I even have code for it written in proton basic, again trouble converting it.
    I'll try to find my v53l0x but think it is faulty...hence it being cheap.
    edit. found it and I can find it's rd/wr address.
    Was there ever a working version of the device measureing distance?

     

    Last edit: stan cartwright 2020-05-14
  • stan cartwright

    stan cartwright - 2020-05-16

    What would this picaxe be in gcb please?

    hi2csetup i2cmaster, 82, i2cfast, i2cbyte
    
    Then to trigger a cycle we set a bit in register 0x00:
    
    hi2cout 0x00,(0x01) ;trigger
    
    Then the distance in mm will be ready in registers 0x1E, 0x1F :
    
    hi2cin 0x1E,(b3,b2) ;read range in mm
    
    To convert from the two input bytes to word value w3:
    
    w3 = b3
    w3 = w3 * 256
    w3 = w3 | b2
    
     
  • Anobium

    Anobium - 2020-05-17

    @Stan. See the code https://github.com/Anobium/Great-Cow-BASIC-Library-Development/tree/master/VL53L0X ... this was in the first port. The PICAXE port is there.

     
    • stan cartwright

      stan cartwright - 2020-05-17

      Is that the code I tried to convert. The HI2C is wrong cos I did not understand it. It looks different to your read hi2c byte/word above.
      I found the last code on the picaxe forum from a a google search for v53l0x. it's recent.
      hi2csetup i2cmaster, 82, i2cfast, i2cbyte

      Then to trigger a cycle we set a bit in register 0x00:

      hi2cout 0x00,(0x01) ;trigger

      Then the distance in mm will be ready in registers 0x1E, 0x1F :

      hi2cin 0x1E,(b3,b2) ;read range in mm

       
  • mmotte

    mmotte - 2020-05-17

    @Stan, I took anobium's port and made it work, some. Certainly there is many loose ends and one of them is the index on the da array, it seems to be one off, lost it somewhere and for now I just adjusted the prints to align. But this does send the measuement , signal strength and ambient light strength. It is uncalibrated and measurement seems ~50mm long but changes nicely as you move the target. Sometimes it sends 20mm which must be the default low value when it looses the target.

    My chinese board is CJVL53L0XV2 and runs on 5v , and has the voltage translators and voltage regulator. I used no pullups on the I2C lines and did not do anything with the GPIO1 ,XSHUT pins

    6 , 92 , 0 , 255 , 255 , 10 , 211 , 0 , 3 , 0 , 200 , 0 , 
    Status: Data OK!devError= 0
    Distance: 200 mm
    Ambient 3 mc/s
    Signal Rate = 2771 mc/s
    SPAD = 92
    6 , 96 , 0 , 255 , 255 , 10 , 166 , 0 , 3 , 0 , 202 , 0 , 
    Status: Data OK!devError= 0
    Distance: 202 mm
    Ambient 3 mc/s
    Signal Rate = 2726 mc/s
    SPAD = 96
    
    ;vl53l0x converted from picaxe
    #chip 16F886,8
    #option Explicit
    #define W_ADDRESS 0xEC
    #define R_ADDRESS 0xED
    #define VL53Dev 0x52
    
    #define HI2C_BAUD_RATE 400
    #define HI2C_DATA PORTC.5
    #define HI2C_CLOCK PORTC.4
    HI2CMode Master
    
    #define USART_BAUD_RATE 9600
    #define USART_TX_BLOCKING
    #define USART_DELAY 1 ms
    
    dim VL52ByteValue as byte
    dim VL52WordValue as word
    dim DATABUFFER_POINTER as byte
    
    
    'VL53L0x Registers Write and Read
    'No.  Command Return value  Description
    '1    0XA0    BYTE1,BYTE2   Word output mode, the output distance is (BYTE1 < 8) &BYTE2;
    '                       the conversion to 10 is the actual measurement distance, the unit is mm
    '2    0XA1    BYTE1,BYTE2   VL53L0X initialization (initialization time is 500mS)
    '3    0XB0    0XB0      The module baud rate is set to 9600, and it takes effect in time (default)
    '4    0XB1    0XB1      The module baud rate is set to 19200, and it takes effect in time
    '5    0XB2    0XB2      The module baud rate is set to 115200, and it takes effect in time
    '6    0XC0    0XC0      Set up as a long distance measurement mode (default)
    '7    0XC1    0XC1      Set up as a high-speed measurement model
    '8    0XC2    0XC2      Set to high precision measurement mode (measurement interval is greater than 180mS)
    '9    0XD0    0XD0      Set XSHUT to high level, module work normally and initialize module
    '10         0XD1          0XD1      Setting XSHUT to low level, VL53L0X closes
    '11         0XF0            BYTE1--BYTE4          Current baud rate (MSB)
    '                     BYTE5  0X00 long distance mode                                                    0X01 high speed measurement mode
    '                            0X02 high precision measurement mode
    '                     BYTE6  The status of the current XSHUT
    dim da(14) as byte
    'Symbol Da1        = b10
    'Symbol Da2        = b11
    'Symbol Da3        = b12
    'Symbol Da4        = b13
    'Symbol Da5        = b14
    'Symbol Da6        = b15
    'Symbol Da7        = b16
    'Symbol Da8        = b17
    'Symbol Da9        = b18
    'Symbol Da10       = b19
    'Symbol Da11       = b20
    'Symbol Da12       = b21
    '
    'Symbol devError   = b22
    'Symbol datoVL   = b23
    'Symbol Distance   = w12
    'Symbol Signal   = w13
    'Symbol SPAD     = w14
    'Symbol Ambient    = w15
    dim devError,datoVL,tmp,addr,ctr as byte
    dim Distance,Signal,SPAD,Ambient as word
    
    ;hi2csetup I2CMASTER, $52, i2cfast, i2cbyte
    
    'do
    ;  hi2cin $C0,(b0)
        rd_byte_verVL53( VL53Dev, 0xC0, VL52ByteValue )
        HSerPrint "Device ID       0xEE           0x"
        HSerPrint hex(VL52ByteValue)
        HSerPrintCRLF
        wait 10 ms
    
    ;  hi2cin $C1,(b0)
        rd_byte_verVL53( VL53Dev, 0xC1, VL52ByteValue )
        HSerPrint "Address 0xC1    0xAA           0x"
        HSerPrint hex(VL52ByteValue)
        HSerPrintCRLF
        wait 10 ms
    
    ;  hi2cin $C2,(b0)
        rd_byte_verVL53( VL53Dev, 0xC2, VL52ByteValue )
        HSerPrint "Revision ID     0x10           0x"
        HSerPrint hex(VL52ByteValue)
        HSerPrintCRLF
        wait 1 s
    
    ' Soft reset
    'hi2cout $89,($01)
        wr_byte_VL52 ( VL53Dev,0x89,  0x01 )
    
        wait 200 ms
    do
    'Sys range start
    ';hi2cout $00,($01)
        wr_byte_VL52 ( VL53Dev,0x00,  0x01 )
    
    
    
    
    'Read 12 raw data of Sensor:
    ;hi2cin $14,(da1,da2,da3,da4,da5,da6,da7,da8,da9,da10,da11,da12)
    rd_multi_verVL53  ( VL53Dev, 0x14, 12, Da() )
    
    ;sertxd (#da1," ",#da2," ",#da3," ",#da4," ",#da5," ",#da6," ",#da7," ",#da8," ",#da9," ",#da10," ",#da11," ",#da12,cr,lf)
    for ctr=1 to 12
      hserprint str(da(ctr))+" , "
    next ctr
    hserprintcrlf
    
    'Resolve sensor errors
    devError = (Da(1) and 0x78)/8 ;>> 3 ' // Check for errors
    hserprint "Status: "
    ;sertxd("Status: ")
    ;hserprint str(tmp)
    ;If devError = $00 Then  sertxd ("Data OK!") : endif  ' No device error
    If devError = 0 Then hserprint "Data OK!"
    ;If devError = $01 Then  sertxd ("VCSEL CONTINUITY TEST FAILURE!") : endif
    If devError = 1 Then hserprint "VCSEL CONTINUITY TEST FAILURE!"
    ;If devError = $02 Then  sertxd ("VCSEL WATCHDOG TEST FAILURE!") : endif
    If devError = 2 Then hserprint "VCSEL WATCHDOG TEST FAILURE!"
    ;If devError = $03 Then  sertxd ("NO VHV VALUE FOUND!") : endif
    If devError = 3 Then hserprint "NO VHV VALUE FOUND!"
    ;If devError = $04 Then  sertxd ("MSRC NO TARGET!") : endif
    If devError = 4 Then hserprint "MSRC NO TARGET!"
    ;If devError = $05 Then  sertxd ("SNR CHECK!") : endif
    If devError = 5 Then hserprint "SNR CHECK!"
    ;If devError = $06 Then  sertxd ("RANGE PHASE CHECK!") : endif
    If devError = 6 Then hserprint "RANGE PHASE CHECK!"
    ;If devError = $07 Then  sertxd ("SIGMA THRESHOLD CHECK!") : endif
    If devError = 7 Then hserprint "SIGMA THRESHOLD CHECK!"
    ;If devError = $08 Then  sertxd ("TCC!"): endif
    If devError = 8 Then hserprint "TCC!"
    ;If devError = $09 Then  sertxd ("PHASE CONSISTENCY!") : endif
    If devError = 9 Then hserprint "PHASE CONSISTENCY!"
    ;If devError = $0A Then  sertxd ("MIN CLIP!" ): endif
    If devError = 10 Then hserprint "MIN CLIP!"
    ;If devError = $0B Then  sertxd ("RANGE COMPLETE!") : endif
    If devError = 11 Then hserprint "RANGE COMPLETE!"
    ;If devError = $0C Then  sertxd ("ALGO UNDERFLOW!") : endif
    If devError = 12 Then hserprint "ALGO UNDERFLOW!"
    ;If devError = $0D Then  sertxd ("ALGO OVERFLOW!") : endif
    If devError = 13 Then hserprint "ALGO OVERFLOW!"
    ;If devError = $0E Then  sertxd ("RANGE IGNORE THRESHOLD!") : endif
    If devError = 14 Then hserprint "RANGE IGNORE THRESHOLD!"
    
    ;sertxd (" (",devError,")",cr,lf)
    hserprint "devError= "+str(devError)
    hserprintcrlf
    
    'Resolve info of sensor VL53L0x:
      'If devError = $00 or devError = $06 update Distance
      'If devError = $00 Or devError = $06Then
    Distance=Da(10)*256+Da(11)
    'endif
      'Effective SPAD Return Count
    SPAD = Da(2) + Da(3) /255
      'Signal Rate
    Signal = Da(6)*256+Da(7)
      'Ambient Rate
    Ambient= Da(8)*256+Da(9)
    
    'Send terminal info:
    ;sertxd ( "Distance: ", #Distance," mm",13,10 )
    hserprint "Distance: "+str(Distance)+" mm"
    hserprintcrlf
    ;sertxd ("Ambient ", #Ambient,"mc/s",13,10 )
    hserprint "Ambient "+str(Ambient)+" mc/s"
    hserprintcrlf
    ;sertxd ( "Signal Rate = ",#Signal,"mc/s",13,10 )
    hserprint "Signal Rate = "+str(Signal)+" mc/s"
    hserprintcrlf
    ;sertxd ( "SPAD = ",#SPAD,13,10 )
    hserprint "SPAD = "+str(SPAD)
    hserprintcrlf
    wait 5 s
    loop
    
      sub rd_byte_verVL53( in VL53Dev as byte, in VL53Addr as byte, out VL53ByteVal as byte )
          ;read a single byte from an address
          #ifdef HI2C_DATA
              HI2CStart
              HI2CSend(VL53Dev)
              HI2CSend(VL53Addr)
              HI2CReStart
              HI2CSend(VL53Dev or 1)                   ;set the read flag
              HI2CReceive(VL53ByteVal, NACK)           ;read one byte and conclude
              HI2CStop
          #endif
    
          #ifdef I2C_DATA
              I2CStart                              ;generate a start signal
              I2CSend(VL53Dev)                       ;inidcate a write
              I2CSend(VL53Addr)
              I2CReStart
              I2CSend(VL53Dev or 1)                   ;set the read flag
              I2CReceive(VL53ByteVal, NACK)           ;read one byte and conclude
              I2CStop
              I2CAckPoll(VL53Dev)                ;wait for buffer write
          #endif
    
        end sub
    
    
        sub rd_word_verVL53( in VL53Dev as byte, in VL53Addr as byte, out VL53WordVal as word )
          ;read a single byte from an address
          #ifdef HI2C_DATA
              HI2CStart
              HI2CSend(VL53Dev)
              HI2CSend(VL53Addr)
              HI2CReStart
              HI2CSend(VL53Dev or 1)                   ;set the read flag
              HI2CReceive(VL53WordVal_h)           ;read one byte and conclude
              HI2CReceive(VL53WordVal, NACK)           ;read one byte and conclude
              HI2CStop
          #endif
    
          #ifdef I2C_DATA
              I2CStart                              ;generate a start signal
              I2CSend(VL53Dev)                       ;inidcate a write
              I2CSend(VL53Addr)
              I2CReStart
              I2CSend(VL53Dev or 1)                   ;set the read flag
              I2CReceive(VL53WordVal_h)           ;read one byte and conclude
              I2CReceive(VL53WordVal, NACK)           ;read one byte and conclude
              I2CStop
              I2CAckPoll(VL53Dev)                ;wait for buffer write
          #endif
    
        end sub
    
        sub rd_multi_verVL53  ( in VL53Dev as byte, in VL53Addr as byte,  in  NumOfByteData as byte, out DataBuffer() )
          'NumOfByteData--
          #ifdef I2C_DATA
              I2CStart
              I2CSend(VL53Dev)                 ;Send address
              I2CSend(VL53Addr)
              I2CReStart
              I2CSend(VL53Dev+1)               ;indicate a read operation
              For DataBuffer_Pointer = 0 to (NumOfByteData -1)
                  I2CReceive DataBuffer( DataBuffer_Pointer), ACK
              next
              I2CReceive BME280_DataBuffer( NumOfByteData ) , NACK
              I2CStop
          #endif
    
          #ifdef HI2C_DATA
              HI2CStart
              HI2CSend(VL53Dev)
              HI2CSend(VL53Addr)
              HI2CReStart
              HI2CSend(VL53Dev+1)               ;indicate a read operation
    
              For DataBuffer_Pointer = 0 to (NumOfByteData -1)
                  HI2CReceive DataBuffer( DataBuffer_Pointer), ACK
              next
              HI2CReceive DataBuffer( NumOfByteData   ), NACK
              HI2CStop
          #endif
    
    end sub
    
    
    
    
    sub wr_byte_VL52 ( in VL52Dev as byte, in VL52Address as byte,  in VL52_SendByte as byte )
    
          #ifdef I2C_DATA
              I2CStart
              I2CSend(VL52Dev)                 ;Send address
              I2CSend(VL52Address)
              I2CSend(VL52_SendByte)           ;Send data
              I2CStop
          #endif
    
          #ifdef HI2C_DATA
              HI2CStart
              HI2CSend(VL52Dev)
              HI2CSend(VL52Address)
              HI2CSend(VL52_SendByte)
              HI2CStop
          #endif
    
    end sub
    
     
  • stan cartwright

    stan cartwright - 2020-05-17

    Thanks, it seems to work. I get a varying distance to object.
    Had to dim NumOfByteData using option explicit
    Thank you mmotte for converting the hi2c from picaxe...I knew I did it wrong...to think that was all needed to get a result.
    Least I can experiment. Nice one.
    David Briscoe try it. All feedback for this device interesting.
    Thanks again, best bit of code for ages. Do you have one of these devices mmotte?
    Though Anobium would have pointed out the read byte stuff needed. Busy.

     

    Last edit: stan cartwright 2020-05-17
  • mmotte

    mmotte - 2020-05-18

    about line 113 - change Da(1) to Da(0) and this will give the correct status

    it is more a staus than errors .

    devError = (Da(0) and 0x78)/8  ' // Check for errors
    

    TCC is Target Center Check

     
    • stan cartwright

      stan cartwright - 2020-05-18

      There is no Da(0).
      Gcb arrays start at 1

       
  • mmotte

    mmotte - 2020-05-18

    It exists!

     
    • stan cartwright

      stan cartwright - 2020-05-20

      From Chris Roper
      To Quote Anobium: "You can use element 0. Help tries to clarify that element 0 does hold the length of the array but only when less than 255 elements.... hence, as a general rule do not use element 0 as the array length."

      Now I am confused too :)

      A) You Can use Element 0.
      B) Element 0 holds the length of the array.
      C) As a general rule do not use element 0 as the array length.

      So how do we not use element 0 as the length of the array?
      Should we define all arrays to be greater than 255 elements to meet criteria C?

      Should it read you MAY NOT use Element 0 UNLESS your array is greater than 255 elements?

      What happened to the #Option Radix statement we discussed a while ago, specifically to avoid future confusion like this?

      Cheers
      Chris

       
      • Anobium

        Anobium - 2020-05-20

        I can only try to clarify.

        You can use element 0. Help tries to clarify that element 0 does hold the length of the array but only when less than 255 elements.... hence, as a general rule do not use element 0 as the array length - just make sure you know the number of elements in the array.

        You can use element 0 - see previous paragraph.
        Element 0 holds the length of the array - see previous paragraph.
        As a general rule do not use element 0 as the array length - if there are more than 255 elements.

        So how do we not use element 0 as the length of the array?

        I am confused by your question. Element 0 as the length of the array when the array has less than 255 elements.

        Should we define all arrays to be greater than 255 elements to meet criteria C?

        Dont know the answer as this is really odd question. This is not hard. Specify the size of the array using a Constant. Use the Constant if you need the size of the array. Then, you do not need to read or worry about element. Regarding defining all arrays with 255 elements. No sure that that approach is the best use of RAM.

        Should it read you MAY NOT use Element 0 UNLESS your array is greater than 255 elements?

        I guess so. Someone can update the Help? I am not sure where the source of the statement is. Someone can update the Help?

        What happened to the #Option Radix statement we discussed a while ago, specifically to avoid future confusion like this?

        The impact of #Option Radix was assessed by Hugh. The impact was to high. All of the libraries would need to reviewed. All of them and there was some other issue raised.

         
    • stan cartwright

      stan cartwright - 2020-05-20

      I tried changing

      For DataBuffer_Pointer = 0 to (NumOfByteData -1)
      

      to

      For DataBuffer_Pointer = 1 to (NumOfByteData)
      

      and get NumOfByteData not explicitly declared.

      In sub rd_multi_verVL53 ( in VL53Dev as byte, in VL53Addr as byte, in NumOfByteData as byte, out DataBuffer() ),
      does da() correspond to DataBuffer() ie does da() start at 0 ?
      If devError = (Da(0) and 0x78)/8
      then is Distance=Da(9)256+Da(10) now? it was da(10)256+da(11)

       
  • Anobium

    Anobium - 2020-05-20

    As do not really remember the VL code. I don't.

    I just looked at it.

    The array da() is being used as a buffer. Therefore, the reading of the length is not used.

    Let us review the code.

    dim da(14) as byte The array is defined using a constant.

    rd_multi_verVL53 ( VL53Dev, 0x14, 12, Da() ) the method rd_multi_verVL53 is called passing the da() array as the buffer. Oddly, the constant 12 is passed to inform the method of the size of the buffer - this is clearly wasting 2 bytes....

    The FOR-NEXT loop in the method For DataBuffer_Pointer = 0 to (NumOfByteData -1) then uses element 0 to 11 as the buffer.....

    In the context that this was ported from PICAXE and this is not a released library... we can take away that the buffer should be defined by a constant and that constant should be reused. As in...

    'Somehing like
    #DEFINE BUFFERSIZE = 11
    dim da(BUFFERSIZE) as byte '
    ....
    rd_multi_verVL53  ( VL53Dev, 0x14, BUFFERSIZE , Da() )
    ....
    For DataBuffer_Pointer = 0 to NumOfByteData
    
     
  • mmotte

    mmotte - 2020-05-20

    @stan

    I am sorry that this is a problem for you. I have programmed in many languages and arrays always had '0' elements because computers count from zero. Yes you can pretend it don't exist.

    strings in gcb basic are arrays with the length of the string in the 0th element. this is a special case /use of an array used in gcb.

    I have adjusted the program so the element of the status is '1'.
    Attached is the newer file.

    I have worked on the arduino adaptation porting to gcb but only get it to work intermitently. Also it uses floats for some of the computations which makes them harder to figure.

    Also experimenting with module, i can only get about 1200 mm range . Here again the parameter to adjust is a float. 0.25 > 0.1.

     

    Last edit: mmotte 2020-05-20
    • stan cartwright

      stan cartwright - 2020-05-20

      This new code gives error
      edit it does not seem to work ie error and distance
      Looks cool on arduino youtube using c sketches.
      It was me who got picaxe to write code and it has no floats so thought code would be portable to gcb.
      Thanks again mmotte for sharing your code.
      I am reading the distance on a glcd cos the terminal was a chore

       

      Last edit: stan cartwright 2020-05-20
  • Anobium

    Anobium - 2020-05-20

    I will have to try this new code!! I clearly never finished the program as it was in the development library.

    But, now it works.. should be easy.

     
    • stan cartwright

      stan cartwright - 2020-05-20

      "now it works" maybe not but we have , is it your , read/write regs and some values.
      The c versions use floats. I don't see a practical way around this so try to find alternatative solutions.
      I would not bother with this as a priority. It could be nice if working.
      For distance the ultra sonic is better from experience.
      I tried a sharp 2YOA21....not reliable I thought..disappointed

       
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.