Please Guide line on Serial Package Control.

Hi,

I was new on C programing on Arduino, i wish like to control 4 servo motors angle by using Serial package.

Please Guide what the best way to read serial and processing.

By the the way i design to send like AB000C000D000E000

A = enable
B = 1st servo. C = 2nd D = 3rd E = 4th.
and 00 that is 000 value of angle.

i try a little abit to read bit by bit but not work perfectly.

Thank in Advance :slight_smile:

Don't try to do it all at once - it'll end in tears.
Just take one servo and work on controlling that.
Make sure you've got a separate power supply for the servos.
You'll need to use something like MegaServo, because the standard servo library only supports two servos.

Start off just using the serial monitor to send your commands to the Arduino, so you're not having to debug and develop two lots of software at the same time.
When you're happy that the Arduino end of things is working, start on the Processing.

Good luck.

Thank

Can anyone guide me the programing code

Start by looking through the learning section for servo examples, maybe start with a pot and a servo, then start learning about the serial interface, and how to receive and convert numbers.

I know how to control Servo,

but i don't know how to Convert Number, wait for someone givem some example

Probably the simplest way is to use the function "atoi".
For this, you need to store the ASCII decimal digits as they arrive, in , say a four byte array (assuming three digit numbers), make sure the last character is a zero ('\0') and then call atoi.

Here is some code I use to test the MegaServo library that should give you an idea of how to do what you want:

#include <MegaServo.h>

#define NBR_SERVOS     12        // the number of servos, up to 48 for Mega, 12 for other boards
#define FIRST_SERVO_PIN 2

MegaServo myServos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

void setup() 
{ 
  Serial.begin(9600); 
  for(int i=0; i < NBR_SERVOS; i++)
    myServos[i].attach(FIRST_SERVO_PIN +i);  
} 


void loop()
{
  static int pos = 0;

  if ( Serial.available())
  {
    char ch = Serial.read();

    if(ch >= '0' && ch <= '9')              // is ch a number?  
      pos = pos * 10 + ch - '0';           // yes, accumulate the value
    else if(ch >= 'a' && ch <= 'a'+  NBR_SERVOS) // is ch a letter for one of our servos?
    {
      myServos[ch - 'a'].write(pos);         // yes, save the position in the position array   
      pos = 0;
      int channel =  ch - 'a';
      int  angle = myServos[channel].read();
      int pulseWidth = myServos[channel].readMicroseconds();
      Serial.print("Servo on pin "); 
      Serial.print(FIRST_SERVO_PIN + channel, DEC);
      Serial.print(": angle = ");  
      Serial.print(angle,DEC),  Serial.print(", pulse = ");  
      Serial.println(pulseWidth,DEC); 
    }
    else if (ch == '*')
    {
      // position all the servos
      for(int i=0; i < NBR_SERVOS; i++)
        myServos[i].write(pos);         
      pos = 0;      
    }
    else if (ch == '+')
    {
      // sweep the servos from 0 to 180
      for(int angle = 0;angle < 180; )
      {
        for(int i=0; i < NBR_SERVOS; i++)
        {
          myServos[i].write(angle);            
        }
        angle = myServos[0].read();     
        Serial.print("Angle = "); Serial.print(angle,DEC), Serial.print(", pulse = "); Serial.println(myServos[0].readMicroseconds(),DEC); 
        ++angle; 

        delay(20);
      }
      pos = 0;      
    }
    else if (ch == '-')
    {
      // sweep the servos from 180 to 0
      for(int angle = 180;angle >= 0; )
      {
        for(int i=0; i < NBR_SERVOS; i++)
        {
          myServos[i].write(angle);                
        }
        angle = myServos[0].read();   
        Serial.print("Angle = "); Serial.print(angle,DEC), Serial.print(", pulse = "); Serial.println(myServos[0].readMicroseconds(),DEC); 
        --angle; 
        delay(20);
      }
      pos = 0;      
    }
  }
}

the code expects a serial command consisting of a valid value (0 through 180) followed by a letter indicating the servo to write to. The letter 'a' is the first servo, 'b' the second and so on.

For example:
90a will write a value of 90 to the first servo
180b will write 180 to the second servo

A value followed by a * instead of a letter will be written to all servos
The single character + will sweep all the servos from 0 to 180
The single character – will sweep all the servos from 180 to 0

