Hi guys,
I am stuck with an issue of a not being able to update my gps coordinates whilst in a while loop (and so being unable to break the out of it). I am using the AssettrackerRK to access the distanceBetween function from TinyGPS.
Basically I have an array with some coordinates and the program runs through to check if I am close to any of these specific points. That part works great. Whilst within a certain threshold of a certain point I need it to execute some specific code (run a dc motor and publish some stuff) and stop worrying about the other locations for the time being.
My problem is that as soon as I get into this while loop I no longer get any update on the gps position, i.e. the coordinates I get stay in the same position as when entering the loop so that it gets stuck there.
I have feeling this might be very simple but I just cant figure it out
As always very grateful for any ideas / suggestions:slight_smile:
this is the offending code:
void closeTo() {
int numberLocation = 5;
static const double POS_LAT[] = {51.508131, 56.164644, 56.171765, 56.172123, 56.171662};
static const double POS_LON[]= {-0.128002, 10.188129, 10.189953, 10.189050, 10.188551};
const char * locations[] = {"london", "botanisk have", "roof", "office window", "entrance opp"};
for (int i=0; i < numberLocation; i++){
metersToLocation =
(unsigned long)TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), POS_LAT[i], POS_LON[i]);
digitalWrite(ledPin,LOW);
analogWrite(transistorPin, 0);
Serial.print(" distance to: ");
Serial.print(locations[i]);
Serial.print(" ");
Serial.print(metersToLocation);
Serial.println();
while(metersToLocation<=maxDistance){
i =i; //this might be redundant
int rotateMotor = map(metersToLocation,maxDistance,0,150,255);
digitalWrite(ledPin,HIGH);
analogWrite(transistorPin, rotateMotor);
Serial.println("close");
Particle.publish("close", String(metersToLocation), 60, PRIVATE);
Particle.publish("to", String(locations[i]), 60, PRIVATE);
Serial.print(" distance to: ");
Serial.print(locations[i]);
Serial.print(" ");
Serial.print(metersToLocation);
Serial.println();
metersToLocation =
(unsigned long)TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), POS_LAT[i], POS_LON[i]);
Serial.print(gps.location.lat());
Serial.print(", ");
Serial.println(gps.location.lng());
}
}
}
and this is the entire thing (GPS is towards the end):
// This #include statement was automatically added by the Particle IDE.
#include "Particle.h"
// Port of TinyGPS for the Particle AssetTracker
// https://github.com/mikalhart/TinyGPSPlus
#include "TinyGPS++.h"
bool publish = true; // set to true if elctron should publish
const unsigned long PUBLISH_PERIOD = 10000;
const unsigned long SERIAL_PERIOD = 5000;
// The TinyGPS++ object
TinyGPSPlus gps;
unsigned long lastSerial = 0;
unsigned long lastPublish = 0;
unsigned long startFix = 0;
bool gettingFix = false;
unsigned long metersToLocation;
int maxDistance = 35;
bool close = false;
//WEATHER:
int i = 0;
bool weatherGood = false;
char* R = "weather";
//how often to call the weather
long interval = 60000*10;
long previousMillis = 0;
//conditions
int minTemp = 15;
int minHum = 30;
int maxWind = 40;
float maxPrep = 10;
//actuators:
const int transistorPin = D2;
const int ledPin = D7;
void affect(void);
bool trigger = false;
SYSTEM_THREAD(ENABLED);
void displayInfo(); // forward declaration
String data = String(10);
void setup()
{
// Subscribe to the integration response event
Particle.subscribe("hook-response/WeatherAarhus", myHandler, MY_DEVICES);
Particle.publish("WeatherAarhus", data, PRIVATE);
Serial.begin(9600);
// The GPS module on the AssetTracker is connected to Serial1 and D6
Serial1.begin(9600);
// Settings D6 LOW powers up the GPS module
pinMode(D6, OUTPUT);
digitalWrite(D6, LOW);
startFix = millis();
gettingFix = true;
pinMode(transistorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
pinMode(D5, INPUT_PULLUP);
attachInterrupt(D5, affect, FALLING);
}
void loop()
{
// INTERRUPT:_______________________________________
if (trigger) {
Particle.publish("affect", NULL, PRIVATE);
displayInfo();
}
trigger = false;
//WEATHER:_______________________________________
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > interval) {
// save the last time you read sensor
previousMillis = currentMillis;
Particle.publish("WeatherAarhus", data, PRIVATE);
}
//GPS:____________________________________________
while (Serial1.available() > 0) {
if (gps.encode(Serial1.read())) {
displayInfo();
}
}
closeTo();
}
void affect()
{
trigger = true;
}
//get weatherdata from Wunderground.api
void myHandler(const char *event, const char *data) {
// Handle the integration response
i++;
Serial.print(i);
Serial.print(event);
String str = String(data);
char strBuffer[strlen(data)];
str.toCharArray(strBuffer, strlen(data));
char* token = strtok(strBuffer, "\"~");
atoi(strtok(NULL, "\"~"));
char* weather = strtok(NULL, "\"~");
int temp = atoi(strtok(NULL, "\"~"));
int humidity = atoi(strtok(NULL, "\"~"));
int wind = atoi(strtok(NULL, "\"~"));
int prep = atoi(strtok(NULL, "\"~"));
if(strcmp(weather,R)!=0){
Serial.print("strings not same");
if (temp > minTemp && humidity > minHum && wind < maxWind && prep < maxPrep)
{weatherGood = true;}
}
else {weatherGood = false;}
/* Serial.print("weather: ");
Serial.println(weather);
Serial.print("temp: ");
Serial.println(temp);
Serial.print("humidity: ");
Serial.println(humidity);
Serial.print("wind_kph: ");
Serial.println(wind);
Serial.print("precip_today: ");
Serial.println(prep);
Serial.print("weatherGood: ");
Serial.println(weatherGood);*/
delay(1);
}
//GPS:-----------------------------------------------------------
void closeTo() {
int numberLocation = 5;
static const double POS_LAT[] = {51.508131, 56.164644, 56.171765, 56.172123, 56.171662};
static const double POS_LON[]= {-0.128002, 10.188129, 10.189953, 10.189050, 10.188551};
const char * locations[] = {"london", "botanisk have", "roof", "office window", "entrance opp"};
for (int i=0; i < numberLocation; i++){
metersToLocation =
(unsigned long)TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), POS_LAT[i], POS_LON[i]);
digitalWrite(ledPin,LOW);
analogWrite(transistorPin, 0);
Serial.print(" distance to: ");
Serial.print(locations[i]);
Serial.print(" ");
Serial.print(metersToLocation);
Serial.println();
while(metersToLocation<=maxDistance){
i =i; //this might be redundant
displayInfo();
int rotateMotor = map(metersToLocation,maxDistance,0,150,255);
digitalWrite(ledPin,HIGH);
analogWrite(transistorPin, rotateMotor);
Serial.println("close");
Particle.publish("close", String(metersToLocation), 60, PRIVATE);
Particle.publish("to", String(locations[i]), 60, PRIVATE);
Serial.print(" distance to: ");
Serial.print(locations[i]);
Serial.print(" ");
Serial.print(metersToLocation);
Serial.println();
metersToLocation =
(unsigned long)TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), POS_LAT[i], POS_LON[i]);
Serial.print(gps.location.lat());
Serial.print(", ");
Serial.println(gps.location.lng());
}
}
}
void displayInfo()
{
if (millis() - lastSerial >= SERIAL_PERIOD) {
lastSerial = millis();
Serial.print("sat: ");
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
Serial.println();
char buf[128];
if (gps.location.isValid()) {
snprintf(buf, sizeof(buf), "%f,%f", gps.location.lat(), gps.location.lng());
if (gettingFix) {
gettingFix = false;
unsigned long elapsed = millis() - startFix;
Serial.printlnf("%lu milliseconds to get GPS fix", elapsed);
}
}
else {
strcpy(buf, "no location");
if (!gettingFix) {
gettingFix = true;
startFix = millis();
}
}
Serial.println(buf);
if (publish) {
if (Particle.connected()) {
if (millis() - lastPublish >= PUBLISH_PERIOD) {
Particle.publish("gps", buf);
lastPublish = millis();
}
}
}
}
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i=strlen(sz); i<len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len-1] = ' ';
Serial.print(sz);
}