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.