Arduino Forum

Topics => Robotics => Topic started by: Woehrlec on Aug 01, 2011, 08:40 pm

Title: Wireless Servo Control
Post by: Woehrlec on Aug 01, 2011, 08:40 pm
Greetings all,
I'm trying to create a switch loop that will change the position of a servo given a wireless command.
Not much of a programmer, so please take a look at what I've got. Problems that I've determined are that it does not respond to a second command (Stuck in loop?) and the servo turns to the same position even though its commanded to a different position.

Thanks in advance,

Woehrlec

Code: [Select]
created 30 Jul 2011
by Woehrle

*/
#include <Servo.h>
#include <NewSoftSerial.h>
NewSoftSerial mySerial = NewSoftSerial(2,3);
Servo myservo;
int value = 0; // for incoming serial data
int value1 = 0;
int pos=0;
int orig = 5;
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
 
     
     
        Serial.print("Initalize Servo");
        mySerial.begin(9600);
        myservo.attach(9);
        Serial.print("Servo Initalized");
     
}


void loop() {


  if (mySerial.available() > 0) {
    int inByte = Serial.read();
    value1 = map(value, 48, 57, 0, 180);
    // do something different depending on the character received. 

    switch (inByte) {
    case 'n':    //North
      myservo.write(9);
      break;
    case 's':    //South
      myservo.write(5);
      break;
    case 'o':    //Original or neutral
     myservo.write(0);
      break;
    default:
      // anyother character go to default
      myservo.write(0);
      }
      delay(15);
    }
  }

Title: Re: Wireless Servo Control
Post by: Erni on Aug 01, 2011, 09:18 pm
Hey

One of the problems are the values you are using in the write.servo

case 'n':    //North
     myservo.write(9);
     break;
   case 's':    //South
     myservo.write(5);
     break;
   case 'o':    //Original or neutral
    myservo.write(0);


The values should be between 0 and 180 (degrees) like below.

I haven't used 180 and 0, because it sends my cheap servo over the edge.



Quote

   case 'n':    //North
     myservo.write(150);
   
     break;
   case 's':    //South
     myservo.write(30);
     
     break;
   case 'o':    //Original or neutral
    myservo.write(90);
     
     break;
   default:
     // anyother character go to default
     myservo.write(90);
     }

Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 01, 2011, 10:19 pm
Found the other problem....int inByte = Serial.read(); needs to be int inByte = mySerial.read();

Thanks for the help,

Woehrlec
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 02, 2011, 05:38 am
If I wanted to attach multiple servos... would I create multiple objects for multiple servos? how would I select a specific servo? Would I do a switch with in a switch? Kinda in over my head........

Thanks in advance,

Woehrlec

Here is what I'm currently working with...
Code: [Select]
#include <Servo.h>
#include <NewSoftSerial.h>
NewSoftSerial mySerial = NewSoftSerial(2,3);
Servo servo_a;  // create servo object to control a servo
// a maximum of eight servo objects can be created
Servo servo_b;
Servo servo_c;
int value = 0; // for incoming serial data
int value1 = 0;
int pos=0;
int orig = 5;
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
 
     
     
        Serial.print("Initalize Servo");
        mySerial.begin(9600);
        servo_a.attach(9);
        servo_b.attach(8);
        servo_c.attach(7);
        Serial.print("Servo Initalized");
     
}


void loop() {


  if (mySerial.available() > 0) {
    int inByte = mySerial.read();
    value1 = map(value, 48, 57, 0, 180);
    // do something different depending on the character received. 

    switch (inByte) {
    case 'n':    //North
      servo_a.write(165);
     
      break;
    case 's':    //South
     servo_a.write(10);
       
      break;
    case 'o':    //Original or neutral
     servo_a.write(90);
       
      break;
    default:
      // anyother character go to default
   servo_a.write(90);
   
      }
      delay(15);
    }
  }
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 02, 2011, 08:46 am
Code: [Select]
value1 = map(value, '0', '9', 0, 180);
is easier to read, don't you think?

Quote
how would I select a specific servo?

With a letter representing servo a, b or c? (It may be easier to program if you have an array of three servos, instead of three individuals)
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 02, 2011, 06:09 pm
I took your advice and created an array for the three servos, but now I'm a bit lost on how I will choose the servo and then be able to use the switch command...

Help!..... =]
Like always, thanks in advance

Woehrlec

Code: [Select]
#include <Servo.h>
#include <NewSoftSerial.h>
#define N_SERVOS 3
Servo myServo [N_SERVOS];
const byte servoPin [N_SERVOS] = {7,8,9};
NewSoftSerial mySerial = NewSoftSerial(2,3);
int value = 0; // for incoming serial data
int value1 = 0;
int pos=0;
int orig = 5;
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
 
        Serial.print("Initalize Servo");
        mySerial.begin(9600);
       
        Serial.print("Servo Initalized");
      for (int i = 0; i < N_SERVOS; ++i) {
myServo [i].attach (servoPin [i]);
      }
}


void loop() {


  if (mySerial.available() > 0) {
    int inByte = mySerial.read();
    value1 = map(value, 0, 9, 0, 180);
    // do something different depending on the character received. 

    switch (inByte) {
    case 'n':    //North
      servo_a.write(165);
     
      break;
    case 's':    //South
     servo_a.write(10);
       
      break;
    case 'o':    //Original or neutral
     servo_a.write(90);
       
      break;
    default:
      // anyother character go to default
   servo_a.write(90);
   
      }
      delay(15);
    }
  }
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 02, 2011, 06:11 pm
Quote
value1 = map(value, 0, 9, 0, 180);

