Pages: [1] 2   Go Down
Author Topic: Wireless Servo Control  (Read 2718 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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 - downloaded 10 times.)
Logged

Denmark
Offline Offline
Edison Member
*
Karma: 36
Posts: 1082
Happy Hobbyist
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

« Last Edit: August 01, 2011, 02:24:06 pm by Erni » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Thanks for the help,

Woehrlec
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26471
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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)
« Last Edit: August 02, 2011, 02:19:38 am by AWOL » Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26471
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: August 02, 2011, 11:14:24 am by AWOL » Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Whoops! I guess I need a bit more coffee this morning....
Fixed.
Code:
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
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26471
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

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

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26471
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

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

London
Offline Offline
Tesla Member
***
Karma: 10
Posts: 6255
Have fun!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 308
Posts: 26471
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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.
« Last Edit: August 02, 2011, 04:58:59 pm by AWOL » Logged

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

Offline Offline
Newbie
*
Karma: 0
Posts: 9
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1] 2   Go Up
Jump to: