Project - Analog Joysticks

Note: Either of the modues shown above can offer 4 analog inputs, and although they both look and function similarly, pay attention to their very different left-hand pinouts.

The trimpots shown on the modules above are connected between GND and VCC, with the wiper connected via tombstone jumper to ADC3 input.
Adjusting the trimpot varies the ADC3 input resulting in an appropriate ADC value of between 0 and 255.
A dual-axis joystick works in the same way, using one ADC input for horizontal axis and another for vertical axis.
The other 2 remaining ADC inputs might be similarly used for a second joystick, if wished.

Whatever your intended joystick use, it is easier to set things up properly if you can monitor the ADC values.
So the following script provides 4 textbox windows and 4 meters components to monitor the 4 ADC values.

This offers the opportunity to check out the effects of the on-board thermistor, LDR and trimpot, if wished.
When ready to use the ADC inputs for something else, just remember to remove the appropriate jumpers.
The ADC inputs don't necessarily have to be used for joysticks of course, they might monitor any analog voltages.

Joystick Breakout Modules are available from ebay for about a quid, or dual joysticks can be got for about £3.
Or you could 're-purpose' a computer gaming joystick, or steering wheel and pedals, or anything with potentiometers.
(The lettering is easier to read from upside down pics)

Whatever you choose, connect one side of the pots to 0v, the other side to VCC, and connect the X and Y axis wipers to your chosen ADCs.

The webpage textbox and meter components will help you orientate the controls to get them working in the appropriate directions for your purposes, and  makes it easier to see if any offsets or biases are required.

Any disconnected ADC inputs tend to act a bit like rider-less horses in a race and will follow the other inputs.
Tie any unused ADC inputs high or low if you prefer, but it will do no harm to just let them 'roam free'.
It's possible to only request data from used ADCs, but for our purposes it's unnecessary over-complication.

Set the Timer0 interval for a period sufficiently responsive for your needs, while also being realistic, because if too fast it will cause problems.

If the joystick has a Fire button it can be connected to GPIO00, if more joystick buttons are needed they can be duplicated using spare gpio's.
If insufficient gpio's, more could be added by connecting a PCF8574 8-port expander to the same i2c bus to gain 8 more digital inputs or outputs.

(the 2 modules above use the same two i2c pins to provide 8 gpio's, 4 x 8bit Analog to Digital converters, as well as a Digital to Analog converter)
 
NOTE:  Joysticks for Remote Control Aircraft have 2 standard layouts, with most western countries adopting Mode 2, where the left stick controls throttle and steering while the right stick controls forward/backward and sideways motions - Mode 1 swaps the sticks, using the right for throttle.

Basic:
'                                          Analog Joysticks
'i2c.setup 4, 5                     'i2c RX and TX pins need to be configured as appropriate
i2c.setup 5, 4                     'i2c RX and TX pins need to be configured as appropriate
'goto i2cscanner                 'uncomment to use i2c scanner
PCF8591_address = 72     'set to module i2c address
adc0 = 0: adc1 = 0: adc2 = 0: adc3 = 0
buttonpin1 = 0        
pin.mode buttonpin1, input, pullup
interrupt buttonpin1, button1
led1 = 1
timer0 300, readadc
gosub paint
onhtmlreload paint
wait

button1:
if pin(buttonpin1) = 0 then led1 = 0 else led1 = 1
refresh
return

readadc:
i2c.begin PCF8591_address
i2c.write 4
i2c.end
i2c.reqfrom PCF8591_address, 5
adc0 = i2c.read       'first byte is discarded
adc0 = i2c.read
adc1 = i2c.read
adc2 = i2c.read
adc3 = i2c.read
refresh
return

paint:
cls
a$ = ""
a$ = a$ + " ADC 0 " + textbox$(adc0,"tb") + " " + meter$(adc0,0,255) + "<br>"
a$ = a$ + " ADC 1 " + textbox$(adc1,"tb") + " " + meter$(adc1,0,255) + "<br>"
a$ = a$ + " ADC 2 " + textbox$(adc2,"tb") + " " + meter$(adc2,0,255) + "<br>"
a$ = a$ + " ADC 3 " + textbox$(adc3,"tb") + " " + meter$(adc3,0,255) + "<br>"
a$ = a$ + " Button1 " + led$(led1) + "<br>"
a$ = a$ + cssid$("tb","width:40px;text-align:right;")
html a$
return

i2cscanner:
wlog "Scanning for i2c devices..."
for c = 1 to 126
 i2c.begin c
 if i2c.end = 0 then
  wlog "found " + str$(c) + string$(5," ") +  hex$(c)
  pause 50
 end if
next c
wlog "Finished"
end
return

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



Margaret Baker,
Feb 10, 2018, 5:40 AM
v.1