This log is going to be about the python communication files, explaining the interfaces used in order to communicate both with the ps3 controller and with the arduino.
Serial Bidirectional Communication on python.
This is written in the serial_com.py file and the code goes as follow:
- First thing is to define the serial port and its baudrate.
import serial
class ArduinoSerial:
def __init__(self , port):
#ls -l /dev | grep ACM to identify serial port of the arduino
self.arduino = serial.Serial(port, 500000, timeout = 1)
self.arduino.setDTR(False) #force an arduino reset
time.sleep(1)
self.arduino.flushInput()
self.arduino.setDTR(True)
- Then the communication is done with the next two fuctions. This fuctions are very general and can be used without big chnges.
This program will stop the main loop until the next data arrives, this way the arudino memory is not overloaded with the pulse commands arriving.
def serialSend(self, pulse):
comando = "<{0}#{1}#{2}#{3}#{4}#{5}#{6}#{7}#{8}#{9}#{10}#{11}>" #Input
command=comando.format(int(pulse[0]), int(pulse[1]), int(pulse[2]),
int(pulse[3]), int(pulse[4]), int(pulse[5]),
int(pulse[6]), int(pulse[7]), int(pulse[8]),
int(pulse[9]), int(pulse[10]), int(pulse[11]))
self.arduino.write(bytes(command , encoding='utf8'))
def serialRecive(self):
try:
startMarker = 60
endMarker = 62
getSerialValue = bytes()
x = "z" # any value that is not an end- or startMarker
byteCount = -1 # to allow for the fact that the last increment will be one too many
# wait for the start character
while ord(x) != startMarker:
x = self.arduino.read()
# save data until the end marker is found
while ord(x) != endMarker:
if ord(x) != startMarker:
getSerialValue = getSerialValue + x
byteCount += 1
x = self.arduino.read()
loopTime , Xacc , Yacc , roll , pitch = numpy.fromstring(getSerialValue.decode('ascii', errors='replace'), sep = '#' )
Connecting PS3 controller to the Raspberry Pi and reading its events.
- Connecting the PS3 controller was very simple, here is the tutorial i used: https://pimylifeup.com/raspberry-pi-playstation-controllers/
- Then events are read on the joystick.py file, using evdev python library. In this set up, the events are read every time the read() function is called, ignoring the others ongoing events. Also there isn't any queue method or filtering.
from evdev import InputDevice, categorize, ecodes
from select import select
import numpy as np
class Joystick:
def __init__(self , event):
#python3 /usr/local/lib/python3.8/dist-packages/evdev/evtest.py for identify event
self.gamepad = InputDevice(event)
def read(self):
r,w,x = select([self.gamepad.fd], [], [], 0.)
if r:
for event in self.gamepad.read():
if event.type == ecodes.EV_KEY:
if event.value == 1:
if event.code == 544:#up arrow
self.T += 0.05
if event.code == 545:#down arrow
self.T -= 0.05
if event.code == 308:#square
if self.compliantMode == True:
self.compliantMode = False
elif self.compliantMode == False:
self.compliantMode = True
else:
print("boton soltado")
elif event.type == ecodes.EV_ABS:
absevent = categorize(event)
if ecodes.bytype[absevent.event.type][absevent.event.code] == "ABS_X":
self.L3[0]=absevent.event.value-127
elif ecodes.bytype[absevent.event.type][absevent.event.code] == "ABS_Y":
self.L3[1]=absevent.event.value-127
elif ecodes.bytype[absevent.event.type][absevent.event.code] == "ABS_RX":
self.R3[0]=absevent.event.value-127
elif ecodes.bytype[absevent.event.type][absevent.event.code] == "ABS_RY":
self.R3[1]=absevent.event.value-127
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.