Thursday, 10 September 2015

Remote Robot Arm

Earlier, I set up the Raspberry Pi to communicate with the Ardunio using a Python script. With this in place I can now start putting things together to make something more interesting; for example, controlling the Robot arm.

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