Pages: [1]   Go Down
Author Topic: serial control of four servos  (Read 934 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Goal: I am trying to make a serial feed that will allow me to have control of four servos. I want to type in four numbers, the first number will be the servo number and the last three are the angle for the servo.

Ex:  2180 or 1090  will make servo two turn to 180 degrees or make servo one go to 90 degrees, respectively.

problems: my program seems to keep reseting itself. every so many seconds also the servos are only twitching rather than turning.  I have never used the function map() to change values and am unsure if i did it right.  still working on it but please help

code:
Code:
#include<stdlib.h>

int servoPin2 = 2;
int servoPin3 = 3;
int servoPin4 = 4;
int servoPin5 = 5;

int minPulse = 600;
int maxPulse = 2400;

int refreshTime = 20;

int pulseWidth2;
int pulseWidth3;
int pulseWidth4;
int pulseWidth5;

long lastPulse = 0;

char array[4];
byte count = 0;
byte four = 4;

int servo;

void setup ()
{
  pinMode(servoPin2,OUTPUT);
  pinMode(servoPin3,OUTPUT);
  pinMode(servoPin4,OUTPUT);
  pinMode(servoPin5,OUTPUT);
  
  Serial.begin(9600);
  Serial.println ("type in four numbers");
  Serial.println ("first digit is the servo number");
  Serial.println ("last three are anlges");
  Serial.println ("start");
}

void loop ()
{
  count = 0;
      if (Serial.available())     //check to see if i need >0
         {
           do{
               array[count++] = Serial.read();
               delay (20);
           }while(Serial.available() && count <= four); //check to see if this is correct less than sign
           array[count] ='\0';
          
       Serial.print ("you sent");
       Serial.println (array);
    
       char anglay[4] = {array[1],array[2],array[3],'\0'};
       servo = atoi(anglay);
      
       Serial.print ("the servo ");
       Serial.println (array[0]);
      
       Serial.print ("angle measuse of ");
       Serial.println (anglay);
      
            if (array[0] =='1') {pulseWidth2 = map(servo,minPulse,maxPulse,0,179);}
            
            if (array[0] =='2') {pulseWidth3 = map(servo,minPulse,maxPulse,0,179);}
            
            if (array[0] =='3') {pulseWidth4 = map(servo,minPulse,maxPulse,0,179);}
            
            if (array[0] =='4') {pulseWidth5 = map(servo,minPulse,maxPulse,0,179);}
            
            
         }
        
   if (millis()-lastPulse >= refreshTime)
     {
       digitalWrite(servoPin2,HIGH);
       delayMicroseconds(pulseWidth2);   // check if it needs to be micro or milli
       digitalWrite (servoPin2,LOW);
      
       digitalWrite(servoPin3,HIGH);
       delayMicroseconds(pulseWidth3);   // check if it needs to be micro or milli
       digitalWrite (servoPin3,LOW);
      
       digitalWrite(servoPin4,HIGH);
       delayMicroseconds(pulseWidth4);   // check if it needs to be micro or milli
       digitalWrite (servoPin4,LOW);
      
       digitalWrite(servoPin5,HIGH);
       delayMicroseconds(pulseWidth5);   // check if it needs to be micro or milli
       digitalWrite (servoPin5,LOW);
      
       lastPulse = millis();
     }
}

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

alright so i figured out that my map() command was a little backwards and now im getting a decent response from the motors.
unfortunately my charactar array isn't doing so well. it seems to break my entries up every now and then and is very inconsistent. sometimes when i type in 1150 it will only spit out a couple of my numbers...

where im at
Code:
#include<stdlib.h>

int servoPin2 = 2;
int servoPin3 = 3;
int servoPin4 = 4;
int servoPin5 = 5;

int minPulse = 600;
int maxPulse = 2400;

int refreshTime = 20;

int pulseWidth2;
int pulseWidth3;
int pulseWidth4;
int pulseWidth5;

long lastPulse = 0;

char array[4];
byte count = 0;
byte four = 4;

int servo;

void setup ()
{
  pinMode(servoPin2,OUTPUT);
  pinMode(servoPin3,OUTPUT);
  pinMode(servoPin4,OUTPUT);
  pinMode(servoPin5,OUTPUT);
  
  Serial.begin(9600);
  Serial.println ("type in four numbers");
  Serial.println ("first digit is the servo number");
  Serial.println ("last three are anlges");
  Serial.println ("start");
}

void loop ()
{
  count = 0;
      if (Serial.available())     //check to see if i need >0
         {
           do{
               array[count++] = Serial.read();
               delay (1000);
           }while(Serial.available() && count < four); //check to see if this is correct less than sign
           array[count] ='\0';
          
       Serial.print ("you sent");
       Serial.println (array);
    
       char anglay[4] = {array[1],array[2],array[3],'\0'};
       servo = atoi(anglay);
      
       Serial.print ("the servo ");
       Serial.println (array[0]);
      
       Serial.print ("angle measuse of ");
       Serial.println (anglay);
      
            if (array[0] =='1') {pulseWidth2 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='2') {pulseWidth3 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='3') {pulseWidth4 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='4') {pulseWidth5 = map(servo,0,179,minPulse,maxPulse);}
            
            
         }
        
   if (millis()-lastPulse >= refreshTime)
     {
       digitalWrite(servoPin2,HIGH);
       delayMicroseconds(pulseWidth2);   // check if it needs to be micro or milli
       digitalWrite (servoPin2,LOW);
      
       digitalWrite(servoPin3,HIGH);
       delayMicroseconds(pulseWidth3);   // check if it needs to be micro or milli
       digitalWrite (servoPin3,LOW);
      
       digitalWrite(servoPin4,HIGH);
       delayMicroseconds(pulseWidth4);   // check if it needs to be micro or milli
       digitalWrite (servoPin4,LOW);
      
       digitalWrite(servoPin5,HIGH);
       delayMicroseconds(pulseWidth5);   // check if it needs to be micro or milli
       digitalWrite (servoPin5,LOW);
      
       lastPulse = millis();
     }
}

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

particularly with my character array my third charactar that i send gets drop
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

so ive narrowed down the problem with the code. It is something to do with the last if statement causes my array to drop the third charactar. I dont understand why it would do this.. can some one please help?

Code:
#include<stdlib.h>

int servoPin2 = 2;
int servoPin3 = 3;
int servoPin4 = 4;
int servoPin5 = 5;

int minPulse = 600;
int maxPulse = 2400;

int refreshTime = 20;

int pulseWidth2;
int pulseWidth3;
int pulseWidth4;
int pulseWidth5;

long lastPulse = 0;

char array[5];
byte count = 0;
byte four = 4;

int servo;

void setup ()
{
  pinMode(servoPin2,OUTPUT);
  pinMode(servoPin3,OUTPUT);
  pinMode(servoPin4,OUTPUT);
  pinMode(servoPin5,OUTPUT);
  
  Serial.begin(9600);
  Serial.println ("type in four numbers");
  Serial.println ("first digit is the servo number");
  Serial.println ("last three are anlges");
  Serial.println ("start");
}

void loop ()
{count = 0;                                                  
  
      if (Serial.available() > 0)    
         {
          
           do{
               array[count++] = Serial.read();
               delay (1000);
           }while(Serial.available() && count <= 5);
           array[count++] ='\0';
          
       Serial.print ("you sent");
       Serial.println (array);
    
       char anglay[4] = {array[1],array[2],array[3],'\0'};
       servo = atoi(anglay);
      
       Serial.print ("the servo ");
       Serial.println (array[0]);
      
       Serial.print ("angle measuse of ");
       Serial.println (anglay);
      
      
      
            if (array[0] =='1') {pulseWidth2 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='2') {pulseWidth3 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='3') {pulseWidth4 = map(servo,0,179,minPulse,maxPulse);}
            
            if (array[0] =='4') {pulseWidth5 = map(servo,0,179,minPulse,maxPulse);}
            
            
         }
        
   if (millis()-lastPulse >= refreshTime)     // THIS if statement is the reason i lose my third character in the array
     {
       digitalWrite(servoPin2,HIGH);
       delayMicroseconds(pulseWidth2);  
       digitalWrite (servoPin2,LOW);
      
       digitalWrite(servoPin3,HIGH);
       delayMicroseconds(pulseWidth3);  
       digitalWrite (servoPin3,LOW);
      
       digitalWrite(servoPin4,HIGH);
       delayMicroseconds(pulseWidth4);  
       digitalWrite (servoPin4,LOW);
      
       digitalWrite(servoPin5,HIGH);
       delayMicroseconds(pulseWidth5);  
       digitalWrite (servoPin5,LOW);
      
       lastPulse = millis();
     }
}

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

its very quirky and rarely consistent, does the code just have to much happening at once, or does it deal with at what point the code is at in its loop when it uploads the serial.

-confused
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 29
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

alright so as I dig farther into whats wrong... can I even do what I am trying...  I'm trying to set up a program that can run the pins like they were pwm pins. But by trying to do this with multiple pins all of my delays were overlapping and the program just falls apart.  I was wondering if I code break my commands up into arrays like the code for multiple LED page but... with different time delays for each pin I dont know if its possible.  feel free to give input... I fairly stumped at the moment.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm working on a similar problem and have been scouring the forum and the web to find other examples.  I'm curious if you were ever able to solve this effectively or not?

Does anyone have any other examples they'd be willing to share?
Logged

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 331
Posts: 16540
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well the normal way to drive servos is with one of the library servo routines. Is there a reason you are 'bit banging' rather then using the proven library?

http://www.arduino.cc/playground/Code/MegaServo

Lefty
Logged

Pages: [1]   Go Up
Jump to: