Introduction :
In this article we are going to implement straightforward Arduino robot controller using python code. so let’s get started :

Table of Contents
Pre- requirement :
- Wireless Xbox 360 dongle
- Xbox 360 controller
- Raspberry Pi
- Arduino
- Robot arm kit
Pin connection board (Python Code For Robot Arm Controller Using Arduino)
Step 1 :
First make the pin connection of servo motor to arduino uno
Step 2:
Then connect Arduino to the Raspberry Pi through USB along with the wireless Xbox 360 dongle.
Step 3: Installation
You need to confirm to see all installation file are loaded successfully or not. i.e. Installed servo motor arduino library
Next is to setup arduino-python3 environment. and install pyserial 2.6 using this:
So let’s install pyserial using this:
pip install pyserial
(Note: If you are face any library installation problem then please see our previous post )
Arduino code for Robot Arm Controller Using Arduino project :
#!/usr/bin/env python
from __future__ import print_function
import xbox
from Arduino import Arduino
import time
# Define Arduino variables
servo1 = 9
servo2 = 6
servo3 = 5
servo4 = 3
servo5 = 11
board = Arduino()
board.Servos.attach(servo1)
board.Servos.attach(servo2)
board.Servos.attach(servo3)
board.Servos.attach(servo4)
board.Servos.attach(servo5)
angle1 = 90
angle2 = 90
angle3 = 90
angle4 = 90
angle5 = 0
# Format floating point number to string format -x.xxx
def fmtFloat(n):
return '{:6.3f}'.format(n)
# Print one or more values without a line feed
def show(*args):
for arg in args:
print(arg, end="")
# Print true or false value based on a boolean, without linefeed
def showIf(boolean, ifTrue, ifFalse=" "):
if boolean:
show(ifTrue)
else:
show(ifFalse)
# Move servo with respect to the left analog stick X values limited to the min-max angle set
def leftXmove(servonum,minAngle,maxAngle):
angle = angle1
if int(joy.leftX()) > 0:
angle = angle - 2
if angle <= minAngle:
angle = minAngle
return angle
elif int(joy.leftX()) < 0:
angle = angle + 2
if angle >= maxAngle:
angle = maxAngle
return angle
else:
return angle
# Move servo with respect to the left analog stick X values limited to the min-max angle set
def leftYmove(servonum,minAngle,maxAngle):
angle = angle2
if int(joy.leftY()) > 0:
angle = angle - 2
if angle <= minAngle:
angle = minAngle
return angle
elif int(joy.leftY()) < 0:
angle = angle + 2
if angle >- maxAngle:
angle = maxAngle
return angle
else:
return angle
# Move servo with respect to the right analog stick Y values limited to the min-max angle set
def rightYmove(servonum,minAngle,maxAngle):
angle = angle3
if int(joy.rightY()) > 0:
angle = angle - 2
if angle <= minAngle:
angle = minAngle
return angle
elif int(joy.rightY()) < 0:
angle = angle + 2
if angle >= maxAngle:
angle = maxAngle
return angle
else:
return angle
# Move servo with respect to the right analog stick X values limited to the min-max angle set
def rightXmove(servonum,minAngle,maxAngle):
angle = angle4
if int(joy.rightX()) > 0:
angle = angle - 2
if angle <= minAngle:
angle = minAngle
return angle
elif int(joy.rightX()) < 0:
angle = angle + 2
if angle >= maxAngle:
angle = maxAngle
return angle
else:
return angle
# Move servo when right trigger is used
def rightTrigmove(servonum,minAngle,maxAngle):
angle5 = minAngle
if int(joy.rightTrigger()) > 0:
angle5 = maxAngle
board.Servos.write(servonum,angle5)
else:
board.Servos.write(servonum,minAngle)
# Instantiate the controller
joy = xbox.Joystick()
# Show various axis and button states until Back button is pressed
print("Xbox controller sample: Press Back button to exit")
while not joy.Back():
# Show connection status
show("Connected:")
showIf(joy.connected(), "Y", "N")
# Left analog stick
show(" Left X/Y:", fmtFloat(joy.leftX()), "/", fmtFloat(joy.leftY()))
# Right analog stick
show(" Right X/Y:", fmtFloat(joy.rightX()), "/", fmtFloat(joy.rightY()))
# Right trigger
show(" RightTrg:", fmtFloat(joy.rightTrigger()))
# Poll controller leftX values and move servo1 accordingly
angle1 = leftXmove(servo1,0,180)
board.Servos.write(servo1,angle1)
# Poll controller leftY values and move servo2 accordingly
angle2 = leftYmove(servo2,0,120)
board.Servos.write(servo2,angle2)
# Poll controller rightY values and move servo3 accordingly
angle3 = rightYmove(servo3,0,180)
board.Servos.write(servo3,angle3)
# Poll controller rightX values and move servo4 accordingly
angle4 = rightXmove(servo4,0,180)
board.Servos.write(servo4,angle4)
# Move claw conencted to servo5 depending on right trigger value
rightTrigmove(servo5,0,90)
# A/B/X/Y buttons
show(" Buttons:")
showIf(joy.A(), "A")
showIf(joy.B(), "B")
showIf(joy.X(), "X")
showIf(joy.Y(), "Y")
# Dpad U/D/L/R
show(" Dpad:")
showIf(joy.dpadUp(), "U")
showIf(joy.dpadDown(), "D")
showIf(joy.dpadLeft(), "L")
showIf(joy.dpadRight(), "R")
# Move cursor back to start of line
show(chr(13))
# Close out when done
joy.close()
Arduino prototype code :
#include <SoftwareSerial.h>
#include <Wire.h>
#include <Servo.h>
#include <EEPROM.h>
void Version(){
Serial.println(F("V0.6"));
}
SoftwareSerial *sserial = NULL;
Servo servos[8];
int servo_pins[] = {0, 0, 0, 0, 0, 0, 0, 0};
boolean connected = false;
int Str2int (String Str_value)
{
char buffer[10]; //max length is three units
Str_value.toCharArray(buffer, 10);
int int_value = atoi(buffer);
return int_value;
}
void split(String results[], int len, String input, char spChar) {
String temp = input;
for (int i=0; i<len; i++) {
int idx = temp.indexOf(spChar);
results[i] = temp.substring(0,idx);
temp = temp.substring(idx+1);
}
}
uint8_t readCapacitivePin(String data) {
int pinToMeasure = Str2int(data);
// readCapacitivePin
// Input: Arduino pin number
// Output: A number, from 0 to 17 expressing
// how much capacitance is on the pin
// When you touch the pin, or whatever you have
// attached to it, the number will get higher
// http://playground.arduino.cc/Code/CapacitiveSensor
//
// Variables used to translate from Arduino to AVR pin naming
volatile uint8_t* port;
volatile uint8_t* ddr;
volatile uint8_t* pin;
// Here we translate the input pin number from
// Arduino pin number to the AVR PORT, PIN, DDR,
// and which bit of those registers we care about.
byte bitmask;
port = portOutputRegister(digitalPinToPort(pinToMeasure));
ddr = portModeRegister(digitalPinToPort(pinToMeasure));
bitmask = digitalPinToBitMask(pinToMeasure);
pin = portInputRegister(digitalPinToPort(pinToMeasure));
// Discharge the pin first by setting it low and output
*port &= ~(bitmask);
*ddr |= bitmask;
delay(1);
// Make the pin an input with the internal pull-up on
*ddr &= ~(bitmask);
*port |= bitmask;
// Now see how long the pin to get pulled up. This manual unrolling of the loop
// decreases the number of hardware cycles between each read of the pin,
// thus increasing sensitivity.
uint8_t cycles = 17;
if (*pin & bitmask) { cycles = 0;}
else if (*pin & bitmask) { cycles = 1;}
else if (*pin & bitmask) { cycles = 2;}
else if (*pin & bitmask) { cycles = 3;}
else if (*pin & bitmask) { cycles = 4;}
else if (*pin & bitmask) { cycles = 5;}
else if (*pin & bitmask) { cycles = 6;}
else if (*pin & bitmask) { cycles = 7;}
else if (*pin & bitmask) { cycles = 8;}
else if (*pin & bitmask) { cycles = 9;}
else if (*pin & bitmask) { cycles = 10;}
else if (*pin & bitmask) { cycles = 11;}
else if (*pin & bitmask) { cycles = 12;}
else if (*pin & bitmask) { cycles = 13;}
else if (*pin & bitmask) { cycles = 14;}
else if (*pin & bitmask) { cycles = 15;}
else if (*pin & bitmask) { cycles = 16;}
// Discharge the pin again by setting it low and output
// It's important to leave the pins low if you want to
// be able to touch more than 1 sensor at a time - if
// the sensor is left pulled high, when you touch
// two sensors, your body will transfer the charge between
// sensors.
*port &= ~(bitmask);
*ddr |= bitmask;
//return cycles;
Serial.println(cycles);
}
void Tone(String data){
int idx = data.indexOf('%');
int len = Str2int(data.substring(0,idx));
String data2 = data.substring(idx+1);
int idx2 = data2.indexOf('%');
int pin = Str2int(data2.substring(0,idx2));
String data3 = data2.substring(idx2+1);
String melody[len*2];
split(melody,len*2,data3,'%');
for (int thisNote = 0; thisNote < len; thisNote++) {
int noteDuration = 1000/Str2int(melody[thisNote+len]);
int note = Str2int(melody[thisNote]);
tone(pin, note, noteDuration);
int pause = noteDuration * 1.30;
delay(pause);
noTone(pin);
}
}
void ToneNo(String data){
int pin = Str2int(data);
noTone(pin);
}
void DigitalHandler(int mode, String data){
int pin = Str2int(data);
if(mode<=0){ //read
Serial.println(digitalRead(pin));
}else{
if(pin <0){
digitalWrite(-pin,LOW);
}else{
digitalWrite(pin,HIGH);
}
//Serial.println('0');
}
}
void AnalogHandler(int mode, String data){
if(mode<=0){ //read
int pin = Str2int(data);
Serial.println(analogRead(pin));
}else{
String sdata[2];
split(sdata,2,data,'%');
int pin = Str2int(sdata[0]);
int pv = Str2int(sdata[1]);
analogWrite(pin,pv);
}
}
void ConfigurePinHandler(String data){
int pin = Str2int(data);
if(pin <=0){
pinMode(-pin,INPUT);
}else{
pinMode(pin,OUTPUT);
}
}
void shiftOutHandler(String data) {
String sdata[4];
split(sdata, 4, data, '%');
int dataPin = sdata[0].toInt();
int clockPin = sdata[1].toInt();
String bitOrderName = sdata[2];
byte value = (byte)(sdata[3].toInt());
if (bitOrderName == "MSBFIRST") {
shiftOut(dataPin, clockPin, MSBFIRST, value);
} else {
shiftOut(dataPin, clockPin, LSBFIRST, value);
}
}
void shiftInHandler(String data) {
String sdata[3];
split(sdata, 3, data, '%');
int dataPin = sdata[0].toInt();
int clockPin = sdata[1].toInt();
String bitOrderName = sdata[2];
int incoming;
if (bitOrderName == "MSBFIRST") {
incoming = (int)shiftIn(dataPin, clockPin, MSBFIRST);
} else {
incoming = (int)shiftIn(dataPin, clockPin, LSBFIRST);
}
Serial.println(incoming);
}
void SS_set(String data){
delete sserial;
String sdata[3];
split(sdata,3,data,'%');
int rx_ = Str2int(sdata[0]);
int tx_ = Str2int(sdata[1]);
int baud_ = Str2int(sdata[2]);
sserial = new SoftwareSerial(rx_, tx_);
sserial->begin(baud_);
Serial.println("ss OK");
}
void SS_write(String data) {
int len = data.length()+1;
char buffer[len];
data.toCharArray(buffer,len);
Serial.println("ss OK");
sserial->write(buffer);
}
void SS_read(String data) {
char c = sserial->read();
Serial.println(c);
}
void pulseInHandler(String data){
int pin = Str2int(data);
long duration;
if(pin <=0){
pinMode(-pin, INPUT);
duration = pulseIn(-pin, LOW);
}else{
pinMode(pin, INPUT);
duration = pulseIn(pin, HIGH);
}
Serial.println(duration);
}
void pulseInSHandler(String data){
int pin = Str2int(data);
long duration;
if(pin <=0){
pinMode(-pin, OUTPUT);
digitalWrite(-pin, HIGH);
delayMicroseconds(2);
digitalWrite(-pin, LOW);
delayMicroseconds(5);
digitalWrite(-pin, HIGH);
pinMode(-pin, INPUT);
duration = pulseIn(-pin, LOW);
}else{
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
delayMicroseconds(2);
digitalWrite(pin, HIGH);
delayMicroseconds(5);
digitalWrite(pin, LOW);
pinMode(pin, INPUT);
duration = pulseIn(pin, HIGH);
}
Serial.println(duration);
}
void SV_add(String data) {
String sdata[3];
split(sdata,3,data,'%');
int pin = Str2int(sdata[0]);
int min = Str2int(sdata[1]);
int max = Str2int(sdata[2]);
int pos = -1;
for (int i = 0; i<8;i++) {
if (servo_pins[i] == pin) { //reset in place
servos[pos].detach();
servos[pos].attach(pin, min, max);
servo_pins[pos] = pin;
Serial.println(pos);
return;
}
}
for (int i = 0; i<8;i++) {
if (servo_pins[i] == 0) {pos = i;break;} // find spot in servo array
}
if (pos == -1) {;} //no array position available!
else {
servos[pos].attach(pin, min, max);
servo_pins[pos] = pin;
Serial.println(pos);
}
}
void SV_remove(String data) {
int pos = Str2int(data);
servos[pos].detach();
servo_pins[pos] = 0;
}
void SV_read(String data) {
int pos = Str2int(data);
int angle;
angle = servos[pos].read();
Serial.println(angle);
}
void SV_write(String data) {
String sdata[2];
split(sdata,2,data,'%');
int pos = Str2int(sdata[0]);
int angle = Str2int(sdata[1]);
servos[pos].write(angle);
}
void SV_write_ms(String data) {
String sdata[2];
split(sdata,2,data,'%');
int pos = Str2int(sdata[0]);
int uS = Str2int(sdata[1]);
servos[pos].writeMicroseconds(uS);
}
void sizeEEPROM() {
Serial.println(E2END + 1);
}
void EEPROMHandler(int mode, String data) {
String sdata[2];
split(sdata, 2, data, '%');
if (mode == 0) {
EEPROM.write(Str2int(sdata[0]), Str2int(sdata[1]));
} else {
Serial.println(EEPROM.read(Str2int(sdata[0])));
}
}
void SerialParser(void) {
char readChar[64];
Serial.readBytesUntil(33,readChar,64);
String read_ = String(readChar);
//Serial.println(readChar);
int idx1 = read_.indexOf('%');
int idx2 = read_.indexOf('$');
// separate command from associated data
String cmd = read_.substring(1,idx1);
String data = read_.substring(idx1+1,idx2);
// determine command sent
if (cmd == "dw") {
DigitalHandler(1, data);
}
else if (cmd == "dr") {
DigitalHandler(0, data);
}
else if (cmd == "aw") {
AnalogHandler(1, data);
}
else if (cmd == "ar") {
AnalogHandler(0, data);
}
else if (cmd == "pm") {
ConfigurePinHandler(data);
}
else if (cmd == "ps") {
pulseInSHandler(data);
}
else if (cmd == "pi") {
pulseInHandler(data);
}
else if (cmd == "ss") {
SS_set(data);
}
else if (cmd == "sw") {
SS_write(data);
}
else if (cmd == "sr") {
SS_read(data);
}
else if (cmd == "sva") {
SV_add(data);
}
else if (cmd == "svr") {
SV_read(data);
}
else if (cmd == "svw") {
SV_write(data);
}
else if (cmd == "svwm") {
SV_write_ms(data);
}
else if (cmd == "svd") {
SV_remove(data);
}
else if (cmd == "version") {
Version();
}
else if (cmd == "to") {
Tone(data);
}
else if (cmd == "nto") {
ToneNo(data);
}
else if (cmd == "cap") {
readCapacitivePin(data);
}
else if (cmd == "so") {
shiftOutHandler(data);
}
else if (cmd == "si") {
shiftInHandler(data);
}
else if (cmd == "eewr") {
EEPROMHandler(0, data);
}
else if (cmd == "eer") {
EEPROMHandler(1, data);
}
else if (cmd == "sz") {
sizeEEPROM();
}
}
void setup() {
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
Serial.println("connected");
}
void loop() {
SerialParser();
}
Python Code For Robot Arm Controller Using Arduino :
#!/usr/bin/env python
"""
Blinks an LED on digital pin 13
in 1 second intervals
"""
from Arduino import Arduino
import time
board = Arduino() # plugged in via USB, serial com at rate 115200
board.pinMode(13, "OUTPUT")
while True:
board.digitalWrite(13, "LOW")
time.sleep(1)
board.digitalWrite(13, "HIGH")
time.sleep(1)
Hey guys finally all coding work done so you need to customize it and then impress to your …………….!!!
Resource : Arduino official site
BEST OF LUCK!!