My code works fine for a few hours but then stops. At this point it's mostly data logging gps and environmental sensors. I have the GPS hardware and software running on Serial2. I'm wondering why it stops after a while. It usually stops after the line "Serial.println(dataString);" at the end.
#include <SPI.h>
#include <Wire.h>
#include <RH_RF95.h>
#include <Adafruit_GPS.h>
#include <Adafruit_SHT31.h>
#include <Adafruit_BMP280.h>
#include <Adafruit_LIS3MDL.h>
#include <Adafruit_LSM6DS33.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "RTClib.h"
#include "avr/dtostrf.h"
#define ONE_WIRE_BUS 15
#include <Servo.h>
#include <Arduino.h> // required before wiring_private.h
#include "wiring_private.h" // pinPeripheral() functionRTC_PCF8523 rtc;
#include <SD.h>
#include <Adafruit_GPS.h>
Servo servo;
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
RTC_PCF8523 rtc;
Uart Serial2 (&sercom1, 11, 10, SERCOM_RX_PAD_0, UART_TX_PAD_2);
void SERCOM1_Handler() {
Serial2.IrqHandler();
}
// what's the name of the hardware serial port?
#define GPSSerial Serial2
// Connect to the GPS on the hardware port
Adafruit_GPS GPS(&GPSSerial);
// Set GPSECHO to 'false' to turn off echoing the GPS data to the Serial console
// Set to 'true' if you want to debug and listen to the raw GPS sentences
#define GPSECHO false
uint32_t timer = millis();
Adafruit_SHT31 sht30; // humidity
Adafruit_BMP280 bmp280; // use I2C interface
Adafruit_LIS3MDL lis3mdl; // magnetometer
Adafruit_LSM6DS33 lsm6ds33; // accelerometer, gyroscope
#define RFM95_CS 8
#define RFM95_RST 4
#define RFM95_INT 3
#define RF95_FREQ 433.0
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
int MaxAlt = 0;
int MaxSpd = 0;
int MaxITem = 0;
int MinITem = 10000;
int MaxHum = 0;
int f = 0;
int a = 1017;
float Fahrenheit = 0;
int MaxOTem = 0;
int MinOTem = 10000;
int MaxBMPAlt = 0;
void setup() {
sht30.begin();
bmp280.begin();
lis3mdl.begin_I2C();
lsm6ds33.begin_I2C();
servo.attach(5);
servo.write(90);
rtc.start();
SD.begin(10);
pinMode(LED_BUILTIN, OUTPUT);
sensors.begin();
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
Serial.begin(115200);
Serial2.begin(115200);
GPS.begin(9600);
GPS.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA);
GPS.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); // 1 Hz update rate
pinPeripheral(10, PIO_SERCOM);
pinPeripheral(11, PIO_SERCOM);
delay(1000);
// manual reset
digitalWrite(RFM95_RST, LOW);
delay(10);
digitalWrite(RFM95_RST, HIGH);
delay(10);
while (!rf95.init()) {
while (1);
}
if (!rf95.setFrequency(RF95_FREQ)) {
while (1);
}
bmp280.setSampling(Adafruit_BMP280::MODE_NORMAL, /* Operating Mode. */
Adafruit_BMP280::SAMPLING_X2, /* Temp. oversampling */
Adafruit_BMP280::SAMPLING_X16, /* Pressure oversampling */
Adafruit_BMP280::FILTER_X16, /* Filtering. */
Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
rf95.setTxPower(23, false);
if (!SD.begin(10)) {
Serial.println("Card failed");
}
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
}
if (! rtc.initialized() || rtc.lostPower()) {
Serial.println("RTC is NOT initialized, let's set the time!");
}
}
void loop() {
sensors.requestTemperatures();
Fahrenheit = sensors.toFahrenheit(sensors.getTempCByIndex(0));
if (Fahrenheit > MaxOTem) {
MaxOTem = Fahrenheit;
}
if (Fahrenheit < MinOTem) {
MinOTem = Fahrenheit;
}
if (GPS.altitude > MaxAlt) {
MaxAlt = GPS.altitude;
}
if (GPS.speed > MaxSpd) {
MaxAlt = GPS.speed;
}
if (bmp280.readTemperature() > MaxITem) {
MaxITem = bmp280.readTemperature();
}
if (bmp280.readTemperature() < MinITem) {
MinITem = bmp280.readTemperature();
}
if (bmp280.readAltitude(a) > MaxBMPAlt) {
MaxBMPAlt = bmp280.readAltitude(a);
}
if (sht30.readHumidity() > MaxHum) {
MaxHum = sht30.readHumidity();
}
sensors_event_t temp_event, pressure_event;
//bmp_temp->getEvent(&temp_event);
//bmp280_pressure->getEvent(&pressure_event);
sensors_event_t accel;
sensors_event_t gyro;
sensors_event_t temp;
lsm6ds33.getEvent(&accel, &gyro, &temp);
lis3mdl.read();
DateTime now = rtc.now();
float magnetic_x, magnetic_y, magnetic_z;
float Lo = GPS.longitude;
float La = GPS.latitude;
int Al = GPS.altitude;
int Sp = GPS.speed;
int humidity = sht30.readHumidity();
float temperature = temp_event.temperature;
float accel_x, accel_y, accel_z;
float gyro_x, gyro_y, gyro_z;
delay(1000);
// read data from the GPS in the 'main loop'
char c = GPS.read();
// if you want to debug, this is a good time to do it!
if (GPSECHO)
if (c) Serial.print(c);
// if a sentence is received, we can check the checksum, parse it...
if (GPS.newNMEAreceived()) {
// a tricky thing here is if we print the NMEA sentence, or data
// we end up not listening and catching other sentences!
// so be very wary if using OUTPUT_ALLDATA and trying to print out data
Serial.print(GPS.lastNMEA()); // this also sets the newNMEAreceived() flag to false
if (!GPS.parse(GPS.lastNMEA())) // this also sets the newNMEAreceived() flag to false
return; // we can fail to parse a sentence in which case we should just wait for another
}
// approximately every 2 seconds or so, print out the current stats
if (millis() - timer > 2000) {
timer = millis(); // reset the timer
if (GPS.fix) {
Serial.print(GPS.latitude, 4); Serial.print(GPS.lat);
Serial.print(", ");
Serial.print(GPS.longitude, 4); Serial.println(GPS.lon);
Serial.print("kn: "); Serial.println(GPS.speed);
Serial.print("Altitude: "); Serial.println(GPS.altitude);
Serial.print("Satellites: "); Serial.println((int)GPS.satellites);
}
}
delay(1000);
char radiopacket[2] = "N";
Serial.println(radiopacket);
radiopacket[1] = 0;
rf95.send((uint8_t *)radiopacket, 2);
rf95.waitPacketSent();
delay(1000);
char Lat[1] = {};
dtostrf(La, 9, 4, Lat);
Serial.print("Sending "); Serial.println(Lat);
rf95.send((uint8_t *) &Lat, 9);
delay(10);
rf95.waitPacketSent();
delay(1000);
char Lon[1] = {};
dtostrf(Lo, 9, 4, Lon);
Serial.print("Sending "); Serial.println(Lon);
rf95.send((uint8_t *) &Lon, 9);
delay(10);
rf95.waitPacketSent();
delay(1000);
char Spd[1] = {};
dtostrf(Sp, 3, 0, Spd);
Serial.print("Sending "); Serial.println(Spd);
rf95.send((uint8_t *) &Spd, 3);
delay(10);
rf95.waitPacketSent();
delay(1000);
char Alt[1] = {};
dtostrf(Al, 6, 0, Alt);
Serial.print("Sending "); Serial.println(Alt);
rf95.send((uint8_t *) &Alt, 6);
delay(10);
rf95.waitPacketSent();
for (int i = 0; i <= f; i++) {
String dataString = "";
dataString += String(now.month()) += "/" ;
dataString += String(now.day()) += "/";
dataString += String(now.year()) += " ";
dataString += String(now.hour()) += ":";
dataString += String(now.minute()) += ":";
dataString += String(now.second()) += " ";
dataString += String(GPS.latitude, 4);
dataString += String(GPS.lat) += ", ";
dataString += String(GPS.longitude, 4);
dataString += String(GPS.lon) += " ";
dataString += String((int)GPS.satellites) += " Sats ";
dataString += String(bmp280.readTemperature()) += "C MinI:";
dataString += String(MinITem) += "C MaxI:";
dataString += String(MaxITem) += "C MinO:";
dataString += String(MinOTem) += "F MaxO:";
dataString += String(MaxOTem) += "F Humidity:";
dataString += String(sht30.readHumidity()) += "% MaxHum:";
dataString += String(MaxHum) += "% ";
dataString += String(bmp280.readPressure()) += "Pa BMP Max Alt ";
dataString += String(MaxBMPAlt) += "m ";
dataString += String(GPS.speed) += "kn ";
dataString += String(MaxSpd) += "kn MAX ";
dataString += String(GPS.altitude) += "m ";
dataString += String(MaxAlt) += "m MAX MagX:";
dataString += String(lis3mdl.x) += " MagY:";
dataString += String(lis3mdl.y) += " MagZ:";
dataString += String(lis3mdl.z) += " uTesla Acc x:";
dataString += String(accel.acceleration.x) += " Acc y:";
dataString += String(accel.acceleration.y) += " Acc z:";
dataString += String(accel.acceleration.z) += " m/s^2 Gyro x:";
dataString += String(gyro.gyro.x) += " Gyro y:";
dataString += String(gyro.gyro.y) += " Gyro z:";
dataString += String(gyro.gyro.z);
File dataFile = SD.open("datalog.txt", FILE_WRITE); //Opens new text file on SD card called datalog.txt
if (dataFile) {
digitalWrite(LED_BUILTIN, HIGH);
dataFile.println(dataString);
dataFile.close();
digitalWrite(LED_BUILTIN, LOW);
}
Serial.println(dataString);
}
if (MaxAlt > 4000 && GPS.altitude < 3000) {
servo.write(15);
f = 100;
}
}