Datalogger crashing

Hi, this is more of a software/Gamebuino/Arduino question but: I created a ‘game’ to log data from a i2c sensor to the SDcard using SdFat.h
(i originally tried using tinyFAT.h, however it seemed to hit an error initializing the sdcard and would not print the error to a popup - it was just printing gobbldeygook)

Anyway, it compiles and loads, but crashes as soon as i hit ‘A’ to launch the game.

Any help gratefully accepted.
Code as below

#include <SPI.h> //imports the SPI library (needed to communicate with Gamebuino’s screen)
#include <Gamebuino.h> //imports the Gamebuino library
#include <Sodaq_SHT2x.h> // temperature and humidity sensor
#include <Wire.h> // I2C functions for DS1307
#include <string.h>
#include <avr/pgmspace.h>
const int chipSelect = 10; //for sdcard
#include <SdFat.h> // requires sdfat, get it at https://github.com/greiman/SdFat
SdFat sd;
SdFile file;

//creates a Gamebuino object named gb
Gamebuino gb;

//Variables
byte res;// for tinyfat
float currTemperature;
float currHumidity;
float currDewpoint;
double Twetbulb = 0;
const long shtinterval = 1000; // interval at which to update temperature reading (milliseconds)
unsigned long previousMillis = 0; // will store last time reading was updated
//extern const byte font5x7[]; //a large, comfy font
//extern const byte font3x5[]; //a small but efficient font (default)
const char* LogFileName = “TMPLOG.TXT”;
char dataString[] = “”; // holds the data to be written to the SD card

