Right now, I'm just trying to move the circle object based on the joystick coordinates given from the Arduino data.
I'm just testing the x axis to move the circle right when the value of the x axis reaches 1023.
I have two main issues:
So my 2 questions are:
I'm getting following Arduino data from the COM 3 port into python:
JSPy.ino
//input pins
//analog
int JSx = A0;
int JSy = A1;
//digital
int JSpin = 9;
//read JS position values
int JSxVal;
int JSyVal;
int JSVal;
// delay(ms)
int dt = 500;
void setup() {
// put your setup code here, to run once:
pinMode(JSx,INPUT);
pinMode(JSy,INPUT);
digitalWrite(JSpin,HIGH);
Serial.begin(9600);
}
void loop() {
// put your main code here, to run repeatedly:
JSxVal = analogRead(JSx);
JSyVal = analogRead(JSy);
JSVal = digitalRead(JSpin);
delay(dt);
//JSx coor
Serial.print(JSxVal);
Serial.print(" ");
//JSy coor
Serial.println(JSyVal);
}
This is the py file:
main.py
import serial
import time
import pygame as pg
# default port is 9600 baud rate so didnt have to set
arduinoData = serial.Serial("com3")
time.sleep(1)
# pygame settings
#screen
bgSize =screenW,screenH = 500,600
screen = pg.display.set_mode((bgSize))
ballx,bally = 250,300
ballPos=(ballx,bally)
GRAY = (112,112,112)
BLUE = (0,0,255)
run =True
while run:
for event in pg.event.get():
while(arduinoData.inWaiting()==0):
pass
dataPacket = arduinoData.readline()
# convert from binary to string
dataPacket = dataPacket.decode(encoding='utf-8')
# make list of string numbers of coordinates
dataPacket = dataPacket.split()
# turn coordinates into int in the list
dataPacket = [eval(i) for i in dataPacket]
if event.type == pg.QUIT:
run=False
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
run= False
if dataPacket[0] == 1023:
ballx+=1
print(f"x pos = {ballPos[0]}")
screen.fill(BLUE)
print(f" JS - x - {dataPacket[0]}")
pg.draw.circle(screen, GRAY,ballPos,15,4)
pg.display.update()
There's a couple of issues:
dataPacket = dataPacket.split()
# turn coordinates into int in the list
dataPacket = [eval(i) for i in dataPacket]
Firstly don't use eval().
So the Arduino has written two textual numbers into a string, separated by a space, and ended with a newline. That's pretty easy to convert into integers.
positions = dataPacket.split() # creates a list of string-numbers
try:
joy_x = int( positions[0], 10 )
joy_y = int( poisitons[1], 10 )
had_error = False
except:
print( "Bad data packet: " + dataPacket )
had_error = True
The code is drawing the ball at position specified by the tuple ballPos
. The code reads like ballPos
refers to ballx
and bally
- it doesn't, they're copied into the tuple. So you need to update ballPos
too:
if ( not had_error ):
ballx = joy_x
bally = joy_y
ballPos = ( ballx, bally ) # update circle locations
Note: the code above assumes the received position is an absolute pixel coordinate. Maybe that's not how your Arduino joystick is working, but in any event this change will get something happening.