That's a little hard to believe. That means that you are getting, parsing and using a complete sentence from the GPS approximately every 8 milliseconds, at 9600 baud, or 125 per sentences per second. I don't believe that that is the case.
PaulS:
That means that you are getting, parsing and using a complete sentence from the GPS approximately every 8 milliseconds, at 9600 baud, or 125 per sentences per second.
No, it doesn't mean that. It means that a single character is being received in that time - which is credible.
The Serial.print() statements are inside the if(gps.decode(c)) block, which, according to the comment, returns true only when the end of sentence marker arrives. So, that looks to me like they should happen only when the $ at the end of the NMEA sentence arrives.
Never mind. I went back and looked at the code. I assumed some curly braces that were not really there.
OP: I wanted you to print the time only when you got a complete sentence, so we could see how long that was taking.
It's a good idea to always use curly braces, so that you can add code to a block (or not), and it is clear that the code is (or is not) part of a block.
I'm in Grade 10 and I don't have much experience with engineering or arduino. How would I specifically hook up the servos and arduino? For example, how would I connect the 4 x 1.5 V batteries to the servo, and how would I establish a common ground for the arduino and servos.
Arduino still gets its power which ever way suits you, eg from its USB or barrel
Servo gets its power from those batteries, straight into its red and black
The common ground joins servo black to Arduino ground: without that the signal on the yellow from Arduino pin to servo has no "0" and so its level has no meaning.
I just showed this with breadboard, but of course you can hang this together any way that works for you.
However: the servos are still not staying at the right location. Even the tilt servo is moving from the correct degree to about 180 degrees and back again. I think the problem must be in the code because the batteries seem to make no difference. I wrote a similar program to just move the servo to a position - the program worked perfectly, there were no jitters - the servos held their correct position.
Here is the "similar code"
#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;
float dest_latitude =42.24707;
float dest_longitude =-83.00085;
float distance =50;
float distanceangle;
float course = 50;
float courseangle;
void setup()
{
Serial.begin(115200);
panservo.attach(9);
tiltservo.attach(10);
}
void loop()
{
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);
}
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);
}
}
It seems as if when one servo is working, the other one will jitter.
Here is the code:
#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.24129;
float dest_longitude =-83.00351;
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;
}
}
if (newData)
{
float flat, flon;
unsigned long age;
gps.f_get_position(&flat, &flon, &age);
Serial.print("LAT=");
Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6);
Serial.print(" LON=");
Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6);
Serial.print(" SAT=");
Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites());
Serial.print(" PREC=");
Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop());
Serial.print("Millis is");
Serial.print(millis());
float distance = (TinyGPS::distance_between(flat, flon, dest_latitude, dest_longitude ));
float distanceangle;
float course = (TinyGPS::course_to(flat, flon, dest_latitude, dest_longitude ));
float courseangle;
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);
}
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);
}
}
gps.stats(&chars, &sentences, &failed);
Serial.print(" CHARS=");
Serial.print(chars);
Serial.print(" SENTENCES=");
Serial.print(sentences);
Serial.print(" CSUM ERR=");
Serial.println(failed);
}
It's hard to pick put the wheat from the chaff in all the serial output. Do you think that the number of satellites is really making the servos move on their own?
Cut the serial output down to just the values that are relevant - the time and the angles written to each servo.
Learn what that big key along the bottom of the keyboard is for.
#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);
}
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;
}
}
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);
Serial.print ("millis is");
Serial.print(millis());
tiltservo.write(distanceangle);
}
else {
distanceangle = 60;
Serial.print(" distance is greater ");
Serial.print( distanceangle);
Serial.print ("millis is");
Serial.print(millis());
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);
Serial.print ("millis is");
Serial.print(millis());
panservo.write(courseangle);
}
else if (0 <= course && course <= 90){
courseangle = int(-course + 90);
Serial.print (" course is case 2 ");
Serial.print ( courseangle);
Serial.print ("millis is");
Serial.print(millis());
panservo.write(courseangle);
}
else if (90 < course && course < 180){
courseangle = 0;
Serial.print (" course is case 3 ");
Serial.print ( courseangle);
Serial.print ("millis is");
Serial.print(millis());
panservo.write(courseangle);
}
else if (180 <= course && course < 270){
courseangle = 180;
Serial.print (" course is case 4 ");
Serial.print ( courseangle);
Serial.print ("millis is");
Serial.print(millis());
panservo.write(courseangle);
}
}
gps.stats(&chars, &sentences, &failed);
}
this is the serial monitor
distance is greater 60.00 millis is 2029 course is case 2 39.00millis is 2059
distance is greater 60.00 millis is 3092 course is case 2 39.00 millis is 3122
distance is greater 60.00 millis is 4156 course is case 2 39.00 millis is 4185
distance is greater 60.00 millis is 5217 course is case 2 39.00 millis is 5248
distance is greater 60.00 millis is 6281 course is case 2 39.00 millis is 6310
All that seems to show is that the servo is not being commanded to move.
If it's moving then either there's an external problem or the servo library is not able to control the servos accurately. The only reasons I can think of for that are memory corruption, and something disabling timeouts.
How about adding a "delay(5000);" in front of the panservo.write and tiltservo.write lines. Observe the behavior, and drop/raise the delay to tune the servos settle down time.
I am having an almost identical problem in using a TinyGPS with servos. I now know where tghe problem is but not how to fix it. If I only do:
servo1.attach(5)