Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Swipe Right
Author | Message | ||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6098 |
I have been playing with multiple VL53LOX range finder modules. The following program is intended as a contactless switch - very Covid friendly. 2 modules are connected to the same I2C bus. I used I2C2 but whatever suits. One module has its XSHUT pin connected to the pico. To change the address of one of the modules, the one with the XSHUT connected has the pin pulled low to inhibit it . The other module then gets a new address and the first module released. We now have two modules with different addresses. This can be expanded as far as you like. The rangefinders are read every 50mS and then the rest of the code determines if you are swiping left or right. You can also hold a hand close to either module for a simple up/down control. If you want to upset the cat, a pair of tom-toms may be another use. My initial use will be for a radio control, swiping to change stations and tapping to change volume. This allows me to control the radio in the shed with oily/grubby fingers or gloves etc. A video of it in action is on my website https://www.c-com.com.au/stuff/swipe.mp4 'VL53LOX OPTION EXPLICIT OPTION DEFAULT NONE DIM INTEGER dst(2) DIM INTEGER pos_L,pos_R, pingNow,tap_pos = 120 DIM INTEGER hit_L, hit_R, lockout, rdy DIM zoneL$, zoneR$, zoneLx$, zoneRx$ CONST i2caddr=&H29 CONST vl53LOX_reset = 22 'gp17 CONST tap = 100 CONST near = 300 SETPIN GP19,GP18,I2C2 I2C2 OPEN 400,1000 SETPIN vl53LOX_reset, DOUT SETPIN GP20, DOUT PIN(vl53LOX_reset) = 0 ' inhibit the RH module while we change the address of the LH set_address 1 PIN(vl53LOX_reset) = 1 scanner ' just to confirm thata we now have two addresses ' initialise modules I2C2 WRITE i2caddr+1,0,2,&H89,&H1 IF MM.I2C THEN PRINT "Li",MM.I2C I2C2 WRITE i2caddr ,0,2,&H89,&H1 IF MM.I2C THEN PRINT "Ri",MM.I2C CLS ' start readings in continuous mode I2C2 WRITE i2caddr ,0,2,0,2 I2C2 WRITE i2caddr+1,0,2,0,2 SETTICK 50, ping DO IF pingNow THEN pingIt LOOP ' SUB ping 'pin(gp20) = 1 pos_R = get_distance(0) IF MM.I2C THEN PRINT "R",MM.I2C pos_L = get_distance(1) IF MM.I2C THEN PRINT "L",MM.I2C 'pin(gp20) = 0 pingNow = 1 END SUB SUB pingIt pingNow = 0 IF pos_L > 1000 THEN pos_L = 0 IF pos_R > 1000 THEN pos_R = 0 zoneL$ = zone$(pos_L) zoneR$ = zone$(pos_R) hit_R = INSTR(zoneRx$,"B") hit_L = INSTR(zoneLx$,"B") zoneLx$ = zoneL$+LEFT$(zoneLx$,5) zoneRx$ = zoneR$+LEFT$(zoneRx$,5) TEXT 20,100,STR$(pos_L,4,0), lm,3,1 TEXT 240,100,STR$(pos_R,4,0), lm,3,1 ' for a swwipe the opposite sensor must record a hit in the last 6 reads ' but not still registering IF zoneL$="B" AND INSTR(zoneRx$,"B")> 1 THEN swipe_left IF zoneR$="B" AND INSTR(zoneLx$,"B")> 1 THEN swipe_right ' for a tap, we want two consecutive triggers IF zoneL$="A" AND MID$(zoneLx$,2,1)="A" THEN tap_Left IF zoneR$="A" AND MID$(zoneRx$,2,1)="A" THEN tap_right END SUB FUNCTION zone$(x%) SELECT CASE x% CASE IS < 50 zone$="_" CASE IS < tap zone$="A" CASE IS < near zone$ = "B" CASE ELSE zone$= "_" END SELECT END FUNCTION FUNCTION get_distance(dev AS INTEGER) AS INTEGER PIN(GP20) = 1 I2C2 WRITE i2caddr+dev,1,1,&H1E I2C2 READ i2caddr+dev,0,2,dst() I2C2 WRITE i2caddr+dev,0,2,&H0B,1 get_distance = (dst(0)<<8) + dst(1) '- 20 PIN(GP20) = 0 END FUNCTION SUB set_address dev AS INTEGER I2C2 WRITE i2caddr,0,2,&h8A, i2caddr +dev AND &h7F IF MM.I2C THEN PRINT "set",MM.I2C END SUB SUB scanner LOCAL INTEGER x,y, addr PRINT "System I2C Address Scanner" ' Prep table PRINT " 0 1 2 3 4 5 6 7 8 9 A B C D E F" ' loop col/row FOR y=0 TO 7 PRINT HEX$(y,2);": "; FOR x=0 TO 15 addr = y*16+x ' calc address I2C2 WRITE addr, 0, 1, &H00 ' write zerp to that adress IF MM.I2C=0 THEN ' check for errors PRINT HEX$(addr,2);" "; ' found one! ELSE PRINT "-- "; ' nothing here.. ENDIF NEXT x NEXT y END SUB SUB tap_Left PRINT "Tap Left",pos_L tap_pos = tap_pos - 2 BOX 140,0,40,240,1,RGB(BLUE),RGB(BLUE) BOX 140,240-tap_pos,40,tap_pos,1,RGB(YELLOW),RGB(YELLOW) END SUB SUB tap_right PRINT "Tap Right",pos_R tap_pos = tap_pos + 2 BOX 140,0,40,240,1,RGB(BLUE),RGB(BLUE) BOX 140,240-tap_pos,40,tap_pos,1,RGB(YELLOW),RGB(YELLOW) END SUB SUB swipe_right IF lockout < TIMER THEN lockout = TIMER + 500 CLS RGB(GREEN) BOX 140,0,40,240,1,RGB(BLUE),RGB(BLUE) BOX 140,240-tap_pos,40,tap_pos,1,RGB(YELLOW),RGB(YELLOW) PRINT "Swipe Right ";ZONELx$,pos_R ENDIF END SUB SUB swipe_left IF lockout < TIMER THEN lockout = TIMER + 500 CLS RGB(RED) BOX 140,0,40,240,1,RGB(BLUE),RGB(BLUE) BOX 140,240-tap_pos,40,tap_pos,1,RGB(YELLOW),RGB(YELLOW) PRINT "Swipe Left ";ZONERx$,pos_L ENDIF END SUB There are lots of PRINT statements which are only for development and can be eliminated. The I2C scanner is only there to prove the change of address. pin GP20 is connected to the CRO for timing measurements. Jim Edited 2024-02-10 17:41 by TassyJim VK7JH MMedit MMBasic Help |
||||
PhenixRising Guru Joined: 07/11/2023 Location: United KingdomPosts: 858 |
Have you tested the accuracy/repeatabilty of displacement sensing, Jim? I have one of these somewhere but didn't get around to playing with it yet. |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6098 |
Repeatability is good. I used the modules as is without any calibration so the results are not perfect. I will play with calibration when time permits but for now, they are reliable enough for this purpose. When I start putting the sensors behind a window, I am sure that calibration will be needed. In the program, anything closer than a nominal 50mm is too close and ignored, from 50 to 100 mm is considered a 'tap' and from 100 to 300mm is in the zone for 'swiping' The true distances are about 20mm closer and I should be subtracting that 20mm from the returned values. I decided to leave the values as reported and adjusted the program to suit. I did find a few stray readings that upset things and I had to allow for them. I was concerned that there would be some interaction between the two modules but that doesn't seem to be a problem. It might be with 4 modules in use. The sensors have a narrow beam and that can be a good thing but also a problem for some uses. They also take about 30mS for a reading so I put them into continuous mode and make use of the most recent results which could be 30mS behind the times. That way it is only 1mS to get both readings. Jim VK7JH MMedit MMBasic Help |
||||
stanleyella Guru Joined: 25/06/2022 Location: United KingdomPosts: 2129 |
I used one on a robot but also distance displayed on ssd1306 oled same i2c. interesting you got 2 working.They're ok 100mm to 800mm accurate to 10mm. |
||||
Print this page |