Arduino Servo NewSoftSerial

Hi
I’ve been working on a project that controls 6 servos with the Polulu 8 servo controller. I’m syncing the movement of my servos to each frame of a quicktime (25 fps) Using Max/msp. After much head scratching I’ve got it working with 3 servos, but now that I’ve got 6 running, the servos aren’t keeping up. I’m using the old SoftwareSerial library that can only run at 9600 baud. I’ve tried using the NewSoftwareSerial library (which can run at much higher baud rate) but I just get a red and green flashing light. Has anyone used the NewSoftwareSerial library? or could there be another reason for the problem? (I’ve included my code)
Any pointers would be greatly appreciated ( I’m afraid I’m still struggling with Arduino).
Kind regards Conor

// Pololu micro serial servo controller modes
// Software Serial from Arduino example by Tom Igoe
// put() (now position_absolute) & set_speed() functions found on pololu forums & modified
// mike crist 2009-01-03

#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 3

// set up a new serial port
SoftwareSerial softSerial =  SoftwareSerial(rxPin, txPin);

int i = 500;

void setup()
{
  pinMode(rxPin, INPUT);
  digitalWrite(txPin, HIGH); // keeps pololu board from getting spurious signal
  pinMode(txPin, OUTPUT);

  // set the data rate for the hardware serial port
  Serial.begin(9600);
  // set the data rate for the SoftwareSerial port
  softSerial.begin(9600);
  
  
  set_speed(0, 0);
  set_speed(1, 0);
  set_speed(2, 0);
  set_speed(3, 0);
  set_speed(4, 0);
  set_speed(5, 0);
  
  
  
  

 
}

void loop()
{
 
 Serial.flush();
  char inputA[8];
  char inputB[8];
  char inputC[8];
  char inputD[8];
  char inputE[8];
  char inputF[8];
  
  
  memset(inputA, '\0', 8);
  memset(inputB, '\0', 8);
  memset(inputC, '\0', 8);
   memset(inputD, '\0', 8);
  memset(inputE, '\0', 8);
  memset(inputF, '\0', 8);
 
  
  byte inByte = '\0';
  
  
  while(inByte != 'A') {
    inByte = Serial.read(); // Wait for the start of the message
  }
  if(inByte == 'A') {
    while(Serial.available() < 24) { // Wait until we receive 5 characters
      ;
    }
    for (int a=0; a < 24; a++) {
      if( a >= 0 && a <= 3){
      inputA[a] = Serial.read(); // Read the characters into an array
    }
  if( a >= 4 && a <= 7){
      inputB[(a-4)] = Serial.read(); // Read the characters into an array
  }
   if( a >= 8 && a <= 11){
      inputC[(a-8)] = Serial.read(); // Read the characters into an array
  }
  if( a >= 12 && a <= 15){
      inputD[(a-12)] = Serial.read(); // Read the characters into an array
  }
  if( a >= 16 && a <= 19){
      inputE[(a-16)] = Serial.read(); // Read the characters into an array
  }
  if( a >= 20 && a <= 23){
      inputF[(a-20)] = Serial.read(); // Read the characters into an array
  }
  
    }
  } 

 

  int  numberA = atoi(inputA);
   int  numberB = atoi(inputB);
    int  numberC = atoi(inputC);
    int  numberD = atoi(inputD);
   int  numberE = atoi(inputE);
    int  numberF = atoi(inputF);
    
    
    
    
    
position_absolute(0, numberA);
position_absolute(1, numberB);
position_absolute(2, numberC);
position_absolute(3, numberD);
position_absolute(4, numberE);
position_absolute(5, numberF);



}



 



void position_absolute(byte servo, int angle)
{
  //this function uses pololu mode command 4 to set absolute position
  //servo is the servo number (typically 0-7)
  //angle is the absolute position from 500 to 5500

   unsigned int temp;
   byte pos_hi,pos_low;

   temp = angle & 0x1f80;  //get bits 8 thru 13 of position
   pos_hi = temp >> 7;     //shift bits 8 thru 13 by 7
   pos_low = angle & 0x7f; //get lower 7 bits of position

   //Send a Pololu Protocol command
   softSerial.print(0x80, BYTE);    //start byte
   softSerial.print(0x01, BYTE);    //device id
   softSerial.print(0x04, BYTE);    //command number
   softSerial.print(servo, BYTE);   //servo number
   softSerial.print(pos_hi, BYTE);  //bits 8 thru 13
   softSerial.print(pos_low, BYTE); //bottom 7 bits
}

void set_speed(byte servo, byte speedVal)
{
   //this function uses pololu mode command 1 to set speed
   //servo is the servo number (typically 0-7)
   //speedVal is servo speed (1=slowest, 127=fastest, 0=full)
   //set speedVal to zero to turn off speed limiting

   speedVal = speedVal & 0x7f; //take only lower 7 bits of the speed

   //Send a Pololu Protocol command
   softSerial.print(0x80,BYTE);     //start byte
   softSerial.print(0x01,BYTE);     //device id
   softSerial.print(0x01,BYTE);     //command number
   softSerial.print(servo,BYTE);    //servo number
   softSerial.print(speedVal,BYTE); //speed
}