Look again...carefully.

You need to define a protocol, like 0a2b4c

Where 0 gets written to the first servo, 2 to the second and 4 to the third.
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 02, 2011, 06:22 pm
Whoops! I guess I need a bit more coffee this morning....
Fixed.
Code: [Select]
if (mySerial.available() > 0) {
    int inByte = mySerial.read();
    value1 = map(value, '0', '9', 0, 180);


What do I do about servo selection now? Conditional while statement? (my level of programming skills are being maxed out)

Thanks,

Woehrlec
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 02, 2011, 06:25 pm
Well, you could loop until you got a character in the range a..c, then assume that the next character will be numeric (or for safety, you could check that it is numeric). When you get the second character, write it to the servo denoted by the first character.
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 02, 2011, 06:59 pm
Would creating three If statements for the servos work? What I mean is if the condition is met, the choosen servo would become the variable within the switch statement? Or is that not possible....I just don't want three huge blocks of code for each If statement.

Any hints? Thanks for all your help so far.

Code: [Select]


    switch (inByte) {
    case 'n':    //North
      myServo [N_SERVOS].write(165);
     
      break;
    case 's':    //South
     myServo [N_SERVOS].write(10);
       
      break;
    case 'o':    //Original or neutral
     myServo [N_SERVOS].write(90);
       
      break;
    default:
      // anyother character go to default
   myServo [N_SERVOS].write(90);
   
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 02, 2011, 07:01 pm
Quote
myServo [N_SERVOS].write(165);

That is never going to work.

Read a character a..c or A..C, subtract 'a' or 'A' to give a number 0..2, and use that as the index
Title: Re: Wireless Servo Control
Post by: mem on Aug 02, 2011, 08:03 pm
I posted some code that my help you here: http://arduino.cc/forum/index.php/topic,67633.msg497265.html#msg497265
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 02, 2011, 11:50 pm
I haven't had much time, but I think the concept of this might work..... the serial will choose the servo first then the direction.
But it doesn't seem to work...lol Hints please?

Code: [Select]
/*
  Switch statement  with mySerial input

Demonstrates the use of a switch statement.  The switch
statement allows you to choose from among a set of discrete values
of a variable.  It's like a series of if statements.

To see this sketch in action, open the Serial monitor and send any character.
The characters N,S, and O will turn on LEDs.  Any other character will turn
the LEDs off.


created 30 Jul 2011
by Woehrle

*/
#include <Servo.h>
#include <NewSoftSerial.h>
#define N_SERVOS 3
Servo myServo [N_SERVOS];
const byte servoPin [N_SERVOS] = {7,8,9};
NewSoftSerial mySerial = NewSoftSerial(2,3);
int value = 0; // for incoming serial data
int value1 = 0;
int pos=0;
int orig = 5;


int counter = 0; //when counter is 2 trigger the servo write
byte dirByte = 0;
byte serByte = 0;
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
 
        Serial.print("Initalize Servo");
        mySerial.begin(9600);
       
        Serial.print("Servo Initalized");
      for (int i = 0; i < N_SERVOS; ++i) {
myServo [i].attach (servoPin [i]);
      }
}


void loop() {


  if (mySerial.available() > 0) {
    int inByte = mySerial.read();
   
    if(counter == 0) serByte = (byte)inByte;
    if(counter == 1)
    {
      dirByte = (byte)inByte;
   
        switch (dirByte)
        {
          case 'n':    //North
            myServo [serByte].write(165);
           
            break;
          case 's':    //South
           myServo [serByte].write(10);
             
            break;
          case 'o':    //Original or neutral
           myServo [serByte].write(90);
             
            break;
          default:
            // anyother character go to default
            myServo [serByte].write(90);
        }
    }
    counter++;
    if(counter == 2) counter = 0;

      delay(15);
    }
  }
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 02, 2011, 11:54 pm
Code: [Select]
if(counter == 0) serByte = (byte)inByte;
    if(counter == 1)
    {
      dirByte = (byte)inByte;
   
        switch (dirByte)
        {
          case 'n':    //North
            myServo [serByte].write(165);

So, you've given up on sending 'a' to 'c' for the servo number, and are sending 0..2 instead?

If that's what you're sending, I think this should work.
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 03, 2011, 12:02 am
I understood the numbers way better than a through c. The code doesn't seem to be responding, but I'll check it out later.

Thanks for all your help
Title: Re: Wireless Servo Control
Post by: AWOL on Aug 03, 2011, 09:25 am
Quote
I understood the numbers way better than a through c

They are all just numbers.
The ASCII character 'a' has the hex val 0x61 (97 decimal), and 'c the value 0x63.
So, if you receive a lower-case alphabetic character and want to convert it to an index 0..2, just subtract 'a'.
Title: Re: Wireless Servo Control
Post by: PaulS on Aug 03, 2011, 01:15 pm
If you put each { and } on its own line, and use Tools + Auto Format, you will see that you have this structure:
Code: [Select]
void loop()
{
  if (mySerial.available() > 0)
  {
    int inByte = mySerial.read();

    if(counter == 0) serByte = (byte)inByte;
// Snipped...
    counter++;
    if(counter == 2) counter = 0;

    delay(15);
  }
}

Now, what possible purpose is there for that delay?
Title: Re: Wireless Servo Control
Post by: Woehrlec on Aug 03, 2011, 04:23 pm
@PaulS Your right, not sure why that delay is there..........

@AWOL Oh, I should of known that.....thanks for the reminder.

I'll try to polish up my code later today.

Thanks =]