Skip to main content
2 of 11
added 3113 characters in body
ZanQdo
  • 31
  • 1
  • 1
  • 5

Send multiple int values from Python to Arduino using pySerial

I'm trying to send 5 ints in the range of 0-180 from Blender to the Arduino Uno device using pySerial (py3K). I have managed to send 1 int (not sure if it's the best way but it works). However I'm failing to send more than 1 and every example online seems to stop at 1.

Here's the complete code. The task is to send servo0-servo4 to the arduino and apply those values to the corresponding servos. In line 64 I send servo0 from Blender and in line 94 I receive it in the Arduino using Serial.parseInt() (Again I'm just using this cause it works but I'll welcome any better/faster way).

Runs once at startup in Blender

import sys
sys.path.append("/usr/lib/python3.3/site-packages/")
import serial
import bge

bge.scene = bge.logic.getCurrentScene()
bge.arduino = serial.Serial('/dev/ttyACM0', 9600, timeout=.01)
bge.joySticks = bge.logic.joysticks

Runs in a loop in Blender

import bge
import math

xbox = bge.joySticks[0]
xboxAxis = xbox.axisValues

# -1<>1
xboxLeftStickLR = xboxAxis[0]
xboxLeftStickUD = xboxAxis[1]
xboxRightStickLR = xboxAxis[3]
xboxRightStickUD = xboxAxis[4]
xboxLeftTrigger = xboxAxis[2]
xboxRightTrigger = xboxAxis[5]

# 0<>180
servo0 = int((xboxLeftStickLR + 1) * 90)
servo1 = int((xboxLeftStickUD + 1) * 90)
servo2 = int((xboxRightStickLR + 1) * 90)
servo3 = int((xboxRightStickUD + 1) * 90)
servo4 = int(((-xboxLeftTrigger + 1) * 45) + ((xboxRightTrigger + 1) * 45))

# on screen visualizers
needle0 = bge.scene.objects['needle0']
needle1 = bge.scene.objects['needle1']
needle2 = bge.scene.objects['needle2']
needle3 = bge.scene.objects['needle3']
needle4 = bge.scene.objects['needle4']

needle_xyz = needle0.localOrientation.to_euler()
needle_xyz[1] = math.radians(servo0-90)
needle0.localOrientation = needle_xyz.to_matrix()

needle_xyz = needle1.localOrientation.to_euler()
needle_xyz[1] = math.radians(-servo1+90)
needle1.localOrientation = needle_xyz.to_matrix()

needle_xyz = needle2.localOrientation.to_euler()
needle_xyz[1] = math.radians(servo2-90)
needle2.localOrientation = needle_xyz.to_matrix()

needle_xyz = needle3.localOrientation.to_euler()
needle_xyz[1] = math.radians(-servo3+90)
needle3.localOrientation = needle_xyz.to_matrix()

needle_xyz = needle4.localOrientation.to_euler()
needle_xyz[1] = math.radians(servo4-90)
needle4.localOrientation = needle_xyz.to_matrix()

# write to arduino
bge.arduino.write(str(servo0).encode())

print (bge.arduino.readline())

The Arduino code

#include <Servo.h>

Servo servo0;
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;

void setup(){
  Serial.begin(9600);
  Serial.setTimeout(10);
  pinMode(12, OUTPUT);
  servo0.attach(3);
  servo1.attach(5);
  servo2.attach(6);
  servo3.attach(9);
  servo4.attach(10);
}

void loop(){
  
  if(Serial.available()){
    
    int message = Serial.parseInt();
    
    // let's be safe
    if (message > 179){
      message = 179;
    }
    else if (message < 0){
      message = 0;
    }
    
    // dp something with the LED
    if(message == 0 || message == 179){
        digitalWrite(12, HIGH);
      }
    else{
      digitalWrite(12, LOW);
    }
    
    // control the servos
    servo0.write(message);
    Serial.println(message);

  }
  
}
ZanQdo
  • 31
  • 1
  • 1
  • 5