Hello,
I'm writing a piece of software that logs some data from various environmental sensors and GPS, and does some basic data processing and SD storage. I have run into some problems (Probably?) regarding memory. after several loops this program's output degrades as seen in screenshot below. I suspect this may be caused by memory fragmentation and I have tired several ways how to fix it, but I've run out of ideas. I'm posting the code with screenshot below, if anyone here could point me to right direction I'd be very grateful...
//=== LIBRARIES ===//
#include <dht.h>
#include <SD.h> //library for SD card
#include <SPI.h> // library for comunication
#include <Wire.h> //virtual wire library
#include <Adafruit_BMP085.h> // BMP180 library
#include <TinyGPS.h> // library for GPS NEO 6M
#include <SoftwareSerial.h> // library for Serial comunication and for using more serial pins
//=== DEFINES ===//
//define for SD card
#define SD_INIT_MAX_RETRY 100
#define CHIP_SELECT
//defines for DHT
#define DHTPIN 2
#define DHTTYPE DHT21 // DHT 21 (AM2301)
#define LOG_FILE_OPEN_MAX_ATTEMPTS 100
//defines for GPS
#define TX 3 //pin 3 where is gps TX wire connected
#define RX 4 // pin 4 where is gps RX wire connected
#define BUTTON_PIN 7
//=== GLOBAL VARIABLES ===//
int loopCounter = 0; //counter
//variables for activating and deactivating function
bool active = false;
int buttonValue;
//=== VOID SETUP ===//
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT);
// this part is for initialization of the SD card
for (int i = 0; !SD.begin(CHIP_SELECT) && i < SD_INIT_MAX_RETRY; i++) {
}
}
//=== MAIN LOOP ===//
void loop() {
//check for button presses, on press it will pause/unpause main loop to prevent SD card corruption
buttonValue = digitalRead(BUTTON_PIN);
if (buttonValue == LOW) {
active = !active;
}
if (!active) {
Serial.print("Inactive \n");
delay(1000);
return;
} else {
Serial.print("Active \n");
}
processDHT();
processBMP();
processGPS();
loopCounter++;
delay(1000);
}
void processDHT() {
dht DHT;
DHT.read21(DHTPIN);
logData("Humidity: " + String(DHT.humidity));
logData("Temperature: " + String(DHT.temperature));
logData("Dew point: " + String(dewPoint(DHT.temperature, DHT.humidity)));
}
void processBMP() {
Adafruit_BMP085 bmp180;
bmp180.begin();
logData("Press: " + String(bmp180.readPressure()));
}
void processGPS() {
TinyGPS gps;
SoftwareSerial swSerial(RX, TX);
swSerial.begin(9600);
// after 5 seconds, the data will come from gps
for (unsigned long start = millis(); millis() - start < 1000;) {
// control of activity of serial monitor
while (swSerial.available()) {
// invoke a variabile for reading data from GPS
char c = swSerial.read();
//Serial.write(c); // for displaying data on serial monitor, uncomment this line
if (gps.encode(c)) { //if this pass, we got meaningfull data
// if the data are recieved we will invoke an another variabile for cleaning the data :P <-- yeah, after we solve memory issues...
float latitude, longitude;
int year;
byte month, day, hour, minute, second;
//just log everything
gps.f_get_position(&latitude, &longitude);
logData("Lat: " + String(latitude));
logData("Long: " + String(longitude));
logData("Alt: " + String(gps.f_altitude()));
logData("Spd: " + String(gps.f_speed_kmph()));
}
}
}
}
void logData(String data) {
File dataFile;
//Serial.print("Trying to open Data File \n");
for (int i = 0; i < LOG_FILE_OPEN_MAX_ATTEMPTS && !dataFile; i++) {
//Serial.print("Opening data file \n");
dataFile = SD.open("datalog.txt", FILE_WRITE);
if (i == 99) { //comment after
Serial.print("Max attempts reached");
}
}
if (dataFile) {
Serial.print("Logging data " + data + "\n");
dataFile.print("Loop no. " + loopCounter);
dataFile.println(" | " + data);
dataFile.close();
}
}
//
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
return 1.8 * celsius + 32;
}
//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
return celsius + 273.15;
}
// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm
double dewPoint(double celsius, double humidity)
{
double A0 = 373.15 / (273.15 + celsius);
double SUM = -7.90298 * (A0 - 1);
SUM += 5.02808 * log10(A0);
SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1 / A0))) - 1) ;
SUM += 8.1328e-3 * (pow(10, (-3.49149 * (A0 - 1))) - 1) ;
SUM += log10(1013.246);
double VP = pow(10, SUM - 3) * humidity;
double T = log(VP / 0.61078); // temp var
return (241.88 * T) / (17.558 - T);
}
Output degradation from log:

