Pages: [1] 2   Go Down
Author Topic: My Servo won't move [SOLVED]  (Read 1432 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have a program that receives data over Serial1 of the mega 2560. The data is a series of bytes that represent a number in english from about -10 to 10, followed by an 'E'. anyway, what this is supposed to do is map the number to 0 to 179 for the servo, and write it to the motor. The problem is that after initially moving the servo to 90, nothing happens to the servo. I know from the Serial output that the values are being manipulated correctly, so it is definitely a problem with the implementation of Servo. The hardware is right because the servo sweep example works. Any ideas? Also, if anyone knows an easier way to cast from a character array to a float, that would be much appreciated.

Code:
#include <Servo.h>

char byteIn;
char numberChar[6];
int sVal;
int x;
int y;
float number = 0.000;
Servo myservo;

void setup() {
  Serial1.begin(9600);       // start serial communication at 9600bps
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(90);
}

void loop()
{
  if (Serial1.available())
  {
    byteIn = Serial1.read();
    if (byteIn == 'E')
    {
     x = 0;
     y = 0;
     if (numberChar[0]=='-')\
     {
      y = 1;
     }
     number = numberChar[0+y]-'0';
     number += ((numberChar[2+y]-'0')/10.0);
     number += ((numberChar[3+y]-'0')/100.0);
     number += ((numberChar[4+y]-'0')/1000.0);
     if (numberChar[0]=='-')\
     {
      number = number*-1;
     }
     sVal = (int)map(number, -10, 10, 0, 179);
     myservo.write(sVal);
     Serial.println(number);
     Serial.println(sVal);
     delay(10);
    }
    else
    {
     numberChar[x] = byteIn;
     x++;
    }
  }
}
« Last Edit: November 14, 2012, 03:03:47 pm by InventiousTech » Logged

UK
Offline Offline
Shannon Member
****
Karma: 184
Posts: 11164
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Those Serial print statements are rather anonymous so it'd be easy to be mistaken about which value is which. I suggest you prefix each output with the name of the value you're printing. If you still think the number processing part is correct, then post the input and output from running the sketch and describe what the servo does.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Offline Offline
Newbie
*
Karma: 0
Posts: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wow, that was fast. Ok. how about this:

Code:
#include <Servo.h>

char byteIn;
char numberChar[6];
int sVal;
int x;
int y;
float number = 0.000;
Servo myservo;

void setup() {
  Serial1.begin(9600);       // start serial communication at 9600bps
  Serial.begin(9600);
  myservo.attach(9);
  myservo.write(90);
}

void loop()
{
  if (Serial1.available())
  {
    byteIn = Serial1.read();
    if (byteIn == 'E')
    {
     x = 0;
     y = 0;
     if (numberChar[0]=='-')\
     {
      y = 1;
     }
     number = numberChar[0+y]-'0';
     number += ((numberChar[2+y]-'0')/10.0);
     number += ((numberChar[3+y]-'0')/100.0);
     number += ((numberChar[4+y]-'0')/1000.0);
     if (numberChar[0]=='-')\
     {
      number = number*-1;
     }
     sVal = (int)map(number, -10, 10, 0, 179);
     myservo.write(sVal);
     Serial.print("Raw value: ");
     Serial.println(number);
     Serial.print("Servo angle: ");
     Serial.println(sVal);
     Serial.println();
     delay(10);
    }
    else
    {
     numberChar[x] = byteIn;
     x++;
    }
  }
}

The input is actually coming from a python script running on scripting layer for android (SL4A) over bluetooth through a JY-MCU module to the Serial1 input, so it's a little hard to tell you exactly what is coming in, given that the data goes through a couple layers of android data manipulation then the bluetooth module, but I can tell you with reasonable certainty that the value coming in (for this example) is "5.057" as a series of bytes through Serial1. The output is

Raw value: 5.06
Servo angle: 134


So yes, I am pretty sure the data is right. The servo essentially does nothing. Hence the problem, since it started at 90 degrees and should be at 134.
Logged

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

Can I introduce you to a good friend of mine?

