Go Down

Topic: Wireless Servo Control (Read 2 times) previous topic - next topic

Woehrlec

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);
    }
  }


Erni

#1
Aug 01, 2011, 09:18 pm Last Edit: Aug 01, 2011, 09:24 pm by Erni Reason: 1
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);
     }


Woehrlec

Found the other problem....int inByte = Serial.read(); needs to be int inByte = mySerial.read();

Thanks for the help,

Woehrlec

Woehrlec

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);
    }
  }

AWOL

#4
Aug 02, 2011, 08:46 am Last Edit: Aug 02, 2011, 09:19 am by AWOL Reason: 1
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)
"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.

Woehrlec

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);
    }
  }

AWOL

#6
Aug 02, 2011, 06:11 pm Last Edit: Aug 02, 2011, 06:14 pm by AWOL Reason: 1
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.
"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.

Woehrlec

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

AWOL

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.
"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.

Woehrlec

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);
   

AWOL

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
"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.

mem

I posted some code that my help you here: http://arduino.cc/forum/index.php/topic,67633.msg497265.html#msg497265

Woehrlec

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);
    }
  }

AWOL

#13
Aug 02, 2011, 11:54 pm Last Edit: Aug 02, 2011, 11:58 pm by AWOL Reason: 1
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.
"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.

Woehrlec

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

Go Up