Hi again. I've been building a GPS autopilot model boat and today was the first day we got to try it in the water. The boat behaved strangely and I've managed to pull the telemetry from it and figure out that the GPS is only updating its current position when the boat is going rather slow (like nearly static) I'm trying to figure out if this is something software based or hardware based.
I have since discovered that n stead of the isUpadted() argument you can also use a isValid() argument and wondering if this could be my problem. Other than that I'm at a bit of a loss unless the patch antenna isnt up to the job
CODE
#include <TinyGPSPlus.h>
#include <SoftwareSerial.h>
#include <Wire.h>
#include <LSM303.h>
#include <PWMServo.h>
#include <PID_v1.h>
// SERVO PID CONTROL
double Setpoint, Input, Output;
double Kp = 1.00, Ki = 0.0, Kd = 0.0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);
#define PIN_OUTPUT 10
// VOLTAGE
#define ANALOG_IN_PIN A0
// Floats for ADC voltage & Input voltage
float adc_voltage = 0.0;
float in_voltage = 0.0;
// Floats for resistor values in divider (in ohms)
float R1 = 30000.0;
float R2 = 7500.0;
// Float for Reference Voltage
float ref_voltage = 4.20;
// Integer for ADC value
int adc_value = 0;
///AMPS
int analogPin = A1; // Current sensor output
const int averageValue = 500;
long int sensorValue = 0; // variable to store the sensor value read
float voltage = 0;
float current = 0;
// GPS
static const int RXPin = 6, TXPin = 7; //GPS TX & RX
SoftwareSerial ss(RXPin, TXPin); //GPS TX & RX
// Create objects
TinyGPSPlus gps;
LSM303 compass;
PWMServo myservo;
PWMServo ESC;
// GPS buadrate
static const uint32_t GPSBaud = 9600;
// ESC inputs - 180 = full power etc
int motor_power = 110;
void setup()
{
Serial.begin(115200);
Serial.println("Project West Wind by Alan & Elise Thompson");
Serial.println("begin serial @ 115200");
ss.begin(GPSBaud);
Serial.println("softwareserial begin @ 9600");
Wire.begin();
Serial.println("wire begin");
compass.init();
Serial.println("compass initiated");
compass.enableDefault();
Serial.println("compass enable default");
myservo.attach(SERVO_PIN_B);
Serial.println("rudder servo attched");
ESC.attach(SERVO_PIN_A);
Serial.println("esc attached");
Setpoint = 90;
myPID.SetMode(AUTOMATIC);
Serial.println("pid set to AUTO");
compass.m_min = (LSM303::vector<int16_t>){ -629, -621, -422 };
compass.m_max = (LSM303::vector<int16_t>){ +594, +592, +519 }; //{ -629, -621, -422} max: { +594, +592, +519}
Serial.println("compass calibration data loaded");
Serial.println(F("Time , Current location , Destination , Distance to desination , Course to destination , Heading , Heading error , Speed(kph) , Rudder input , System amps , System voltage "));
}
void loop() {
while (ss.available() > 0) {
gps.encode(ss.read());
compass.read();
}
if (gps.location.isUpdated()) {
// NAVIGATION FOMULAS
static const double Destination_lat = 55.294285, Destination_lng = -1.580930; /// 55.294285458482264, -1.5809302852304756
double distanceToDestination = TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), Destination_lat, Destination_lng);
double courseToDestination = TinyGPSPlus::courseTo(gps.location.lat(), gps.location.lng(), Destination_lat, Destination_lng);
double heading = compass.heading();
int heading_error_INT = round(heading - courseToDestination);
float heading_error = (heading_error_INT + 540) % 360 - 180; //int heading_error = (bearing-heading+540)%360 -180;
// Serial prints
ESC.write(0);
Serial.print(gps.time.hour());
Serial.print(F(":"));
Serial.print(gps.time.minute());
Serial.print(F(":"));
Serial.print(gps.time.second());
Serial.print(" , ");
Serial.print(gps.location.lat(), 6);
Serial.print(",");
Serial.print(gps.location.lng(), 6);
Serial.print(",");
Serial.print(Destination_lat, 6);
Serial.print(",");
Serial.print(Destination_lng, 6);
Serial.print(",");
Serial.print(distanceToDestination / 1000);
Serial.print(",");
Serial.print(courseToDestination);
Serial.print(",");
Serial.print(heading);
Serial.print(",");
Serial.print(heading_error);
Serial.print(",");
Serial.print(gps.speed.kmph());
Serial.print(",");
for (int i = 0; i < averageValue; i++) {
sensorValue += analogRead(analogPin);
}
sensorValue = sensorValue / averageValue;
voltage = sensorValue * 4.20 / 1024.0;
current = (voltage - 2.5) / 0.185;
adc_value = analogRead(ANALOG_IN_PIN);
adc_voltage = (adc_value * ref_voltage) / 1024.0;
in_voltage = adc_voltage / (R2 / (R1 + R2));
Serial.print(current);
Serial.print(",");
Serial.println(in_voltage, 2);
Input = heading_error;
myPID.SetOutputLimits(0, 180);
myPID.Compute();
myservo.write(Output);
Serial.println(Output);
Serial.println(heading_error);
}
}
Screen shot of the gps data it stored every 1 second (as ive asked it to). as you can see the data points are scattered and I would expect them to be closely grouped together at a 1 second interval. The boat only travels around 1m/s so cant see the speed being that much of an issue though clearly it is having an effect.
For the most part, the lat and lng it has stored are very accurate, maybe down to a couple of metres.
Any help appreciated