Go Down

Topic: Glitches with Arduino and servo control (Read 943 times) previous topic - next topic

Tripacer

May 21, 2012, 05:24 am Last Edit: May 21, 2012, 05:48 am by Tripacer Reason: 1
I am trying to control two servos with an Arduino Duemilanove with servos connected to pins 8 & 9.

I have a driver program written in Visual Basic that sends two byte via the serial port to the Arduino.  The values range from 0 to 100.  The attached Arduino code reads the values and moves the servos to the correct position.  One function of the driver program send one single pair of values (50,50) and the servos respond with no problem.  Another function sends two groups of 100 pairs of values with one value equal to 0 and the other varying from 100 down to 0.  Randomly both servos will move rapidily out of the normal range of positions and then continue onwards.  I have check the serial data stream with my oscilloscope and there appear to be no data problems.  When I check the pulses coming out of the Arduino they vary normally until the random movement occurs, then return to normal expected values.
 I have been struggling to no avail for the past week or so trying to diagnose this bug and correct it.  I would appreciate any help.

Thanks,  Tripacer

Code: [Select]
//Fuel Tank Control program version 2  : FuelTankControl2.ino
//  external program.  Values range from 0 to 100
// which represents the range of tanks values from empty to full.
//  Values are sent in two byte pairs;  left tank first followed by right tank.



#include <Servo.h>


Servo LeftTank;      // Create a seervo object to control a servo
Servo RightTank;

int  angle;    // variable to store servo position

int  LeftTankVal;
int  RightTankVal;
int   LeftTankReadVal;    // Converted int value
int   RightTankReadVal;

int  LeftTankMin = 30;    // Left tank minimum value
int  LeftTankMax = 125;   // Left tank maximum value
int  RightTankMin = 30;   // Right tank minimum value
int  RightTankMax = 125;  // Right tank maximum value
char CommandVal;          // Input command value
byte  TankVal[2];    // Left and right tank input values
int  LeftTankRange;       // Left tank Min to Max servo movement range
int  RightTankRange;  // Range for right tank
int  i;  // Array index


void setup()
{
 LeftTank.attach(8);    // attach the servo to pin 9 to the servo object
 RightTank.attach(9);  // attach the servo to pin 10
 
 // Set initial servo positions **** if possible in setup block ****
 
 LeftTank.write(LeftTankMin);
 RightTank.write(RightTankMin);

 LeftTankRange = LeftTankMax - LeftTankMin; // Calculate range value
 RightTankRange = RightTankMax - RightTankMin;

 
 Serial.begin(9600);    // Start and configure servial communications

}

void loop()
{

 if (Serial.available() > 0 )
 {
   
   TankVal[0] = Serial.read();
   TankVal[1] = Serial.read();
   // This section zeros the value and converts byte value to int
   LeftTankReadVal = 0;
   LeftTankReadVal = LeftTankReadVal + TankVal[0];
   RightTankReadVal = 0;
   RightTankReadVal = RightTankReadVal + TankVal[1];


 }              
 // End data read

 //  Calculate servo positions - rounds to integer value

   LeftTankVal = (LeftTankRange * LeftTankReadVal) / 100;
   RightTankVal = (RightTankRange * RightTankReadVal) / 100;


 //  Move servo to new position

   LeftTank.write(LeftTankVal);
   RightTank.write(RightTankVal);
 
   delay(20);    //  waits 20ms between servocommands


}   // end of program

zoomkat

A typical newbie mistake is trying to power the servos from the arduino instead of a seperate power supply.
Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   8)

AWOL

...and another is to forget to have common grounds.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

And a third is to assume that serial data transmission is guaranteed to result in all data being transferred.

And a fourth is this classic:
Code: [Select]
  if (Serial.available() > 0 )
  {
   
    TankVal[0] = Serial.read();
    TankVal[1] = Serial.read();

See if there is at least one byte available, then read both of them. For this, you need to whack yourself with a clue-by-four.

Tripacer

Thanks for the suggestions and comments.  However, I have always powered the servos form a separate external power supply with the power supply and the Arduino grounds connect to a common bus.  This has no effect on the problem.
  Also reading the data via a while loop or as outlined in the code above does not change the problem.  Watching the output for the servo signal coming from an Arduino pin shows that a larger time pulse is sent to the servo for positioning. 
  The data sending programing is displaying the values sent to the serial port, and the glitches randomly occur at different points in the sequence.  I suspect some type of timing issue but cannot seem to run it down.

Thanks again :)

Go Up