Program looping setup [SOLVED]

I'm trying to create a datalogger with an ELEGOO UNO R3 board.

Hardware:

  • DS1307 RTC
  • 10K NTC thermistor
  • DS18B20 temperature sensor
  • 32GB SDHC card (with microSD card adapter).
  • 16x2 LCD

The link of the purchase:

[elegoo purchase link]([ELEGOO UNO R3 Project The Most Complete Ultimate Starter Kit Compatible with Arduino IDE w/TUTORIAL, UNO R3 Controller Board, LCD 1602, Servo, Stepper Motor : Amazon.co.uk: Toys & Games])

As I want the data logger to be used without a pc (just plugged into a system and ran for a period of time) I am trying to use the lcd screen to display information, such as debugging, file name and current time. However, any time I enter the lcd code into the program, it loops in setup. Here is an example of the serial monitor output:

Initialising SD card...

SD card initialised.

RTC initialised

The file: 29-01-24.txt already exists. Any logged data will be appended to the already existing file.

Initialising SD card...

SD card initialised.

RTC initialised

The file: 29-01-24.txt already exists. Any logged data will be appended to the already existing file.

and the full code:

#include <OneWire.h>

#include <DallasTemperature.h>

#include <SPI.h>

#include <SD.h>

#include <LiquidCrystal.h>

#include <Wire.h>

#include <TimeLib.h>

#include <DS1307RTC.h>

#define totalTime() millis() / 1000

#define ONE_WIRE_BUS 9

#define getT1() sensors.getTempCByIndex(0)

#define requestT1() sensors.requestTemperatures()

#define T2Pin A1

#define year() tmYearToCalendar(tm.Year) - 2000

File dataFile;

OneWire oneWire(ONE_WIRE_BUS);

DallasTemperature sensors(&oneWire);

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

tmElements_t tm;

const int CS = 10;

const short logInterval = 10;

const float sampleInterval = 1.25;

static int logTime = totalTime() + logInterval;

static float sampleTime = totalTime() + sampleInterval;

const short userDelay = 2000;

static short numSamples = 0;

static float averageT1;

static float averageT2;

static float totalT1 = 0;

static float totalT2 = 0;

void initialisation() { //used in setup to initialise the RTC and SD card

  while (!Serial); //wait for serial port to connect, putting this before serial.begin ensures that the program does not reset every time the serial monitor opens

  Serial.begin(115200); //initialise serial connection BAUD rate

  lcd.begin(16, 2); //initialise lcd with display parameters

  Serial.println(); //prints a new line to format serial monitor data in case of zero bytes printed during serial connection

  lcd.setCursor(0, 0);

  Serial.println("Initialising SD card...");

  lcd.print("Initialising SD");

  delay(userDelay);

  lcd.clear();

 lcd.setCursor(0, 0);

  if (!SD.begin(CS)) { //checks if SD card is available and prints error message if not

    Serial.println("SD card initialisation failed. Check SD card is present and wiring is correct");

    lcd.print("SD failed");

    while (1); //create an endless loop with nothing to do if sd card fails

  } //end if

  else {  //prints message that the SD has been initialised

    Serial.println("SD card initialised.");

    lcd.print("SD initialised");

  }  //end else

  delay(userDelay);

  lcd.clear();

  lcd.setCursor(0, 0);

  if (RTC.read(tm)) { //initialises RTC using the set time

    Serial.println("RTC initialised");

    lcd.print("RTC initialised");

  } //end RTC if

  else {

    Serial.println("RTC initialisation failed. Please check RTC module is present and wiring is correct");

    lcd.print("RTC failed");

  } //end else 

  delay(userDelay);

  lcd.clear();

  lcd.setCursor(0, 0);

} //end initialisation()

void createFileAndName() { //creates file and names the file according to the date

  requestT1();  //requests data before first loop iteration to print data at the log interval

  char fileName[13]; //buffer to store file name

  sprintf(fileName, "%02d-%02d-%d.txt", tm.Day, tm.Month, year());  //formats and concatenates the RTC data to create the file name

  if (!SD.exists(fileName)) { //creates file if the file is not already created

    Serial.println("Creating file...");

    Serial.print("File name: ");

    Serial.println(fileName);

  } //end SD if

  else { //appends data to already existing file

    Serial.print("The file: ");

    Serial.print(fileName);

    Serial.println(" already exists. Any logged data will be appended to the already existing file.");

  } //end else

  lcd.print(fileName);

  dataFile = SD.open(fileName, FILE_WRITE);
  
  if (dataFile) {  //checks if the file is available

    dataFile.println();

    dataFile.println("TEMPERATURE DATA LOGGER");

    dataFile.close();

    Serial.println("TEMPERATURE DATA LOGGER");

  } //end dataFile if

  else {  //if the file does not open

    Serial.println("Error opening and writing to file");

    while (1);  //create an endless loop with nothing to do if file does not open

  }  //end else

} //end createFileAndName()