Hi mem, just a question... what would be the input pin on the 328 diecimilia board... can i use PB0 (pin 14) or must be Rx pin ( pin 2) ???

thanks in advance

GMV

The pins in that sketch are output pins. You can use any valid pin including pins 14 through 19

oh i see, so as an example and for driving 12 servos, looking at your sketch what would be the first ( i presume pin 2 ???) and last output pin that the code will look at ?

thanks

For 12 servos, if the first pin is 2 then the last pin is 13

the problem i have now is that i have reserved pin 8 as an input on my pcb , so is there any inconvenient to use any analog pin as an input for data coming in ?

thanks

You can create an array to define the pins you want to use.
The sketch below uses pins 2 through 7 and 9 through 14 ( 14 is analog pin 0)

You can change the values used to initialize the servPins array if you want different pins

#include <Servo.h>

#define NBR_SERVOS     12        // the number of servos, up to 48 for Mega, 12 for other boards

Servo myServos[NBR_SERVOS] ; // max servos is 48 for mega, 12 for other boards

const int servPins[NBR_SERVOS] = {2,3,4,5,6,7,9,10,11,12,13,14};

void setup()
{
  Serial.begin(9600);
  for(int i=0; i < NBR_SERVOS; i++)
    myServos[i].attach(servPins[i]);  
}


void loop()
{
  static int pos = 0;

  if ( Serial.available())
  {
    char ch = Serial.read();

    if(ch >= '0' && ch <= '9')              // is ch a number?  
      pos = pos * 10 + ch - '0';           // yes, accumulate the value
    else if(ch >= 'a' && ch <= 'a'+  NBR_SERVOS) // is ch a letter for one of our servos?
    {
      myServos[ch - 'a'].write(pos);         // yes, save the position in the position array  
      pos = 0;
      int channel =  ch - 'a';
      int  angle = myServos[channel].read();
      int pulseWidth = myServos[channel].readMicroseconds();
      Serial.print("Servo on pin ");
      Serial.print(servPins[channel], DEC);
      Serial.print(": angle = ");  
      Serial.print(angle,DEC),  Serial.print(", pulse = ");  
      Serial.println(pulseWidth,DEC);
    }
    else if (ch == '*')
    {
      // position all the servos
      for(int i=0; i < NBR_SERVOS; i++)
        myServos[i].write(pos);        
      pos = 0;
    }
    else if (ch == '+')
    {
      // sweep the servos from 0 to 180
      for(int angle = 0;angle < 180; )
      {
        for(int i=0; i < NBR_SERVOS; i++)
        {
          myServos[i].write(angle);
        }
        angle = myServos[0].read();    
        Serial.print("Angle = "); 
        Serial.print(angle,DEC), Serial.print(", pulse = "); 
        Serial.println(myServos[0].readMicroseconds(),DEC);
        ++angle;

        delay(20);
      }
      pos = 0;
    }
    else if (ch == '-')
    {
      // sweep the servos from 180 to 0
      for(int angle = 180;angle >= 0; )
      {
        for(int i=0; i < NBR_SERVOS; i++)
        {
          myServos[i].write(angle);                
        }
        angle = myServos[0].read();  
        Serial.print("Angle = "); 
        Serial.print(angle,DEC), Serial.print(", pulse = "); 
        Serial.println(myServos[0].readMicroseconds(),DEC);
        --angle;
        delay(20);
      }
      pos = 0;
    }
  }
}

mem, thank again, it looks a lot easier this way, so i can use any analog pin as an output(digital) as well, ok thats nice....

To test this skecth i´ll be using windows Xp hyper terminal and send characters over the arduino to control servos, but in the future i´ll be making another pcb to read any ppm frame (futaba or Multiplex) from the radio trainer port, so i would like to ask you what do you recommend as the best method to read it and send the several servo "pulse width" as characters to the ardu decoder board.

I´ve been searching for info about this for a while and it looks to me that it will take some time till i find the best solution.

thanks

i´ll be making another pcb to read any ppm frame (futaba or Multiplex) from the radio trainer port, so i would like to ask you what do you recommend as the best method to read it and send the several servo "pulse width" as characters to the ardu decoder board.

That depends on what you have on your external PCB. I suggest you start another thread to discuss this so we don't hijack this one.
Post a link here so we can find your new thread.

Ok mem you´re right, i´ve just created this thread... http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1291378785/0#0