I have recently upgraded to an ESP32 from the standard nano, as I am creating a web server and also want to use an NTP server to set the DS3231 time if the RTC lost power since the last program execution. However, for specific codes, whenever I upload my code, the nano ESP32 panic resets (the COM port connects and disconnects at one second intervals). I have no idea why this is happening- it happened with the DS18B20ESP32 library example sketch too. Can anyone help me with this? This is my code, it isn't finished yet, but I can't think of why it would be resetting like this with my code:
/* _______________________________________________________________________________________________________________________________________________________________________
ㅤㅤ /\ \ / /\
ㅤ ㅤ|_\ \ DATALOGGER / /_|
ㅤㅤ |__\ \________________________________ 20x4 LCD, SD ADAPTER, DS3231, DS18B20 (5.1kPU), FLOAT SWITCH ________________________________/ /__|
ㅤㅤ |___\ \____________________________________________________________________/ /___|
ㅤㅤ |____\ /____|
ㅤ ㅤ|_____\ _______________________________________________________________________________________________________________________ /_____|
ㅤㅤ \______\ / \ /______/
ㅤㅤ \_____/\______________/ THIS PROGRAM MAY ALSO BE USED AS A GENERAL DATA LOGGER BY MODIFYING THE SENSOR CODE AND INPUTTING THE NECESSARY CODE \______________/\_____/
ㅤ ㅤ \________________________________________________________________________________________________________________________/
___________________________________________________________________________________________________________________________________________________________________________________
ㅤ ㅤ ㅤ ㅤ/ (ALL VCC AND GND TO BE WIRED TO VCC AND GND) \ /
HARDWARE WIRING LIST: / \ PROGRAM DESCRIPTION: /
_____________________/ \_______________________/
ㅤ
_________________________________ _________________________________________________________________
FOR 20X4 LIQUID CRYSTAL DISPLAY: \ / \
............_____________________/ / This program is designed to log data from a DS18B20 temperature \
-VSS GND / | sensor and read a float switch value. Once the SD card is |
-VDD 5V \____ | initialised and the RTC reads the set time, the program will |
-V0 2k RESISTOR \ | create a file in the SD card and name it according to the date |
-RS PIN A0 ____/ | (the date is retrieved using a DS3231 RTC). once the file and |
-RW GND / | file name is created, 8 data samples from all DS18B20 sensors |
-E PIN A1 | | are averaged, formatted and logged within the logging |
-D0 X / | interval into the created file, as well as the time of the day |
-D1 X / | in seconds and the current state of the float switch. If the |
-D2 X \ | program is ran until the next day, data logging will be |
-D3 X \ | stopped, and another file will be created and named according |
-D4 PIN A2 \ | to the date. The liquid crystal display and serial monitor |
-D5 PIN A3 \ | will show all relevant info, and can be used to ensure that the |
-D6 PIN D2 | | program runs correctly, displaying SD card initialisation, RTC |
-D7 PIN D7 / | initialisation, the filename the data is writing to, the time |
-A 10K POT / | the data started logging in DHHMMSS, and the current time of |
-K GND / \ the RTC. If any Errors occur, the LCD or serial monitor will /
_________/ \__________________ display an Error message. __________________/
ㅤ \___________________________/
____________________________
FOR SD CARD ADAPTER MODULE: \
....................________/
-chipSelect PIN D10 \
-MOSI PIN D11 _____/
-MISO PIN D12 /
-SCK PIN D13 /
____________/
_________________
FOR DS3231 RTC: \
..................\
-SCL PIN SCL OR A5 \
-SDA PIN SDA OR A4 |
-SQW X ___________/
_______/
________________________________
FOR DS18B20 TEMPERATURE SENSOR: \
........._______________________/
-POS 5V \
-NEG GND \__
-DQ 5.1kPU \________________
-5.1kPU LINKING PIN D9 AND 5V \______________
-104pF CERAMIC CAPACITOR LIKNING POS AND NEG \
_____________________________________________/
__________________
FOR FLOAT SWITCH: \
............._____/
-POS PIN D4 /
-NEG GND __/
________/
// INCLUDE LIBRARIES AND DEFINED CONSTANTS:
*********************************************************************************************************************************************************************************/
#include <LiquidCrystal.h>
#include <OneWire.h>
#include <Wire.h>
#include <DallasTemperature.h>
#include <SD.h>
#include <SPI.h>
#include <FS.h>
#include <RTClib.h>
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
#include <Time.h>
#define BLUE 6
#define floatSw 7
#define GREEN 8
#define RED 9
#define chipSelect 21
#define buzzer 17
#define ONE_WIRE_BUS 18
#define buzzerTogglePin 13
#define year() 24
#define printAll(txt) Serial.println(txt), lcd.print(txt)
// used as general global variables
/********************************************************************************************************************************************************************************/
File dataFile;
LiquidCrystal lcd(1, 2, 3, 4, 5, 10);
RTC_DS3231 rtc;
time_t now;
tm myTimeInfo;
int year;
int month;
int day;
int hour;
int minute;
int second;
unsigned long tStart = millis();
unsigned long totMillis;
unsigned long lastMillis = 0;
unsigned long logTm = 10000;
unsigned long sampleTm = 1250;
unsigned long tLog = totMillis + logTm;
unsigned long tSample = totMillis + sampleTm;
int buzzerState = 1;
int BTstate;
int buzzerOutState;
byte errCount = 0;
char dirName[9] = "/TANKLOG";
char fileName[16];
char fullPath[22];
const char* ssid = "ssidi";
const char* password = "password";
const char* NTPserver = "pool.ntp.org";
const long UTCoffsetSec = -3600;
const int daylightOffsetSec = 3600;
const char* time_zone = PSTR("GMT0BST,M3.5.0/1,M10.5.0");
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", UTCoffsetSec);
void (*resetFunc)(void) = 0;
// variables only used for the specific type of datalogging
/********************************************************************************************************************************************************************************/
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
// function runs if a hardware error occurs
/********************************************************************************************************************************************************************************/
void hardwareErr() {
while (!SD.begin() || !rtc.begin()) {
digitalWrite(buzzer, 1);
delay(100);
digitalWrite(buzzer, 0);
delay(1900);
}
if (SD.begin(chipSelect) && rtc.begin()) {
lcd.clear();
resetFunc();
}
}
// initialises most of the hardware
/********************************************************************************************************************************************************************************/
void initialisation() {
printAll("Connecting to WiFi..");
WiFi.begin(ssid, password);
while(!WiFi.status() == WL_CONNECTED);
timeClient.begin();
timeClient.update();
sensors.begin();
Wire.begin();
rtc.enable32K();
sensors.setWaitForConversion(false);
lcd.begin(20, 4);
lcd.clear();
sensors.requestTemperatures();
pinMode(buzzer, OUTPUT);
pinMode(buzzerTogglePin, INPUT);
pinMode(floatSw, INPUT_PULLUP);
pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
SD.begin(chipSelect);
Serial.println();
printAll("Initialising SD...");
delay(1000);
if (!SD.begin()) {
lcd.clear();
printAll("SD card mount failed");
hardwareErr();
}
uint8_t cardType = SD.cardType();
if (cardType == CARD_NONE) {
lcd.clear();
printAll("No SD card attached");
hardwareErr();
}
Serial.print("SD Card Type: ");
if (cardType == CARD_MMC) {
Serial.println("MMC");
} else if (cardType == CARD_SD) {
Serial.println("SDSC");
} else if (cardType == CARD_SDHC) {
Serial.println("SDHC");
} else {
Serial.println("UNKNOWN");
}
uint64_t cardSize = SD.cardSize() / (1024 * 1024);
Serial.printf("SD Card Size: %lluMB\n", cardSize);
lcd.setCursor(0, 1);
printAll("Initialising RTC...");
delay(1000);
if (!rtc.begin()) {
lcd.clear();
printAll(F("RTC failed."));
hardwareErr();
}
if(rtc.lostPower()) {
lcd.clear();
printAll("RTC power lost");
lcd.setCursor(0,1);
printAll("Setting time...");
if(WiFi.status() == WL_CONNECTED) {
year = myTimeInfo.tm_year - 100;
month = myTimeInfo.tm_mon + 1;
day = myTimeInfo.tm_mday;
hour = myTimeInfo.tm_hour;
minute = myTimeInfo.tm_min;
second = myTimeInfo.tm_sec;
rtc.adjust(DateTime(year, month, day, hour, minute, second));
}
}
}
// creates the file and name, and prints lcd info if the file is available to write to
/*******************************************************************************************************************************************************************************/
void createFileAndName() {
sprintf(fileName, "%02d-%02d-%d.txt", day, month, year());
strlcpy(fullPath, dirName, sizeof fullPath);
strlcat(fullPath, "/", sizeof fullPath);
strlcat(fullPath, fileName, sizeof fullPath);
SD.mkdir(dirName);
// INITIALISE LCD DISPLAY DATA
/********************************************************************************************************************************************************************************/
Serial.println(fullPath);
lcd.clear();
lcd.print(dirName);
lcd.print(" ");
lcd.print(fileName);
lcd.setCursor(0, 1);
lcd.print(F("TEMP:"));
lcd.setCursor(0, 2);
lcd.print(F("TANK LVL:"));
lcd.setCursor(17, 2);
}
void firstWrite() {
dataFile = SD.open(fullPath, FILE_APPEND);
dataFile.println(fileName);
dataFile.close();
dataFile = SD.open(fullPath, FILE_APPEND);
dataFile.println("#Time Sw Temp");
dataFile.close();
}
// DATA AND DIAGNOSTICS:
/********************************************************************************************************************************************************************************/
void DatalogAndDiagnostics() {
// TIME INFO:
/********************************************************************************************************************************************************************************/
char displayTime[24];
if (!rtc.begin()) {
lcd.clear();
printAll(F("RTC failed"));
printAll(F("RTC failed"));
hardwareErr();
}
if (hour == 0 && minute == 0 && second == 0) {
createFileAndName();
delay(750);
}
unsigned long totMillis = millis() - tStart;
unsigned long totseconds = (millis() - tStart) / 1000;
unsigned long totminutes = totseconds / 60;
unsigned long tothours = totminutes / 60;
unsigned long totdays = tothours / 24;
totseconds %= 60;
totminutes %= 60;
tothours %= 24;
totdays %= 7;
char chardays[2];
char charhours[3];
char charminutes[3];
char charseconds[3];
dtostrf(totdays, 1, 0, chardays);
dtostrf(tothours, 2, 0, charhours);
dtostrf(totminutes, 2, 0, charminutes);
dtostrf(totseconds, 2, 0, charseconds);
sprintf(displayTime, "%02d:%02d:%02d %sd%sh%sm%ss", hour, minute, second, chardays, charhours, charminutes, charseconds);
lcd.setCursor(0, 3);
lcd.print(displayTime);
unsigned long hToM = hour * 60;
unsigned long hToS = hToM * 60;
unsigned long mToS = (minute * 60);
unsigned long sToS = second;
unsigned long tmdayInS = hToS + mToS + sToS;
//SPECIFIC DATALOGGING CODE:
/********************************************************************************************************************************************************************************/
static int floatSwState;
static byte nSample = 0;
const int highTempTm = 1000;
const int tempErrTm = 1500;
const int floatSwTm = 500;
static bool highTempErrState = 0;
static bool hardwareErrState = 0;
static bool floatSwErrState = 0;
lcd.setCursor(10, 2);
if (digitalRead(floatSw) == 1) {
lcd.print("OK ");
floatSwState = 1;
floatSwErrState = 0;
} else if (digitalRead(floatSw == 0)) {
lcd.print("NOT OK");
floatSwState = 0;
floatSwErrState = 1;
if (totMillis - lastMillis > floatSwTm) {
lastMillis = totMillis;
if (buzzerOutState == 1) {
digitalWrite(buzzer, 1);
}
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 1);
} else {
digitalWrite(buzzer, 0);
}
}
lcd.setCursor(6, 1);
sensors.getTempCByIndex(0);
lcd.print(sensors.getTempCByIndex(0));
lcd.print("\337C ");
sensors.requestTemperatures();
if (sensors.getTempCByIndex(0) >= 0 && sensors.getTempCByIndex(0) <= 22) {
digitalWrite(RED, 0);
digitalWrite(GREEN, 1);
digitalWrite(BLUE, 0);
highTempErrState = 0;
} else if (sensors.getTempCByIndex(0) > 22 && sensors.getTempCByIndex(0) <= 23) {
analogWrite(RED, 255);
analogWrite(GREEN, 255);
digitalWrite(BLUE, 0);
highTempErrState = 0;
} else if (sensors.getTempCByIndex(0) > 23 && sensors.getTempCByIndex(0) <= 24) {
analogWrite(RED, 255);
analogWrite(GREEN, 90);
digitalWrite(BLUE, 0);
highTempErrState = 0;
} else if (sensors.getTempCByIndex(0) > 24 && sensors.getTempCByIndex(0) <= 25) {
digitalWrite(RED, 1);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
highTempErrState = 0;
} else if (sensors.getTempCByIndex(0) > 25) {
highTempErrState = 1;
if (totMillis - lastMillis > highTempTm) {
lastMillis = totMillis;
if (buzzerOutState == 1) {
digitalWrite(buzzer, 1);
}
digitalWrite(RED, 1);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
} else {
digitalWrite(buzzer, 0);
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
}
} else {
hardwareErrState = 1;
if (totMillis - lastMillis > tempErrTm) {
lastMillis = totMillis;
if (buzzerOutState == 1) {
digitalWrite(buzzer, 1);
}
digitalWrite(RED, 1);
digitalWrite(GREEN, 1);
digitalWrite(BLUE, 1);
} else {
digitalWrite(buzzer, 0);
digitalWrite(RED, 0);
digitalWrite(GREEN, 0);
digitalWrite(BLUE, 0);
}
}
static float aveT1 = sensors.getTempCByIndex(0);
static float totT1 = aveT1;
static char charAveT1[9];
static char charTotT1[9];
static char charTemp[9];
dtostrf(aveT1, 7, 2, charAveT1);
dtostrf(totT1, 8, 2, charTotT1);
dtostrf(sensors.getTempCByIndex(0), 7, 2, charTemp);
if (totMillis > tSample) {
nSample += 1;
aveT1 = totT1 / nSample;
totT1 += sensors.getTempCByIndex(0);
sensors.requestTemperatures();
char sampleData[70];
sprintf(sampleData, "Sample: %d Sw: %d temp(°C):%s Ave:%s Tot:%s",
nSample, floatSwState, charTemp, charAveT1, charTotT1);
Serial.println(sampleData);
tSample += sampleTm;
}
if(!sensors.getTempCByIndex(0) > 0 && !sensors.getTempCByIndex(0) < 70 && errCount <=1) {
dataFile = SD.open(fullPath, FILE_APPEND);
dataFile.print("ERROR: ");
dataFile.close();
errCount += 1;
}
if (highTempErrState == 0 && hardwareErrState == 0 && floatSwErrState == 0) {
buzzerOutState = 0;
digitalWrite(buzzer, 0);
}
// OPEN FILE:
/********************************************************************************************************************************************************************************/
char aveData[20];
char charTmdayInS[7];
dtostrf(tmdayInS, 5, 0, charTmdayInS);
sprintf(aveData, "%s %d%s", charTmdayInS, floatSwState, charAveT1);
dataFile = SD.open(fullPath, FILE_APPEND);
if (!dataFile) {
printAll(F("File write Err"));
lcd.clear();
printAll(F("File write Err"));
hardwareErr();
}
if (totMillis > tLog) {
dataFile.println(aveData);
dataFile.close();
Serial.println("#Time Sw Temp");
Serial.println(aveData);
tLog += logTm;
}
if (nSample > 7) {
nSample = 0;
totT1 = sensors.getTempCByIndex(0);
errCount = 0;
}
// ALARM
/********************************************************************************************************************************************************************************/
static bool buzzerState = 1;
static bool lastBTstate = 0;
unsigned long lastDebounceTime = 0;
const byte debounceDelay = 50;
lcd.setCursor(15, 1);
lcd.print("ALARM");
int newBTstate = analogRead(buzzerTogglePin) < 300 ? 1 : 0;
if (newBTstate != lastBTstate) {
lastDebounceTime = totMillis;
}
if ((totMillis - lastDebounceTime) > debounceDelay) {
if (newBTstate != BTstate) {
BTstate = newBTstate;
if (BTstate == 1) {
buzzerState = !buzzerState;
}
}
}
lcd.setCursor(17, 2);
if (buzzerState == 1) {
buzzerOutState = 1;
lcd.print(" ON");
}
else if (buzzerState == 0) {
buzzerOutState = 0;
lcd.print("OFF");
}
lastBTstate = newBTstate;
}
// SETUP() FUNCTION
/********************************************************************************************************************************************************************************/
void setup() {
Serial.begin(115200);
while (!Serial);
initialisation();
createFileAndName();
firstWrite();
tStart = millis();
}
// LOOP() FUNCTION
/********************************************************************************************************************************************************************************/
void loop() {
DatalogAndDiagnostics();
}
// END OF PROGRAM
/********************************************************************************************************************************************************************************/
@ptillisch I've looked through some ESP32 forums and someone said you have a great understanding of the boards. Could you help me with this problem? I only have ever used atmega328p and rp2040 boards before I bought my arduino nano ESP32-S3