Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:14 26 Nov 2024 Privacy Policy
Jump to

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: Australia
Posts: 6098
Posted: 07:38am 10 Feb 2024
Copy link to clipboard 
Print this post



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
   PRINT
 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 Kingdom
Posts: 858
Posted: 04:38pm 10 Feb 2024
Copy link to clipboard 
Print this post

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: Australia
Posts: 6098
Posted: 07:43pm 10 Feb 2024
Copy link to clipboard 
Print this post

  PhenixRising said  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.


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 Kingdom
Posts: 2129
Posted: 01:00am 11 Feb 2024
Copy link to clipboard 
Print this post

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


To reply to this topic, you need to log in.

© JAQ Software 2024