Simple analog and digital control prototype using Arduino and Python

Building hardware interfaces for programs and robotic projects its always easy with Arduino, the communication capability of the board allows to send data directly to a computer or logic circuit with no need for complex custom electronic configurations. The prototype was created to test the following capabilities and characteristics for Arduino and Python working in together:

  • Arduino analog and digital read
  • Arduino Serial communication 
  • Python Serial port reading
  • Python periferical control emulation

Creating a custom shield for the control make it a compact and easy prototype, avoiding the use of temporary connections on a breadboard and giving more extended life use; in this case the board used was a Arduino Serial ATMEGA8-16PU but the control and the concep explained are usable for any Arduino model which can be use a shield. The design is very simple yet effective to get signal from 3 potentiometers and 2 switches on the shield board, the potentiometers connected to the analog input pins A0-A1-A2 and the digital buttons to the 8-9 digital pins on the Arduino board, the communication its done by the serial connection of the board right to the computer USB port.



The finished shield goes on top of the Arduino board and it fits the female pins correctly, its powered by the 5 VDC and GND pins, the third potentiometer gets a handling wheel for easy use and the other two are oriented to side of the shield.



The Arduino code collect the digital and anlog data from de pins and then transmited to the seria port, the map funtion allows to allocate the output signal between known limits which makes easy the interpretation on Python; another important aspect its to avoid to overload the serial port comunication, in this case the three anlog signals consume too much "bandwith" on the comunication, this can be solved by reducing the time between counication adding delay funtions but even this way the comunication may get lag due the constant transmiting data.Adding a "change" parameter the board has the rule to send a package of information only when the input signal changes, this avoid the constant useless repetitive data, the board only write to the serial port when any potentiometer or butthon has change its state, but even there a tiny delay funtion must be used for cases where all the inputs change too fast at the same time.

The Python code first try to find any serial device connected to some known ports and then establish connection to get the data, it assign the whole data package to a single variable, the code form the Arduino board have an identifier between the analog data, which can change in length from 1 to 2 characters, this identifier its searched by the Python code to exactly know where a input ends and the other begins. Using the capability of Python to communicate directly to a system console any known command can be runned on the computer, in this case the program xdotool makes the trick of transfering the arduino serial data to events on the mouse and keyboard.

Arduino Code

Python Code

int firstpotentiometer = 0;
int secondpotentiometer = 0;
int thirdpotentiometer = 0;
int buttonA = 0;
int buttonB = 0;
int change = 0;
int l = 0;

void setup()
{
Serial.begin(9600);
}

void loop()
{
if (Serial.available() > 0) {
firstpotentiometer = analogRead(A0);
firstpotentiometer = map(firstpotentiometer, 0, 1023, 0, 99);
secondpotentiometer = analogRead(A1);
secondpotentiometer = map(secondpotentiometer, 0, 1023, 0, 99);
thirdpotentiometer = analogRead(A2);
thirdpotentiometer = map(thirdpotentiometer, 0, 1023, 0, 99);
buttonA = digitalRead(8);
buttonB = digitalRead(9);
if (change != buttonA + buttonB + firstpotentiometer + secondpotentiometer + thirdpotentiometer){
Serial.print(buttonA);
Serial.print(buttonB);
Serial.print(firstpotentiometer);
Serial.print("C");
Serial.print(secondpotentiometer);
Serial.print("D");
Serial.println(thirdpotentiometer);
change = buttonA + buttonB + firstpotentiometer + secondpotentiometer + thirdpotentiometer;
delay(50);
}
}
}
import serial
import time
import os

locations=['/dev/ttyUSB0','/dev/ttyUSB1','/dev/ttyUSB2','/dev/ttyUSB3','/dev/ttyS0','/dev/ttyS1','/dev/ttyS2','/dev/ttyS3']
for device in locations:
try:
print "Trying...",device
arduino = serial.Serial(device, 9600)
break
except:
print "Failed to connect on",device
try:
time.sleep(0.5)
while True:
link = arduino.readline()
button1 = link[:1]
button2 = link[1:2]
y = link.find("C")
firstpotentiometer = link[2:y]
x = link.find("C")
y = link.find("D")
secondpotentiometer = link[x+1:y]
x = link.find("D")
thirdpotentiometer = link[x+1:]
if int(button1) == 1:
os.system("xdotool keydown space")
else:
os.system("xdotool keyup space")
if int(button2) == 1:
os.system("xdotool keydown Control_L")
else:
os.system("xdotool keyup Control_L")
print (int(firstpotentiometer))
if int(thirdpotentiometer) >= 80:
os.system("xdotool keydown Right")
else:
os.system("xdotool keyup Right")
if int(thirdpotentiometer) <= 20:
os.system("xdotool keydown Left")
else:
os.system("xdotool keyup Left")
resy = range(0,1080)
resx = range(0,1920)
if int(firstpotentiometer) != 0 and int(secondpotentiometer) != 0:
m = ' '.join(['xdotool mousemove', str(int(firstpotentiometer)*20), str(int(secondpotentiometer)*11)])
#print (m)
os.system(m)
except:
print "Failed to send!"