Are there any devices on those two software serial lines besides the Arduino and the Pololu servo controller? -David

Hi
No, just the arduino, servo controller and my computer.
Conor

Hi
I thought I would include the code I’ve been using with the NewSoftSerial, as soon as I replaced my old code with this I got the red light and flashing green. Can anyone help it’s driving me mad.
Regards Conor

#include <NewSoftSerial.h>


NewSoftSerial softSerial(2, 3);

// set up a new serial port




void setup()
{
  //pinMode(2, INPUT);
  digitalWrite(3, HIGH); // keeps pololu board from getting spurious signal
  pinMode(3, OUTPUT);

  // set the data rate for the hardware serial port
  Serial.begin(9600);
  // set the data rate for the SoftwareSerial port
  softSerial.begin(9600);


  set_speed(0, 0);
  set_speed(1, 0);
  set_speed(2, 0);
  set_speed(3, 0);
  set_speed(4, 0);
  set_speed(5, 0);






}

void loop()
{

  Serial.flush();
  char inputA[8];
  char inputB[8];
  char inputC[8];
  char inputD[8];
  char inputE[8];
  char inputF[8];


  memset(inputA, '\0', 8);
  memset(inputB, '\0', 8);
  memset(inputC, '\0', 8);
  memset(inputD, '\0', 8);
  memset(inputE, '\0', 8);
  memset(inputF, '\0', 8);


  byte inByte = '\0';


  while(inByte != 'A') {
    inByte = Serial.read(); // Wait for the start of the message
  }
  if(inByte == 'A') {
    while(Serial.available() < 24) { // Wait until we receive 12 characters
      ;
    }
    for (int a=0; a < 24; a++) {
      if( a >= 0 && a <= 3){
        inputA[a] = Serial.read(); // Read the characters into an array
      }
      if( a >= 4 && a <= 7){
        inputB[(a-4)] = Serial.read(); // Read the characters into an array
      }
      if( a >= 8 && a <= 11){
        inputC[(a-8)] = Serial.read(); // Read the characters into an array
      }
      if( a >= 12 && a <= 15){
        inputD[(a-12)] = Serial.read(); // Read the characters into an array
      }
      if( a >= 16 && a <= 19){
        inputE[(a-16)] = Serial.read(); // Read the characters into an array
      }
      if( a >= 20 && a <= 23){
        inputF[(a-20)] = Serial.read(); // Read the characters into an array
      }

    }
  } 



  int  numberA = atoi(inputA);
  int  numberB = atoi(inputB);
  int  numberC = atoi(inputC);
  int  numberD = atoi(inputD);
  int  numberE = atoi(inputE);
  int  numberF = atoi(inputF);





  position_absolute(0, numberA);
  position_absolute(1, numberB);
  position_absolute(2, numberC);
  position_absolute(3, numberD);
  position_absolute(4, numberE);
  position_absolute(5, numberF);



}







void position_absolute(byte servo, int angle)
{
  //this function uses pololu mode command 4 to set absolute position
  //servo is the servo number (typically 0-7)
  //angle is the absolute position from 500 to 5500

  unsigned int temp;
  byte pos_hi,pos_low;

  temp = angle & 0x1f80;  //get bits 8 thru 13 of position
  pos_hi = temp >> 7;     //shift bits 8 thru 13 by 7
  pos_low = angle & 0x7f; //get lower 7 bits of position

  //Send a Pololu Protocol command
  softSerial.print(0x80, BYTE);    //start byte
  softSerial.print(0x01, BYTE);    //device id
  softSerial.print(0x04, BYTE);    //command number
  softSerial.print(servo, BYTE);   //servo number
  softSerial.print(pos_hi, BYTE);  //bits 8 thru 13
  softSerial.print(pos_low, BYTE); //bottom 7 bits
}

void set_speed(byte servo, byte speedVal)
{
  //this function uses pololu mode command 1 to set speed
  //servo is the servo number (typically 0-7)
  //speedVal is servo speed (1=slowest, 127=fastest, 0=full)
  //set speedVal to zero to turn off speed limiting

  speedVal = speedVal & 0x7f; //take only lower 7 bits of the speed

  //Send a Pololu Protocol command
  softSerial.print(0x80,BYTE);     //start byte
  softSerial.print(0x01,BYTE);     //device id
  softSerial.print(0x01,BYTE);     //command number
  softSerial.print(servo,BYTE);    //servo number
  softSerial.print(speedVal,BYTE); //speed
}

Hi conor,

It helps a lot if you wrap your code with [code] tags. It’s easy to do: highlight your code in the post text editor and click the code button above the editor.

- Ryan

Thanks Ryan I’ll remember that in future.
Cheers Conor