Go Down

Topic: Servo problems... (Read 2 times) previous topic - next topic

rdeans

Yes, the output on the serial monitor corresponds to the movement. This is what I get in the serial monitor throughout about 30 seconds.. in that time, the servo moves about once a second.
Code: [Select]

LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=206 SENTENCES=1 CSUM ERR=0
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=548 SENTENCES=3 CSUM ERR=0
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=963 SENTENCES=5 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=1235 SENTENCES=7 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=1507 SENTENCES=9 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=1779 SENTENCES=11 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=2172 SENTENCES=12 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=2499 SENTENCES=15 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=2771 SENTENCES=17 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=3043 SENTENCES=19 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=3315 SENTENCES=21 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=3763 SENTENCES=23 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=4035 SENTENCES=25 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=4307 SENTENCES=27 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=4579 SENTENCES=29 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=4851 SENTENCES=31 CSUM ERR=1
LAT=42.241939 LON=-83.009277 SAT=6 PREC=190 distance is greater 60.00 course is case 2 39.00 CHARS=5299 SENTENCES=33 CSUM ERR=1


thanks for your help

PaulS

Code: [Select]
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
    }
  }

Using a while loop where appropriate, instead of twisting a for loop out of shape, would be a good idea.

Code: [Select]
float distanceangle;
  if (distance <= 100){
  distanceangle =int(-0.6*distance + 120);

Declare a variable of type float. Compute a float value. Cast it to an int and store in the float. I wonder why more people don't do that.

The indenting of
                     your code makes
          it really
                             hard to
follow. Use the Tools + Auto Format
                         menu item to do something
      about it.

Simplifying your output would be useful. Print millis(), distanceangle, and courseangle only. If you are not changing the value written to the servo on any given pass through loop, but the servo still moves, it is underpowered or undersized.

How are you powering the servos?

PeterH

Looks to me as if the GPS input is being received on average twice a second, there was only one error, the GPS position was consistent throughout and the commanded servo angle was 39 degrees throughout.

If the servo moved during that time then either there's a problem with the servo itself (or wiring/power supply etc), or memory corruption causing the servo's internal state to be corrupted, or a timing issue preventing the Servo class from outputting the PWM pulses accurately. It seems unlikely that a timing issue would occur consistently so the third option seems unlikely. I suggest you check the free memory immediately before doing the gps.encode and see whether you're anywhere near running out. I haven't looked at the gps implementation but presumably it's got a buffer big enough to hold at least a complete sentence, so it'll be a bit of a memory hog. It's also possible that gps.encode itself uses significant stack or heap space , so unless your freeMemory check shows you have hundreds of bytes to spare I would suggest you also look under the covers of the GPS library and see whether the memory consumption is likely to be static, or changing significantly over time. (If it's changing, then your free memory checks won't tell you what the peak consumption is unless you put them INSIDE the library.)
I only provide help via the forum - please do not contact me for private consultancy.

rdeans

hi:

I'm running the servos off of the 5V power supply on the Arduino. I've made the changes to code:
Code: [Select]
#include <SoftwareSerial.h>
#include "TinyGPS.h"
#include <Servo.h>

/* This sample code demonstrates the normal use of a TinyGPS object.
It requires the use of SoftwareSerial, and assumes that you have a
4800-baud serial GPS device hooked up on pins 3(rx) and 4(tx).
*/

Servo panservo;
Servo tiltservo;

TinyGPS gps;
SoftwareSerial ss(3, 4);

float dest_latitude =42.24707;
float dest_longitude =-83.00085;
float distance;
float distanceangle;

void setup()
{
  Serial.begin(115200);
  ss.begin(9600);

  panservo.attach(9);
  tiltservo.attach(10);
  Serial.print("Simple TinyGPS library v. ");
  Serial.println(TinyGPS::library_version());
  Serial.println("by Mikal Hart");
  Serial.println();
}

void loop()
{
  bool newData = false;
  unsigned long chars;
  unsigned short sentences, failed;

  // For one second we parse GPS data and report some key values
  for (unsigned long start = millis(); millis() - start < 1000;)
  {
    while (ss.available())
    {
      char c = ss.read();
      // Serial.write(c); // uncomment this line if you want to see the GPS data flowing
      if (gps.encode(c)) // Did a new valid sentence come in?
        newData = true;
Serial.print("Millis() is ");
Serial.print(millis()); 
  }
   
  }

 
  if (newData)
  {
    float flat, flon;
    unsigned long age;
    gps.f_get_position(&flat, &flon, &age);



    float distance = (TinyGPS::distance_between(flat, flon, dest_latitude, dest_longitude ));
    float distanceangle;
    if (distance <= 100){
      distanceangle =int(-0.6*distance + 120);
      Serial.print(" distance is less");
      Serial.print( distanceangle);
      tiltservo.write(distanceangle);
    }

    else {
      distanceangle = 60;
      Serial.print(" distance is greater ");
      Serial.print( distanceangle);
      tiltservo.write(distanceangle);
    }

    float course =  (TinyGPS::course_to(flat, flon, dest_latitude, dest_longitude ));
    float courseangle;
    if (270 <= course && course <= 360){
      courseangle = int(-course + 450);
      Serial.print (" course is case 1 ");
      Serial.print ( courseangle);
      panservo.write(courseangle);

    }
    else if (0 <= course && course <= 90){
      courseangle = int(-course + 90);
      Serial.print (" course is case 2 ");
      Serial.print ( courseangle);
      panservo.write(courseangle);

    }
    else if (90 < course && course < 180){
      courseangle = 0;
      Serial.print (" course is case 3 ");
      Serial.print ( courseangle);
      panservo.write(courseangle);


    }

    else if (180 <= course && course < 270){
      courseangle = 180;
      Serial.print (" course is case 4 ");
      Serial.print ( courseangle);
      panservo.write(courseangle);

    }

  }


}


This is what I'm getting in the Serial monitor:
Millis() is 150
Millis() is 159
Millis() is 166
Millis() is 174
Millis() is 182
Millis() is 190
Millis() is 198
Millis() is 206
etc...

The distanceangle and courseangle values have not changed.

Thanks

rdeans

PeterH


I'm running the servos off of the 5V power supply on the Arduino.


I suspect that's your problem then.
I only provide help via the forum - please do not contact me for private consultancy.

Go Up