Arduino Compatible Robot Controller 2

image

We’re getting pretty close to finishing up the Arduino compatible robot controller design.  We’ve completed the design, re-design, prototype, re-prototype, assembly, and initial testing (those “re-’s” are not always required).

Still to come are some testing,  cost analysis, documentation, and production.  The design marries the open source Ardunio platform with an open-source PIC based controller design we’re also expecting to produce.  When put together you get a versatile Arduino compatible controller that has built-in capability for controlling motors and hobby servos.

Two lines of the Atmel microcontroller create a serial interface to the PIC16F1829.  Through these lines you send commands that can read up to 4 hobby servo pulses (up to 2.55mS in 10uS intervals, generate pulses to control the position of 4 hobby servos (10uS intervals), and control the speed and direction of 2 DC motors (6-24V, about 1A each).

Here’s a code example of an Arduino program that interfaces to the PIC.  This software was written as an example interface and test of the stand-alone motor/servo controller (breakout module 11).  But since this design just takes that module and adds it to an Arduino compatible circuit it works here as well.  Our communication protocol (whose documentation is not quite complete) describes the various registers in the motor/servo controller and what they do.

But you can get the gist of how this controller works by reviewing this code.   To control motor speed and direction you write a value to one of 2 registers (1 register for each motor).  To control the output pulse for the 4 servos you write to one of 4 registers (1 register for each outgoing pulse channel).  To read incoming pulses from an RC receiver you read 1 of 4 registers (1 register for each input pulse channel).

/*
  BM011 Dual Motor Quad Servo Controller Communication example

 The circuit: 
 * RX is digital pin 2 (connect to TX of other device)
 * TX is digital pin 3 (connect to RX of other device)

 */
#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // Receive data on 2, send data on 3
byte SerialTXBuffer[10];
byte SerialRXBuffer[10];

void setup()  
{
 // Open serial communications and wait for port to open:
  Serial.begin(2400);
  mySerial.begin(9600);
}

/* WriteRegister:
Writes a single byte, "Value",  to the register pointed at by "Index".  
Returns the response 

*/
byte WriteRegister(byte Index, byte Value)
{
byte i = 0;
byte checksum = 0;
byte ack = 0;

SerialTXBuffer[0] = 210;
SerialTXBuffer[1] = 1;
SerialTXBuffer[2] = 3;
SerialTXBuffer[3] = Index;
SerialTXBuffer[4] = Value;

for (i=0;i<6;i++)
  {
  if (i!=5)
    {
    mySerial.write(SerialTXBuffer[i]);
    checksum += SerialTXBuffer[i];    
    }
  else
    mySerial.write(checksum);     
  }
  delay(5);

  if (mySerial.available())
    ack = mySerial.read();

  return ack;
} 

byte ReadRegister(byte Index)
{
byte i = 0;
byte checksum = 0;
byte response;

SerialTXBuffer[0] = 209;
SerialTXBuffer[1] = 1;
SerialTXBuffer[2] = 2;
SerialTXBuffer[3] = Index;
SerialTXBuffer[4] = 1;

for (i=0;i<6;i++)
  {
  if (i!=5)
    {
    mySerial.write(SerialTXBuffer[i]);
    checksum += SerialTXBuffer[i];    
    }
  else
    mySerial.write(checksum);     
  }
  for (i=0;i<4;i++)
    {
    do{
    }while(!mySerial.available());
    SerialRXBuffer[i] = mySerial.read();
    }

  response = SerialRXBuffer[2];  
  return response;
} 

void loop() // run over and over
{

  // Set motor1 to +50% and motor2 to -50% duty cycle
  WriteRegister(9,190);
  delay(10);
  WriteRegister(10,67);
  delay(10);

  // Set each servo out register to 1.25mS pulse width
  WriteRegister(11,125);
  delay(10);
  WriteRegister(12,125);
  delay(10);
  WriteRegister(13,125);
  delay(10);
  WriteRegister(14,125);
  delay(10);

  // Read all servo pulse input registers and display them 
  // using the serial monitor
    Serial.print("Servo In1=");      
    Serial.print(ReadRegister(5));      
    delay(100);

    Serial.print(" Servo In2=");      
    Serial.print(ReadRegister(6));      
    delay(100);

    Serial.print(" Servo In3=");      
    Serial.print(ReadRegister(7));      
    delay(100);

    Serial.print(" Servo In4=");      
    Serial.println(ReadRegister(8));      
    delay(100);
}

Trackbacks

  1. […] been much time to a lot to just doing fun things.  As part of the design effort going into an Arduino clone that control servos and motors independent of the Arduino Atmel part we put together an experimental chassis.  The chassis […]

Speak Your Mind

*