Project - Pan & Tilt

This is a double-ended project.
It is a software virtual proportional dual-axis Joystick.
And it is also a hardware Pan & Tilt servo platform.
They go well together, but either could be used by itself.
Accordingly, even though the first script has the capability to control servos, it has been commented out.
Therefore the dual-axis virtual joystick is provided with horizontal and vertical indicators to show X, Y positions.
These pan and tilt gauges have a checkbox underneath allowing auto-self-centering to be turned On or Off.

A short demo shows the servos being controlled by the second script:  LibraryYouTube
The javascript joystick library has a 'sticky knob' (seriously), therefore click the knob to un-stick the cursor.
Evidently it is 'touch-enabled', which should be handy for use on phone touchscreens etc, but I haven't tried.that.
If the auto-self-centering knob returns too quickly to register on the X.Y gauges, simply click the knob to update.

For anyone not using servos, the javascript actually returns center-zero and -100 to +100 values for each axis.
The script then 'normalises' the returned values to between 0 to 180 to be suitable for actuating the servos.
It also has simple facility to reverse the value from 180 to 0 to reverse the servo direction of travel if needed

Read joy$ from in action: branch if you wish to intercept the returned X,Y string values before they are 'normalised' for servo use.
 wlog joy$
 X=val(word$(joy$,1,",")) +100   
 Y=val(word$(joy$,2,",")) +100
 pan = X/200*180
 tilt   = Y/200*180
 'pan = 180-pan               'uncomment to invert value for reversing direction of travel 
 'tilt = 180-tilt                   'uncomment to invert value for reversing direction of travel 

The javascript file "joy_cb.min.js.gz" should be downloaded from the bottom of this page then uploaded to the root / of your device,

Note: It is best to re-start Annex with a clean slate to avoid 'out of memory' overloads or lost web-socket connections.
.
Basic:
'Virtual Proportional Joystick - Electroguard - developed on Annex 1.41 beta 6
jsexternal "/joy_cb.min.js"
'servo.setup 1,13               'uncomment if using a servo
'servo.setup 2,12               'uncomment if using a servo
X=0
Y=0
pan=90
tilt=90
autoCenter=0                    '1=auto-return to center, 0=remain unchanged
joy$=""
if autoCenter=1 then autoCenter$="true" else autoCenter$="false"
htmleventvar$=""
onHtmlChange action
gosub action
gosub screen
wait

screen:
cls
a$ = ""
a$ = a$ + |<div style='display: table; margin-right: auto; margin-left: auto;'>|
a$ = a$ + |<br><br>|
a$ = a$ + meter$(tilt,0,180,"tilt") + |<br>|
a$ = a$ + cssid$("tilt","transform: rotate(-90deg);width:90px;")
a$ = a$ + |<br><br>|
a$ = a$ + meter$(pan,0,180,"pan") '+ |<br>|
a$ = a$ + cssid$("pan","width:90px;")
a$ = a$ + |</div>|
a$ = a$ + |<div style='display: table; margin-right: auto; margin-left: auto;opacity:'>|
a$ = a$ + checkbox$(autoCenter)
a$ = a$ + |</div>|
a$ = a$ + |<div style='display: table; margin-right: auto; margin-left: auto;'>|
a$ = a$ + |<div id="joyDiv" style="width:200px;height:200px;margin-bottom:20px;margin:20px;"></div></div>|
autorefresh 100
html a$
a$ = ""
a$ = a$ + |joy = new JoyStick('joyDiv',{internalFillColor: '#EE8800', externalStrokeColor: '#808000',autoReturnToCenter: | + autoCenter$ + |});|
a$ = a$ + |joy.SetCallback(function(e) {connection.send('cmd:immediatxJOY$="' + e.GetX() + ',' + e.GetY() + '":HtmlEventVar$="joy$"\n' )});|
jscript a$
a$ = ""
return

action:
if htmleventvar$ = "autocenter" then
 if autoCenter=1 then autoCenter$="true" else autoCenter$="false"
 gosub screen
