Hello,
In my project I am trying to get GPS coordinates from sensor and post them to cloud. Also I am trying to monitor the battery and tell if the device is connected to electricity and charging or it is not charging. I have implemented my solution like it can be seen below. I am kinda newbie and I am asking for advice if my thinking is OK or i should make some conceptual changes? in example putting functions “function_GPS_Load” and “function_IsCharging” in its own software interrupts, set global values inside interrupt and just print them in loop?
This is my code:
#include <stdlib.h>
#include <math.h>
#include <TinyGPS++/TinyGPS++.h>
/* GPS */
TinyGPSPlus gps;
/* GPS telemetry values */
float gps_lat =0;
float gps_lng =0;
int gps_ready =0;
/* BATTERY */
// Battery state - if charging then engine is ON
float last_batt_level =0;
int is_charging =0;
volatile bool doTheWork = false;
/* TIMERS */
//timer that sets variable in loop to true
Timer timer(60000, function_doTheWork);
void setup()
{
Serial.begin(9600);
timer.start();
}
void loop()
{
if(doTheWork == true)
{
noInterrupts();
function_GPS_Load();
function_IsCharging();
doTheWork = false;
interrupts();
}
}
void function_GPS_Load(){
Serial.println("GPS encoding started.");
unsigned long start = millis();
do
{
while (Serial1.available())
gps.encode(Serial1.read());
} while (millis() - start < 60000);
char coord1[10];
sprintf(coord1, "%f", (gps.location.lat(), gps.location.isValid(), 11, 6));
char coord2[10];
sprintf(coord2, "%f", (gps.location.lng(), gps.location.isValid(), 12, 6));
char location[21];
strcpy(location,coord1);
strcat(location,",");
strcat(location,coord2);
Serial.println(location);
// Set global GPS values
gps_lat = atof(coord1);
gps_lng = atof(coord2);
if (millis() > 5000 && gps.charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
String data = String::format("{ \"gps_location\": \"%s\" }", location);
Particle.publish("p2a-gps", data, PRIVATE);
}
void function_IsCharging()
{
// Prepare json data object
FuelGauge fuel;
float batt_level = fuel.getSoC();
if(definitelyLessThan(last_batt_level, batt_level, 0.001))
{
is_charging =1;
}
else
{
is_charging =0;
}
last_batt_level = batt_level;
String data = String::format("{ \"is_charging\": %i }", is_charging);
Particle.publish("p2a-battery", data, PRIVATE);
}
void function_doTheWork()
{
doTheWork = true;
}
//helper
bool definitelyLessThan(float a, float b, float epsilon)
{
return (b - a) > ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
}