// the setup routine runs once when Gamebuino starts up
void setup() {

// initialize the Gamebuino object
gb.begin();

//gb.display.drawBitmap(0, 12, logo);
gb.display.println(F("\35 Reading SD card
\n\n"));
gb.display.update();

if (!sd.begin(chipSelect, SPI_HALF_SPEED)) {
gb.display.println(F(“Insert SD & restart”));
gb.display.update();
while (1);
}

sd.chdir(’/’);
//display the main menu:
gb.titleScreen(F(“Temperature/humidity”));

Wire.begin();

}

// the loop routine runs over and over again forever
void loop() {
unsigned long currentMillis = millis();
//updates the gamebuino (the display, the sound, the auto backlight
 everything)
//returns true when it’s time to render a new frame (20 times/second)
if (gb.update()) {
//pause the game if C is pressed
if (gb.buttons.pressed(BTN_C)) {
gb.titleScreen(F(“Temperature/humidity”));
gb.battery.show = false;
gb.display.fontSize = 2;
}
//prints Hello World! on the screen
//gb.display.println(F(“Hello World!”));
//declare a variable named count of type integer :
//int count;
//get the number of frames rendered and assign it to the “count” variable
//count = gb.frameCount;
//prints the variable “count”
//gb.display.println(count);
gb.display.fontSize = 1;
gb.display.println(" Temps / Humidity");
gb.display.println("");
gb.display.fontSize = 2;
//gb.display.setFont(font5x7);
//gb.display.setFont(font3x5); //excluded to save memory
//gb.display.print(“5x7 font\n”);
gb.display.print("T ");
gb.display.print(currTemperature);
gb.display.println(“°C”);
gb.display.print(“H “);
gb.display.print(currHumidity);
gb.display.println(”%”);
gb.display.print("D ");
gb.display.print(currDewpoint);
gb.display.println(“°C”);
gb.display.fontSize = 1;

}
if (currentMillis - previousMillis >= shtinterval) {
// save the last time you blinked the LED
previousMillis = currentMillis;

// update readings:
currTemperature = SHT2x.GetTemperature();
currHumidity = SHT2x.GetHumidity();
//Twetbulb = currTemperature * atan(0.151977 * pow( currHumidity + 8.313659, 0.5)) + atan( currTemperature + currHumidity ) - atan( currHumidity - 1.676331) + 0.00391838 * pow(currHumidity, 1.5) * atan(0.023101 * currHumidity) - 4.686035;
currDewpoint = SHT2x.GetDewPoint();

//log readings to sdcard
File dataFile = sd.open(LogFileName, FILE_WRITE);
// if the file is available, write to it:
if (dataFile) {
  //dataString = String(currTemperature) + "," + String(currHumidity);
  strcat(dataString, dtostrf(currTemperature, 5, 2, dataString));
  strcat(dataString, ",");
  strcat(dataString, dtostrf(currHumidity, 5, 2, dataString));
  dataFile.println(dataString);
  dataFile.close();
  // print to the serial port too:
  Serial.println(dataString);
}
// if the file isn't open, pop up an error:
else {
  gb.popup(F("error opening TMPLOG.TXT"), 20);
}

}
}

Compilation does give me a low memory warning

Sketch uses 24,584 bytes (76%) of program storage space. Maximum is 32,256 bytes.
Global variables use 1,830 bytes (89%) of dynamic memory, leaving 218 bytes for local variables. Maximum is 2,048 bytes.
Low memory available, stability problems may occur.

So i expect this is the problem. I believe using the file allocates a whole chunk of ram which might be killing it, but i have no idea how to fix it given tinyfat refused to work.

Again, any help appreciated!

Okay, progress. I’m a lot closer using the battery datalogger example.

I’ve managed to figure out that to use tinyfat you need to reformat the SDcard (regardless of how it’s formatted) using the sdcard association tool: https://www.sdcard.org/downloads/formatter_4/

I have a new problem that the temperature sensor no longer reads properly. It starts off with 0.0oC then goes to -273.0oC which suggests a problem reading the sensor. However my other sketch/game with the same code/library to read the sensor works without problem, reading the i2c temperature sensor and displaying it.

New code is

#include <tinyFAT.h> //requires the tinyFAT library. You can download it here : http://www.henningkarlsen.com/electronics/library.php?id=37
#include <SPI.h>
#include <Gamebuino.h>
Gamebuino gb;
#include <Sodaq_SHT2x.h> // temperature and humidity sensor
float currTemperature;

char buffer[7];

char *verboseError(byte err)
{
switch (err)
{
case ERROR_MBR_READ_ERROR:
return “Error reading MBR”;
break;
case ERROR_MBR_SIGNATURE:
return “MBR Signature error”;
break;
case ERROR_MBR_INVALID_FS:
return “Unsupported filesystem”;
break;
case ERROR_BOOTSEC_READ_ERROR:
return “Error reading Boot Sector”;
break;
case ERROR_BOOTSEC_SIGNATURE:
return “Boot Sector Signature error”;
break;
default:
return “Unknown error”;
break;
}
}

void setup() {
gb.begin();
gb.titleScreen(F(“Battery logger”));
gb.backlight.automatic = false;
gb.backlight.set(0);
gb.display.clear();
gb.display.persistence = true;

if (file.initFAT() == NO_ERROR) {
gb.display.println(F(“SD init OK”));
gb.display.update();
}
else {
gb.display.clear();
gb.display.println(F(“No SD card”));
gb.display.println(verboseError(file.initFAT()));
gb.display.update();
while (1);
}
delay(1000);

if (!file.exists(“BATTERY.TXT”)) {
file.create(“BATTERY.TXT”);
gb.display.println(F(“BATTERY.TXT created”));
}

if (file.openFile(“BATTERY.TXT”, FILEMODE_TEXT_WRITE) == NO_ERROR) {
gb.display.println(F(“BATTERY.TXT opened”));
gb.display.update();
file.writeLn(“I will log battery voltage every 1 minutes”);
file.writeLn(TIME);
}
else {
gb.display.clear();
gb.display.println(F(“Can’t open BATTERY.TXT”));
gb.display.update();
while (1);
}
delay(1000);
}

void loop() {
if (gb.update()) {
if ((gb.frameCount % (20 * 60 * 1)) == 64) { //every 1 minutes
//itoa(gb.battery.voltage, buffer, 10);
// update readings:
currTemperature = SHT2x.GetTemperature();
dtostrf(currTemperature, 5, 2, buffer);
file.writeLn(buffer);
}
if ((gb.frameCount % 20) == 0) {
gb.display.clear();

  gb.display.print(currTemperature);
  gb.display.println("oC");

  gb.display.println(F("Running for"));
  gb.display.print(gb.frameCount / 20 / 60 / 60);
  gb.display.print(":");
  gb.display.print((gb.frameCount / 20 / 60) % 60);
  gb.display.print("\"");
  gb.display.println((gb.frameCount / 20) % 60);
}

}
}