Hi all,
I didn't see this posted so here goes...
I'd like to add an analog joystick. (I have one lying around).
The 8Bcraft site has a tutorial to mod the Retrostone but it says:
"IMPORTANT : Joystick driver is not yet functional!"
Also it says the parts needed are:
Analog joystick
MCP3208 SMD SOIC package
But the tutorial only mentions how to install the joystick, no mention of installing the MCP3208.
It also says "The buttons and joystick should work out of the box"
Could someone clear up how this should be done?
Thanks
Analog joystick installation questions
Re: Analog joystick installation questions
Ok I see it now. It is hard to see, but there is an area on the PCB for the MCP3208.
But once installed, will the joystick work or are drivers required?
But once installed, will the joystick work or are drivers required?
Re: Analog joystick installation questions
Yes check the :
The source I used is this : http://codelectron.com/how-to-setup-2-a ... e-pi-zero/
Below is the GPIO driver (drivername.py) including the joystick that I wrote. It seemed correct to me but it did not worked on my first attempt. But it could just have been something that I did not soldered correctly or just a typo in the script...
Note this driver is used for GPIO buttons with pyA20 package. Driver should be able to use same pyA20 package. BTW it should be possible to use pyA20 SPI package instead of spidev. I used spidev because it's what they used on codelectron webpage.
If you want to test this driver you will have to replace current driver python file with this one. I am not sure exactly how it's done since retrorangepi devs enabled by default the retrostone GPIO driver. (vs the other versions of retrorangepi where you have to enable it from retropie emulator/retrorangepi/GPIO)
About the joystick driver I had not much time recently to work on it. I started to work on it but it was not working yet and I had no further time to work on it since.Step 8 : Solder the MCP3208, if you have hot air solder station you can use it, or just use regular (small) solder iron. Check on youtube how to solder chips if you don’t know how. Don’t solder it reversed side ! The writing on the chips should be the same side as the writing on the PCB.
The source I used is this : http://codelectron.com/how-to-setup-2-a ... e-pi-zero/
Below is the GPIO driver (drivername.py) including the joystick that I wrote. It seemed correct to me but it did not worked on my first attempt. But it could just have been something that I did not soldered correctly or just a typo in the script...
Note this driver is used for GPIO buttons with pyA20 package. Driver should be able to use same pyA20 package. BTW it should be possible to use pyA20 SPI package instead of spidev. I used spidev because it's what they used on codelectron webpage.
If you want to test this driver you will have to replace current driver python file with this one. I am not sure exactly how it's done since retrorangepi devs enabled by default the retrostone GPIO driver. (vs the other versions of retrorangepi where you have to enable it from retropie emulator/retrorangepi/GPIO)
Code: Select all
#!/usr/bin/env python
import spidev
import evdev
import uinput
from time import sleep
from evdev import InputDevice, KeyEvent, UInput, AbsInfo, ecodes as e
from pyA20.gpio import gpio
from pyA20.gpio import port
from pyA20.gpio import connector
class MCP3208:
def __init__(self, spi_channel=0):
self.spi_channel = spi_channel
self.conn = spidev.SpiDev(1, spi_channel)
self.conn.max_speed_hz = 1000000 # 1MHz
def __del__( self ):
self.close
def close(self):
if self.conn != None:
self.conn.close
self.conn = None
def bitstring(self, n):
s = bin(n)[2:]
return '0'*(8-len(s)) + s
def ReadInput(self,Sensor):
adc = self.conn.xfer2([1,(8+Sensor)<<4,0])
data = ((adc[1]&3) << 8) + adc[2]
return data
def read(self, adc_channel=0):
# build command
cmd = 128 # start bit
cmd += 64 # single end / diff
if adc_channel % 2 == 1:
cmd += 8
if (adc_channel/2) % 2 == 1:
cmd += 16
if (adc_channel/4) % 2 == 1:
cmd += 32
# send & receive data
reply_bytes = self.conn.xfer2([cmd, 0, 0, 0])
#
reply_bitstring = ''.join(self.bitstring(n) for n in reply_bytes)
# print reply_bitstring
# see also... http://akizukidenshi.com/download/MCP3204.pdf (page.20)
reply = reply_bitstring[5:17]
return int(reply, 2)
events = ([
uinput.BTN_A,
uinput.BTN_B,
uinput.BTN_C,
uinput.BTN_X,
uinput.BTN_Y,
uinput.BTN_Z,
uinput.BTN_TL,
uinput.BTN_TR,
uinput.BTN_THUMBL,
uinput.BTN_THUMBR,
uinput.BTN_SELECT,
uinput.BTN_START,
uinput.BTN_TL2,
uinput.BTN_TR2,
uinput.ABS_X + (0,255,0,0),
uinput.ABS_Y + (0,255,0,0),
uinput.BTN_DPAD_UP,
uinput.BTN_DPAD_DOWN,
uinput.BTN_DPAD_LEFT,
uinput.BTN_DPAD_RIGHT,
])
#could use BTN_DPAD_UP BTN_DPAD_DOWN BTN_DPAD_LEFT BTN_DPAD_RIGHT but is it better?
gamepad = uinput.Device(events,"RetroStone Controle",0x00)
gamepad.emit(uinput.ABS_X, 128, syn=False)
gamepad.emit(uinput.ABS_Y, 128)
#--------------- define botoes -----------------
# ---- PLAYER 1 ---------#
bt_up_p1 = port.PD12
bt_down_p1 = port.PD5
bt_left_p1 = port.PD0
bt_right_p1 = port.PD11
bt_l_p1 = port.PD6
bt_x_p1 = port.PD13
bt_y_p1 = port.PD9
bt_r_p1 = port.PD7
bt_b_p1 = port.PD15
bt_a_p1 = port.PD14
bt_select_p1 = port.PD4
bt_start_p1 = port.PD1
bt_left_trigger_p1 = port.PD8
bt_right_trigger_p1 = port.PD3
#optional buttons
bt_c_p1 = port.PC9
bt_z_p1 = port.PE3
bt_d_p1 = port.PA3
bt_e_p1 = port.PA15
#--------------------------------Initialize module. Always called first
spi = MCP3208(0)
gpio.init()
gpio.setcfg(bt_up_p1, gpio.INPUT)
gpio.pullup(bt_up_p1, gpio.PULLUP)
gpio.setcfg(bt_down_p1, gpio.INPUT)
gpio.pullup(bt_down_p1, gpio.PULLUP)
gpio.setcfg(bt_left_p1, gpio.INPUT)
gpio.pullup(bt_left_p1, gpio.PULLUP)
gpio.setcfg(bt_right_p1, gpio.INPUT)
gpio.pullup(bt_right_p1, gpio.PULLUP)
gpio.setcfg(bt_l_p1, gpio.INPUT)
gpio.pullup(bt_l_p1, gpio.PULLUP)
gpio.setcfg(bt_x_p1, gpio.INPUT)
gpio.pullup(bt_x_p1, gpio.PULLUP)
gpio.setcfg(bt_y_p1, gpio.INPUT)
gpio.pullup(bt_y_p1, gpio.PULLUP)
gpio.setcfg(bt_r_p1, gpio.INPUT)
gpio.pullup(bt_r_p1, gpio.PULLUP)
gpio.setcfg(bt_b_p1, gpio.INPUT)
gpio.pullup(bt_b_p1, gpio.PULLUP)
gpio.setcfg(bt_a_p1, gpio.INPUT)
gpio.pullup(bt_a_p1, gpio.PULLUP)
gpio.setcfg(bt_c_p1, gpio.INPUT)
gpio.pullup(bt_c_p1, gpio.PULLUP)
gpio.setcfg(bt_z_p1, gpio.INPUT)
gpio.pullup(bt_z_p1, gpio.PULLUP)
gpio.setcfg(bt_d_p1, gpio.INPUT)
gpio.pullup(bt_d_p1, gpio.PULLUP)
gpio.setcfg(bt_e_p1, gpio.INPUT)
gpio.pullup(bt_e_p1, gpio.PULLUP)
gpio.setcfg(bt_select_p1, gpio.INPUT)
gpio.pullup(bt_select_p1, gpio.PULLUP)
gpio.setcfg(bt_start_p1, gpio.INPUT)
gpio.pullup(bt_start_p1, gpio.PULLUP)
gpio.setcfg(bt_left_trigger_p1, gpio.INPUT)
gpio.pullup(bt_left_trigger_p1, gpio.PULLUP)
gpio.setcfg(bt_right_trigger_p1, gpio.INPUT)
gpio.pullup(bt_right_trigger_p1, gpio.PULLUP)
_bt_up_p1 = False
_bt_down_p1 = False
_bt_left_p1 = False
_bt_right_p1 = False
_bt_a_p1 = False
_bt_b_p1 = False
_bt_x_p1 = False
_bt_y_p1 = False
_bt_c_p1 = False
_bt_z_p1 = False
_bt_d_p1 = False
_bt_e_p1 = False
_bt_l_p1 = False
_bt_r_p1 = False
_bt_select_p1 = False
_bt_start_p1 = False
_bt_left_trigger_p1 = False
_bt_right_trigger_p1 = False
joystick_spi_LR = 0
joystick_spi_UD = 0
_joystick_spi_LR = 0
_joystick_spi_UD = 0
while True:
#------ player 1 -----------#
#bt a =====================
if (not _bt_a_p1) and (gpio.input(bt_a_p1) == 0):
_bt_a_p1 = True
gamepad.emit(uinput.BTN_A, 1)
if (_bt_a_p1) and (gpio.input(bt_a_p1) == 1):
_bt_a_p1 = False
gamepad.emit(uinput.BTN_A, 0)
#bt b =====================
if (not _bt_b_p1) and (gpio.input(bt_b_p1) == 0):
_bt_b_p1 = True
gamepad.emit(uinput.BTN_B, 1)
if (_bt_b_p1) and (gpio.input(bt_b_p1) == 1):
_bt_b_p1 = False
gamepad.emit(uinput.BTN_B, 0)
#bt X =====================
if (not _bt_x_p1) and (gpio.input(bt_x_p1) == 0):
_bt_x_p1 = True
gamepad.emit(uinput.BTN_X, 1)
if (_bt_x_p1) and (gpio.input(bt_x_p1) == 1):
_bt_x_p1 = False
gamepad.emit(uinput.BTN_X, 0)
#bt Y =====================
if (not _bt_y_p1) and (gpio.input(bt_y_p1) == 0):
_bt_y_p1 = True
gamepad.emit(uinput.BTN_Y, 1)
if (_bt_y_p1) and (gpio.input(bt_y_p1) == 1):
_bt_y_p1 = False
gamepad.emit(uinput.BTN_Y, 0)
#bt C =====================
if (not _bt_c_p1) and (gpio.input(bt_c_p1) == 0):
_bt_c_p1 = True
gamepad.emit(uinput.BTN_C, 1)
if (_bt_c_p1) and (gpio.input(bt_c_p1) == 1):
_bt_c_p1 = False
gamepad.emit(uinput.BTN_C, 0)
#bt Z =====================
if (not _bt_z_p1) and (gpio.input(bt_z_p1) == 0):
_bt_z_p1 = True
gamepad.emit(uinput.BTN_Z, 1)
if (_bt_z_p1) and (gpio.input(bt_z_p1) == 1):
_bt_z_p1 = False
gamepad.emit(uinput.BTN_Z, 0)
#bt D =====================
if (not _bt_d_p1) and (gpio.input(bt_d_p1) == 0):
_bt_d_p1 = True
gamepad.emit(uinput.BTN_THUMBL, 1)
if (_bt_d_p1) and (gpio.input(bt_d_p1) == 1):
_bt_d_p1 = False
gamepad.emit(uinput.BTN_THUMBL, 0)
#bt E =====================
if (not _bt_e_p1) and (gpio.input(bt_e_p1) == 0):
_bt_e_p1 = True
gamepad.emit(uinput.BTN_THUMBR, 1)
if (_bt_e_p1) and (gpio.input(bt_e_p1) == 1):
_bt_e_p1 = False
gamepad.emit(uinput.BTN_THUMBR, 0)
#bt L =====================
if (not _bt_l_p1) and (gpio.input(bt_l_p1) == 0):
_bt_l_p1 = True
gamepad.emit(uinput.BTN_TL, 1)
if (_bt_l_p1) and (gpio.input(bt_l_p1) == 1):
_bt_l_p1 = False
gamepad.emit(uinput.BTN_TL, 0)
#bt R =====================
if (not _bt_r_p1) and (gpio.input(bt_r_p1) == 0):
_bt_r_p1 = True
gamepad.emit(uinput.BTN_TR, 1)
if (_bt_r_p1) and (gpio.input(bt_r_p1) == 1):
_bt_r_p1 = False
gamepad.emit(uinput.BTN_TR, 0)
#bt select =====================
if (not _bt_select_p1) and (gpio.input(bt_select_p1) == 0):
_bt_select_p1 = True
gamepad.emit(uinput.BTN_SELECT, 1)
if (_bt_select_p1) and (gpio.input(bt_select_p1) == 1):
_bt_select_p1 = False
gamepad.emit(uinput.BTN_SELECT, 0)
#bt start =====================
if (not _bt_start_p1) and (gpio.input(bt_start_p1) == 0):
_bt_start_p1 = True
gamepad.emit(uinput.BTN_START, 1)
if (_bt_start_p1) and (gpio.input(bt_start_p1) == 1):
_bt_start_p1 = False
gamepad.emit(uinput.BTN_START, 0)
#bt L2 =====================
if (not _bt_left_trigger_p1) and (gpio.input(bt_left_trigger_p1) == 0):
_bt_left_trigger_p1 = True
gamepad.emit(uinput.BTN_TL2, 1)
if (_bt_left_trigger_p1) and (gpio.input(bt_left_trigger_p1) == 1):
_bt_left_trigger_p1 = False
gamepad.emit(uinput.BTN_TL2, 0)
#bt R2 =====================
if (not _bt_right_trigger_p1) and (gpio.input(bt_right_trigger_p1) == 0):
_bt_right_trigger_p1 = True
gamepad.emit(uinput.BTN_TR2, 1)
if (_bt_right_trigger_p1) and (gpio.input(bt_right_trigger_p1) == 1):
_bt_right_trigger_p1 = False
gamepad.emit(uinput.BTN_TR2, 0)
####DIRECTIONS P1 ###########################
#bt up =====================
if (not _bt_up_p1) and (gpio.input(bt_up_p1) == 0):
_bt_up_p1 = True
gamepad.emit(uinput.BTN_DPAD_UP, 1)
if (_bt_up_p1) and (gpio.input(bt_up_p1) == 1):
_bt_up_p1 = False
gamepad.emit(uinput.BTN_DPAD_UP, 0)
#bt down =====================
if (not _bt_down_p1) and (gpio.input(bt_down_p1) == 0):
_bt_down_p1 = True
gamepad.emit(uinput.BTN_DPAD_DOWN, 1)
if (_bt_down_p1) and (gpio.input(bt_down_p1) == 1):
_bt_down_p1 = False
gamepad.emit(uinput.BTN_DPAD_DOWN, 0)
#bt left =====================
if (not _bt_left_p1) and (gpio.input(bt_left_p1) == 0):
_bt_left_p1 = True
gamepad.emit(uinput.BTN_DPAD_LEFT, 1)
if (_bt_left_p1) and (gpio.input(bt_left_p1) == 1):
_bt_left_p1 = False
gamepad.emit(uinput.BTN_DPAD_LEFT, 0)
#bt right =====================
if (not _bt_right_p1) and (gpio.input(bt_right_p1) == 0):
_bt_right_p1 = True
gamepad.emit(uinput.BTN_DPAD_RIGHT, 1)
if (_bt_right_p1) and (gpio.input(bt_right_p1) == 1):
_bt_right_p1 = False
gamepad.emit(uinput.BTN_DPAD_RIGHT, 0)
#joystick =====================
joystick_spi_LR = spi.ReadInput(1)/4 #/4 because spi read 12 bits, ie 0 to 1023 and we need in range 0 to 253
if (_joystick_spi_LR != joystick_spi_LR)
_joystick_spi_LR = joystick_spi_LR
gamepad.emit(uinput.ABS_X, joystick_spi_LR)
joystick_spi_UD = spi.ReadInput(2)/4
if (_joystick_spi_UD != joystick_spi_UD)
_joystick_spi_UD = joystick_spi_UD
gamepad.emit(uinput.ABS_X, joystick_spi_UD)
sleep(.02)
Re: Analog joystick installation questions
@Brandon: Did you ever attempt to get this working?
Re: Analog joystick installation questions
I want to do a mod but i need something to work on.
New website https://www.rghandhelds.com/
Old website https://jutleys.wixsite.com/retrogamers97-90/home/
Discord channel https://discord.gg/wurh4WM
YouTube channel http://www.youtube.com/c/RGhandhelds
Old website https://jutleys.wixsite.com/retrogamers97-90/home/
Discord channel https://discord.gg/wurh4WM
YouTube channel http://www.youtube.com/c/RGhandhelds
Re: Analog joystick installation questions
Hi, there were developments on the driver side? I'd like to do this mod, but doesn't make sense to do it, if it's not supported at driver level
Re: Analog joystick installation questions
Hi...Unfortunately, with a sensitivity of 4, the pointer jumps from one corner to another without having a slow progression.I have tried sensitivity of 4, 150, 250, 350, 450. There is no analog behavior at all.
smt assembly
smt assembly
Re: Analog joystick installation questions
I'm guessing he gave up, since the Retrostone 2 is out now.