Wireless Servo Control

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

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

Switch.pde (1.37 KB)

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.

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

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

Thanks for the help,

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

#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);
    } 
  }
value1 = map(value, '0', '9', 0, 180);

is easier to read, don't you think?

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)

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

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

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.

Whoops! I guess I need a bit more coffee this morning....
Fixed.

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

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.

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.

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

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

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

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?

/*
  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);
    } 
  }
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.

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

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

If you put each { and } on its own line, and use Tools + Auto Format, you will see that you have this structure:

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?

@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 =]