endif
if htmleventvar$ = "joy$" then
 X = val(word$(joy$,1,",")) +100    
 Y = val(word$(joy$,2,",")) +100
 pan = X/200*180
 tilt  = Y/200*180
 'pan = 180-pan              'uncomment to invert value for reversing direction of travel  
 'tilt = 180-tilt                  'uncomment to invert value for reversing direction of travel  
 'servo 1, pan                  'uncomment if using a servo
 'servo 2, tilt                    'uncomment if using a servo

endif
pause 50
return

End   '-------------------------   End   --------------------------




This next version of the script has the servo's enabled, and the horizontal axis reversed to make that servo function correctly.
It also has transparency added and colours changed so that the controls can be overlaid on top of a CCTV image if wished.

The background image has only been added to help visualise what the overlaid joystick controls might look like on cctv

Basic:
'Pan & Tilt control with Virtual Joystick - Electroguard - developed on Annex 1.41 beta 6
jsexternal "/joy_cb.min.js"
servo.setup 1,13                     '1st servo gpio pin
servo.setup 2,12                     '2nd servo gpio pin
X=0
Y=0
pan=90
tilt=90
joy$=""
dia$="100"                              'changes knob size
knobcol$="Aquamarine"           'changes knob colour
opacity$="0.5"                         'changes opacity of screen objects - 0=transparent, 1=solid
autoCenter=1                          '1=auto return knob to center, 0=knob remains where last set
if autoCenter=1 then autoCenter$="true" else autoCenter$="false"
htmleventvar$=""
onHtmlChange action
gosub action
gosub screen
wait

screen:
cls
a$=""
a$=a$+|<div style='display: table; margin-right: auto; margin-left: auto;width:450px;background:url("beach32.jpg");'>|
a$=a$+|<div style='display: table; margin-right: auto; margin-left: auto;opacity:|+opacity$+|;'>|
a$=a$+ |<br><br>|
a$=a$+meter$(tilt,0,180,"tilt") + |<br>|
a$=a$+cssid$("tilt","transform: rotate(-90deg);width:90px;")
a$=a$+ |<br><br>|
a$=a$+meter$(pan,0,180,"pan")
a$=a$+cssid$("pan","width:90px;")
a$=a$+|</div>|
a$=a$+|<div style='display: table; margin-right: auto; margin-left: auto;opacity:|+opacity$+|;'>|
a$=a$+textbox$(joy$,"j") + |<br>|
a$=a$+cssid$("j","width:90px;text-align:center;border-style: none;opacity:"+opacity$+";")
a$=a$+|</div>|
a$=a$+|<div style='display: table; margin-right: auto; margin-left: auto;opacity:|+opacity$+|;'>|
a$=a$+checkbox$(autoCenter)
a$=a$+|</div>|
a$=a$+|<div style='display: table; margin-right: auto; margin-left: auto;opacity:|+opacity$+|;'>|
a$=a$+|<div id="joyDiv" style="width:|+dia$+|px;height:|+dia$+|px;margin-bottom:20px;margin:00px;"></div></div>|
a$=a$+|</div>|
autorefresh 200
html a$
a$=""
a$=a$+|joy=new JoyStick('joyDiv',{internalLineWidth:1,internalFillColor:'|+knobcol$+|',externalStrokeColor:'#a0ff00',autoReturnToCenter:|+autoCenter$+|});|
a$=a$+|joy.SetCallback(function(e) {connection.send('cmd:immediatxJOY$="' + e.GetX() + ',' + e.GetY() + '":HtmlEventVar$="joy$"\n' )});|
jscript a$
a$=""
return

action:
if htmleventvar$ = "autocenter" then
 if autoCenter=1 then autoCenter$="true" else autoCenter$="false"
 gosub screen
endif
if htmleventvar$ = "joy$" then
 X = val(word$(joy$,1,",")) +100    
 Y = val(word$(joy$,2,",")) +100
 pan = X/200*180
 tilt  = Y/200*180
 pan = 180-pan               'uncomment to invert value for reversing direction of travel  
 'tilt = 180-tilt                  'uncomment to invert value for reversing direction of travel  
 servo 1, pan                  'uncomment if using a servo
 servo 2, tilt                    'uncomment if using a servo
endif
pause 50
return

End   '-------------------------   End   --------------------------



Robin Baker,
Apr 27, 2020, 6:05 AM
v.1