How is the servo connected and powered?
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.

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
     number = numberChar[0+y]-'0';
     number += ((numberChar[2+y]-'0')/10.0);
     number += ((numberChar[3+y]-'0')/100.0);
     number += ((numberChar[4+y]-'0')/1000.0);
0, 2, 3, 4? Are you missing a finger?
Logged

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

No, he's missing the point   smiley-wink
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: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Lol, yes I am missing the point.  smiley-wink
As to the servo, the white is connected to pin 9, the red is on VIN (Straight to the USB cable powering the device), and the black is obviously ground. Servos usually don't draw more than 50 mA, or so I have read, and USB can supply up to 500mA, so I think power is fine. What makes me think the wiring is good is that the "sweep" example works fine. I am at rather a loss here, not even getting any errors. I tried myservo.writeMicroseconds, mapping the data between 1000 and 2000, but that didn't work either.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Servos usually don't draw more than 50 mA
Bullpoop. Servos can pull up to an amp under load.

If your servo works with the sweep example, then the problem isn't with the servo or the wiring. It is with the input that you are sending it, or the way you are processing that input.

What are you sending the Arduino? From what?

Logged

Valencia, Spain
Offline Offline
Faraday Member
**
Karma: 118
Posts: 4549
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What happens if you set the servo to 0 degrees in setup?
Logged

No, I don't answer questions sent in private messages...

Offline Offline
Newbie
*
Karma: 0
Posts: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Paul, yes, but this servo is not under load, as I am just testing it. As to the input, my thoughts exactly. Read my first two posts to see what the input is.
If I set it to 0, then it goes to 0 and stays there for the duration of the program. Currently it goes to 90 and stays there.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Read my first two posts to see what the input is.
You've explained what you think they are, not what they actually are, or where the input is coming from. Let's start with some really simple questions, one at a time.

Are you using the Serial Monitor to send data to the Arduino?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Au contraire, mon ami. I have explained exactly where the data is coming from. It originates in an android phone, it is sent by a python script to the JY-MCU bluetooth module connected to the Serial1 input of the Arduino Mega 2560. The data received by the bluetooth chip is sent to the arduino, fed into a character array until the program hits the end character 'E', then it converts the character array to a floating point number, maps it to the servo's range of 0 to 179, and sends it to the servo via myservo.write(sVal). The data is sent to the computer via Serial both before and after mapping and appears to be correct. Another possibly related issue is that I have the program set up to go to the thousandths place on the float value, but I appear to only be getting hundredths. For a specific example, refer to my second post.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 548
Posts: 46042
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The reason for the questions about the source of the data are because you are assuming that EVERY character read from the serial port is useful, and goes in a specific spot. If the sender is tacking a carriage return/line feed after the E, that will screw up the next iteration, since the carriage return and line feed are going where you expect the ones digit and the decimal point.

Quote
but I appear to only be getting hundredths.
Getting? Or printing?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 13
Against Stupidity, the gods themselves contend in vain.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes, I see your point, but no there is no carriage return at the end of transmission. If I create a program that just  relays information from one serial to another, I just get a long string of numbers separated by 'E's. Also, I know that's not the case because the data being printed to the computer would also be screwed up, but it's not. About the precision, I am wondering what would cause there to be a difference between calculating hundredths and printing hundredths. By the way, thanks for the help so far.
Just for clarity, here is the python script on the phone:

Code:
import android, time

BT_DEVICE_ID = '00:12:09:13:97:48'

droid = android.Android()
droid.bluetoothConnect('00001101-0000-1000-8000-00805F9B34FB', BT_DEVICE_ID)
x = 0
while x<100:
droid.startSensingTimed(1, 25)
time.sleep(0.1)
s4 = droid.sensorsReadAccelerometer().result
droid.stopSensing()
ret = round(s4[1], 3)
droid.bluetoothWrite(str(ret)+"E")
print(ret)
x += 1

exit()
« Last Edit: November 14, 2012, 08:15:53 am by InventiousTech » Logged

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

Quote
, I am wondering what would cause there to be a difference between calculating hundredths and printing hundredths.
The default two places of decimals for the "print" method?
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.

Pages: [1] 2   Go Up
Jump to: