The first script itself was very basic, sending a few fixed characters with sleeps. To make this more interactive I need to be able to read characters from the keyboard.
I based my new controller script on an example in the Python FAQ. The main difference to the boilerplate sample is I write the character to the serial port that the Ardunio is listening on.
import termios,
fcntl, sys, os, serial
ardiuno =
serial.Serial('/dev/ttyUSB0')
fd =
sys.stdin.fileno()
# Get state of
tty and take a copy
oldterm =
termios.tcgetattr(fd)
newattr =
termios.tcgetattr(fd)
# Turn off echo,
line buffering and special character processing
newattr[3] =
newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd,
termios.TCSANOW, newattr)
oldflags =
fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd,
fcntl.F_SETFL, oldflags | os.O_NONBLOCK)
try:
while 1:
try:
c = sys.stdin.read(1)
# repr() : Return a string
containing a printable
#
representation of an object
ardiuno.write(c)
print "Got character",
repr(c)
except IOError: pass
finally:
# restore old state
termios.tcsetattr(fd, termios.TCSAFLUSH,
oldterm)
tcntl.fcntl(fd, fcntl.F_SETFL, oldflags)
The Arduino code is based on my original robot arm controller project. The motors are now engaged by bytes read from serial input.
- o and m : forward and backwards on channel A
- l and k : forward and backwads on channel B
- Space ' ' : Stop all movement
// Motor
controlled by serial inputs
long ii = 0;
byte inByte;
void setup() {
// initialise serial comms at 9600 baud
Serial.begin(9600);
//Setup Channel A
pinMode(12, OUTPUT); // Initialise Motor Channel A pin -
DIRECTION
pinMode(9, OUTPUT); // Initialise Brake Channel A pin - BRAKE
//Setup Channel B
pinMode(13, OUTPUT); // Initialise Motor Channel B pin -
DIRECTION
pinMode(8, OUTPUT); // Initialise Brake Channel B pin - BRAKE
Serial.println("Started");
}
void loop() {
while (Serial.available() > 0)
{
inByte = Serial.read();
if (inByte > 0)
{
Serial.println(inByte);
}
if (inByte == 108) // 'l'
{
digitalWrite(12, HIGH); // Establish forward direction of Channel A
digitalWrite(9, LOW); // Disengage the break for Channel A
digitalWrite(8, HIGH); // Engage the Brake for Channel B
analogWrite(3,244); // Spin the motor on Channel A at full
speed
}
if (inByte == 107) // 'k'
{
digitalWrite(12, LOW); // Establishes backward direction of
Channel A
digitalWrite(9, LOW); // Disengage the Brake for Channel A
digitalWrite(8, HIGH); // Engage the Brake for Channel B
analogWrite(3, 244); // Spin the motor on Channel A at half
speed
}
if (inByte == 111) //'o'
{
// digitalWrite(13,HIGH);
digitalWrite(13, HIGH); // Establish forward direction of Channel B
digitalWrite(8, LOW); // Disengage the break for Channel B
digitalWrite(9, HIGH); // Engage the Brake for Channel A
analogWrite(11,244); // Spin the motor on Channel B at full
speed
}
if (inByte == 109 ) //'m'
{
// digitalWrite(13,LOW);
digitalWrite(13, LOW); // Establishes backward direction of
Channel B
digitalWrite(8, LOW); // Disengage the Brake for Channel B
digitalWrite(9, HIGH); // Engage the Brake for Channel A
analogWrite(11, 244); // Spins the motor on Channel B at half
speed
}
if (inByte == 32) //' '
{
digitalWrite(8, HIGH); // Engage the Brake for Channel B
digitalWrite(9, HIGH); // Engage the Brake for Channel A
}
}
}
That's really all there is to it. It's amazing what can be done with such a small amount of code!
To move the Robot, I log on to the Raspberry Pi using VNC from the laptop. Then run the python script and hit the control keys to engage (or stop!) the motors. As I'm connecting to the Raspberry Pi over wifi, there is no need for the control to be near the robot.
Of course with only a dual channel motor controller I've not got much flexibility in what I can do with the arm but I hope to add another ardunio/controller.
Here is the completed set-up.
No comments:
Post a Comment