Hi there,
I could really need some help to discover why my code is not giving me GPS coordinates.
The goal is to check every hour if liquid level is too high, using a bilge liquid level sensor. High means level is too high and it will send the data to Sigfox backend. The hourly trigger comes from a RTC (DS3231) with an alarm every via the external interrupt pin on ‘TheAirboard’ (Arduino Fio compatible). So far everything works fine. However I also need to send the GPS coordinates every hour. I’m using SoftwareSerial to listen to the GPS coordinates, but they won’t show. It only says INVALID. This is normal for the first 5 results (tested with example codes form TinyGPS++). Obviously I’m doing something wrong with the logic, but I can’t find what’s the main problem. According to isListening() the Arduino is listening to this port.
The ‘challenge’ is a bit below "if (clock.isAlarm1()) " in the code
Any help is much appreciated!
Best,
Freek
Code:
#include <Wire.h>
#include <DS3231.h>
#include <avr/sleep.h>
#include <EEPROM.h>
#include <TheAirBoard.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
TheAirBoard board;
//Pins for GPS board
static const int RXPin = 13, TXPin = 12;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
int wakePin = 3; // pin used for waking up
int led=9;
#define SENSOR 10
#define BLUE 6 // The Airboard BLUE LED
int var = 0; //helping var for one time running Sigfox test at startup
int val; //Input value water level sensor
int sensor; //Input value water level sensor for takeReading
int counter; //Counter value for reducing false positives
int batstate; //Charge state of battery
/** the current address in the EEPROM (i.e. which byte we're going to write to next) **/
int addr = 0;
char buffer[9];
byte value;
DS3231 clock;
RTCDateTime dt;
void setup()
{
Serial.begin(115200);
ss.begin(GPSBaud);
// Initialize DS3231
Serial.println("Initialize DS3231");
delay(100);
clock.begin();
pinMode(wakePin, INPUT_PULLUP);
pinMode(led, OUTPUT);
pinMode(SENSOR, INPUT); //Set sensor pin
pinMode(BLUE, OUTPUT); // initialize the BLUE LED pin as an output
// Disarm alarms and clear alarms for this example, because alarms is battery backed.
// Under normal conditions, the settings should be reset after power and restart microcontroller.
clock.armAlarm1(false);
clock.clearAlarm1();
clock.armAlarm2(false);
clock.clearAlarm2();
// Set Alarm1 - Every 20s in each minute
// setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
clock.setAlarm1(0, 0, 0, 20, DS3231_MATCH_S);
// Set Alarm - Every 01m:25s in each hour
// setAlarm1(Date or Day, Hour, Minute, Second, Mode, Armed = true)
//clock.setAlarm1(0, 0, 15, 0, DS3231_MATCH_M_S); //COMMENTED
// Set alarm for daily 'alive' check
// setAlarm1(Date or Day, Hour, Minute, Mode, Armed = true)
clock.setAlarm2(0, 17, 15, DS3231_MATCH_M); //COMMENTED
attachInterrupt(1, wakeUpNow, LOW);
// Check alarm settings
checkAlarms();
//Show last reading form EEPROM memory
value = EEPROM.read(addr);
}
void checkAlarms()
{
RTCAlarmTime a1;
RTCAlarmTime a2;
if (clock.isArmed1())
{
a1 = clock.getAlarm1();
Serial.print("Alarm1 is triggered ");
switch (clock.getAlarmType1())
{
case DS3231_MATCH_S:
Serial.print("when seconds match: ");
Serial.println(clock.dateFormat("__ __:__:s", a1));
delay(100);
break;
default:
Serial.println("UNKNOWN RULE");
break;
}
}
}
void wakeUpNow() {
}
void sleepNow() {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
attachInterrupt(0,wakeUpNow, FALLING); // use interrupt 0 (pin 2) and run function
//Serial.println("Woke up");
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING UP
sleep_disable(); // first thing after waking from sleep: disable sleep...
detachInterrupt(0); // disables interrupt 0 on pin 2 so the wakeUpNow code will not be executed during normal running time.
}
void loop() {
while(var < 1){
//Send start message
delay(1000);
analogWrite(BLUE, 1);
sprintf(buffer, "AT$SS=%.2X", 3); // acquire and format analog data
//Serial.println("AT$SS=01CAFE");
Serial.println(buffer); // send message
delay(6000);
digitalWrite(BLUE, 0); // reset communication indicator
var ++;
}
val = digitalRead(SENSOR);
dt = clock.getDateTime();
// Send daily alive message
if (clock.isAlarm2()) {
//Start communication steps
Serial.println("Send daily alive message");
analogWrite(BLUE, 1); // set communication indicator
float vbat = board.batteryChk();
Serial.println(vbat);
if (vbat < 3.25) {
batstate = 5; //Code 5 means low battery
}
else {
batstate = 4; //Code 5 means battery OK
}
sprintf(buffer, "AT$SS=%.2X", batstate); // acquire and format analog data
Serial.println(buffer); // send message
delay(6000); // wait until end of transmission
digitalWrite(BLUE, 0); // reset communication indicator
}
Serial.println(clock.dateFormat("d-m-Y H:i:s - l", dt));
delay(100);
// Call isAlarm1(false) if you want clear alarm1 flag manualy by clearAlarm1();
if (clock.isAlarm1())
{
Serial.println("ALARM 1 TRIGGERED!");
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
//GPS communication serial
if (ss.isListening()) {
Serial.println("Port One is listening!");
}
for (int i=0; i <= 2; i++){
while (ss.available() > 0)
if (gps.encode(ss.read()))
delay(100);
displayInfo();
if (millis() > 5000 && gps.charsProcessed() < 10)
{
Serial.println(F("No GPS detected: check wiring."));
while(true);
}
delay(1000);
}
//Show last reading form EEPROM memory
value = EEPROM.read(addr);
//Take sensor readings here
if (val == HIGH) {
//Serial.println("Sensor high");
//Reduce false positives positiveEquals 10 seconds of measurement, needs more than 20 seconds water detected state
delay(100);
//takeReading();
for (int i=0; i <= 11; i++){
//analogWrite(PWMpin, i);
sensor = digitalRead(SENSOR); //Read input value
if (sensor == HIGH) {
counter ++;
}
delay(1000);
}
if (counter >= 10) {
//Start communication steps
if (value != 1) {
analogWrite(BLUE, 1); // set communication indicator
sprintf(buffer, "AT$SS=%.2X", 2); // acquire and format analog data
Serial.println(buffer); // send message
delay(6000); // wait until end of transmission
digitalWrite(BLUE, 0); // reset communication indicator
EEPROM.write(addr, 1); //Put last state in EEPROM memory (water detected)
counter = 0; //Set counter back to zero value
//Need to go back to long sleep to prevent endless loop of notifications
//sleepAftersend();
}
}
}
else {
//Put last state in EEPROM memory
EEPROM.write(addr, 0); //No water detected this time
}
Serial.println("Entering sleep");
delay(100); // sleep function called here
sleepNow();
}
delay(900);
}
void displayInfo()
{
Serial.print(F("Location: "));
if (gps.location.isValid())
{
Serial.print(gps.location.lat(), 6);
Serial.print(F(","));
Serial.print(gps.location.lng(), 6);
}
else
{
Serial.print(F("INVALID"));
}
Serial.println();
}