void getAverageReading() { //prints and logs average temperature data to the file

  lcd.setCursor(0, 1);

  RTC.read(tm);

  char displayTime[12];

  sprintf(displayTime, "Time: %02d:%02d", tm.Hour, tm.Minute);

  lcd.print(displayTime);

  char fileName[13]; //buffer to store file name

  sprintf(fileName, "%02d-%02d-%d.txt", tm.Day, tm.Month, year());  //formats and concatenates the RTC data to create the file name

  dataFile = SD.open(fileName, FILE_WRITE); //opens file to write to

   if (!SD.exists(fileName)) { //creates file if the file is not already created

    createFileAndName();

  } //end SD if
  
  int tempReading = analogRead(T2Pin); //request for T2 not needed as only a calculation from the analog pin reading is necessary

  double tempK = log(10000.0 * ((1024.0 / tempReading - 1)));

  tempK = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * tempK * tempK)) * tempK);

  double T2 = tempK - 273.15;

  getT1(); //gets the temperature from the request within setup

  requestT1(); //requests temperature in the loop, which will be used in the next loop iteration

  char averageData[61]; //the following characters will be stored within the average data character array

  char charLogTime[8];

  dtostrf(logTime, 7, 0, charLogTime);

  char charAverageT1[9];

  dtostrf(averageT1, 8, 2, charAverageT1);

  char charAverageT2[9];

  dtostrf(averageT2, 8, 2, charAverageT2);

  sprintf(averageData, "%02d:%02d:%02d  time:%7ds  T1:%sºC  T2:%sºC", tm.Hour, tm.Minute, tm.Second, logTime, charAverageT1, charAverageT2); //sprintf concatenates these characters into a readable format

  if (totalTime() > sampleTime) { //increments the following every 1.25 seconds

    numSamples += 1;

    totalT1 += getT1();

    totalT2 += T2;

    sampleTime += sampleInterval;

  }  //end totalTime if

  averageT1 = totalT1 / numSamples;  //calculate total of T1

  averageT2 = totalT2 / numSamples;  //calculate total of T2

  if (dataFile) {  //checks if the file is available

    if (totalTime() > logTime) {  //prints the data within the logging interval

      dataFile.println(averageData);

      Serial.println(averageData);

      logTime += logInterval;

    }  //end if

    if (numSamples > 7) {  //resets the number of samples and the total temperature readings

      numSamples = 0;

      totalT1 = 0;

      totalT2 = 0;

    }  //end numSamples if

  }  //end dataFile if

  else {  //if the file does not open

    Serial.println("Error opening and writing to file");

    while (1);  //create an endless loop with nothing to do if file does not open

  }  //end else

  dataFile.close();

}  //end getAverageReading()

void setup() {  //runs once at the start of the program

  initialisation(); //runs initialisation() user defined function in setup

  createFileAndName();  //runs createFileAndName() user defined function in setup

}  //end setup

void loop() {  //loops getAverageReading() user defined function

  getAverageReading();

}  //end loop

Even when I comment the lcd code out, the program is unable to open the file. The code isn't finished so I still need to add a little to it (e.g. printing the log time on the lcd next to the clock time and using push buttons to start/stop the datalogging process). Any help would be appreciated, I haven't been programming for long so it's a little confusing.

assuming year fits on 4 digits you build a name like `29-01-2024.txt" which requires 15 bytes and you only allocated 13 ➜ you are overflowing and messing up with memory you don't own.

At the top in definitions, I have taken the year and subtracted 2000, then called that #define function to only use the last 2 digits, hence the fileName being e.g. 29-01-24.txt. Therefore only 12 bytes are being used (adherent to 8.3 format) + extra byte for good practice.

ah I missed that sorry

Possibly a memory problem, the sketch uses 83% of the ram (dynamic memory).

I'm pretty sure it is, I changed all the serial print debugging statements to debug and put debug equal to 0. Took a bit of code out that wasn't necessary and I'm down to 68% program storage and 62% dynamic memory and the code is working fine. Just need to try fit in the lcd code somehow without using so much memory.

Start by using the F() macro when printing text to the Serial monitor

Serial.println(F("SD card initialisation failed. Check SD card is present and wiring is correct"));

See PROGMEM - Arduino Reference

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.