Hello,
I am very new to coding and I have rewritten code I made with chatGPT, because it didnt do what I wanted. I am using an ESP32-S3 to controll a reeffilter (rollermat). It;s connected to 3 buttons, 1 switch, 3 LEDs and an ISP-display 240x320. I wanted to show realtime info on the display of states (buttons and switch) and variables. So i thought it would be best to split it over 2 cores. Now it gets tricky and I cant get it to work.
14:55:09.251 -> Guru Meditation Error: Core 0 panic'ed (IllegalInstruction). Exception was unhandled.
14:55:09.251 -> Memory dump at 0x420033d8: fff125ff 00000090 21004136
14:55:09.251 -> Core 0 register dump:
14:55:09.251 -> PC : 0x420033dc PS : 0x00060c30 A0 : 0x00000000 A1 : 0x3fca6ed0
14:55:09.251 -> A2 : 0x00000000 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000000
14:55:09.251 -> A6 : 0x00000000 A7 : 0x00000000 A8 : 0x820033dc A9 : 0x3fca6eb0
14:55:09.251 -> A10 : 0x3fc99c00 A11 : 0x00000000 A12 : 0x00000001 A13 : 0x00001ecd
14:55:09.251 -> A14 : 0x80000001 A15 : 0xb33fffff SAR : 0x00000017 EXCCAUSE: 0x00000000
14:55:09.251 -> EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000
14:55:09.251 ->
14:55:09.251 ->
14:55:09.251 -> Backtrace: 0x420033d9:0x3fca6ed0
14:55:09.251 ->
14:55:09.251 ->
14:55:09.252 ->
14:55:09.252 ->
14:55:09.252 -> ELF file SHA256: 0f2fc2409cf4dd56
14:55:09.252 ->
14:55:09.252 -> Rebooting...
14:55:09.252 -> ESP-ROM:esp32s3-20210327
14:55:09.252 -> Build:Mar 27 2021
14:55:09.294 -> rst:0xc (RTC_SW_CPU_RST),boot:0x8 (SPI_FAST_FLASH_BOOT)
14:55:09.294 -> Saved PC:0x403778ed
14:55:09.294 -> SPIWP:0xee
14:55:09.294 -> mode:DIO, clock div:1
14:55:09.294 -> load:0x3fce3818,len:0x508
14:55:09.294 -> load:0x403c9700,len:0x4
14:55:09.294 -> load:0x403c9704,len:0xad0
14:55:09.294 -> load:0x403cc700,len:0x29e4
14:55:09.294 -> entry 0x403c9880
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <WiFi.h>
#include <time.h>
#include <Preferences.h>
#include <Adafruit_NeoPixel.h>
// Pin definitions
#define LED_PIN 48 // Builtin LED
#define NUM_LEDS 1
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
#define FLOAT_SWITCH_PIN 4
#define RESET_BUTTON_PIN 41
#define CW_BUTTON_PIN 42
#define CCW_BUTTON_PIN 40
#define CW_MOTOR_PIN 15
#define CCW_MOTOR_PIN 16
#define TFT_CS 9
#define TFT_RST 46
#define TFT_DC 3
#define TFT_MOSI 8
#define TFT_SCK 18
#define TFT_LED 17
#define GREEN_LED_PIN 39
#define YELLOW_LED_PIN 38
#define RED_LED_PIN 37
//Setup definities
const char *ssid = "X";
const char *password = "X";
const char *ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600; // UTC +1 (CET)
const int daylightOffset_sec = 3600; // 1 hour for daylight saving time (CEST)
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_MOSI, TFT_SCK, TFT_RST);
Preferences preferences;
//Variabelen
unsigned long Tijd_rotatie = 10000;
float Afst_rotatie = 50; //cm
unsigned long Float_tijd = 10000;
unsigned long Reset_knop = 5000;
float rotatieduur = 10000;
float Rolverbruik = 0;
float Rollengte = 2500;
float Totaal_rotaties = 0;
unsigned long Laatste_rotatie = 0;
unsigned long Totaal_rotatietijd = 0;
unsigned long Gem_rotatietijd = 0;
bool displayUpdate = true;
int seconds_left = 0;
int start_tijd = 0;
int duur = 0;
int verbruik = 0;
unsigned long last_rotation_time = 0;
void (*resetFunc)(void) = 0;
void connectWiFi() {
WiFi.begin(ssid, password);
int attempts = 0;
int max_attempts = 10; // Maximum number of attempts before giving up
bool connected = false;
while (attempts < max_attempts && !connected) {
delay(5000); // Wait 5 seconds before checking connection status
attempts++;
if (WiFi.status() == WL_CONNECTED) {
connected = true;
}
}
if (connected) {
uint8_t brightness = 100;
strip.setBrightness(brightness);
strip.setPixelColor(0, strip.Color(0, 0, 255)); // Blue
strip.show();
delay(1000);
} else {
uint8_t brightness = 255;
strip.setBrightness(brightness);
strip.setPixelColor(0, strip.Color(255, 0, 0)); // Red
strip.show();
delay(5000);
// Here you could implement a fallback mechanism or retry logic if needed
}
}
void syncTime() {
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
uint8_t brightness = 100;
strip.setBrightness(brightness);
strip.setPixelColor(0, strip.Color(0, 255, 0)); // Green
strip.show();
delay(1000); // Turn on yellow LED if time synchronized
} else {
uint8_t brightness = 255;
strip.setBrightness(brightness);
strip.setPixelColor(0, strip.Color(255, 255, 0)); // Yellow
strip.show();
delay(5000);
}
}
String getTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "N/A";
}
char buffer[10];
strftime(buffer, sizeof(buffer), "%H:%M:%S", &timeinfo);
return String(buffer);
}
String getDate() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
return "N/A";
}
char buffer[12];
strftime(buffer, sizeof(buffer), "%d-%m-%Y", &timeinfo);
return String(buffer);
}
// Function to split duration into days, hours, minutes, and seconds
void formatDuration(unsigned long duration, int &days, int &hours, int &minutes, int &seconds) {
days = duration / 86400;
duration %= 86400;
hours = duration / 3600;
duration %= 3600;
minutes = duration / 60;
seconds = duration % 60;
}
void displayBasis() {
static unsigned long float_schakel_tijd2 = 0; // Ensure this is static to maintain value between function calls
bool floatSwitchState2 = digitalRead(FLOAT_SWITCH_PIN) == LOW; // Reading the state of the float switch
unsigned long current_time2 = millis(); // Get the current time
if (displayUpdate == true) {
tft.fillScreen(ST77XX_BLACK);
displayUpdate = false;
} else {
tft.setCursor(10, 10);
tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);
tft.setTextSize(2);
tft.print(getTime());
tft.setCursor(150, 10);
tft.print(getDate());
tft.setTextSize(1);
tft.setCursor(30, 10);
tft.print("Verbruik rol: ");
tft.setCursor(30, 150);
tft.print(Rolverbruik);
tft.setCursor(50, 10);
tft.print("Aantal rotaties: ");
tft.setCursor(50, 150);
tft.print(Totaal_rotaties);
unsigned long current_time = millis();
int days, hours, minutes, seconds;
// Duration since last rotation
unsigned long duration_since_last_rotation = (current_time - last_rotation_time) / 1000;
formatDuration(duration_since_last_rotation, days, hours, minutes, seconds);
tft.setCursor(70, 10);
tft.print("Sinds laatste rotatie: ");
tft.setCursor(70, 150);
tft.printf("%02d:%02d:%02d\n", days, hours, minutes, seconds);
tft.setCursor(90, 10);
tft.print("Gem. tijd rotatie: ");
tft.setCursor(90, 150);
int days1, hours1, minutes1, seconds1;
// Duration since last rotation
unsigned long Gem_rotatietijd = Totaal_rotatietijd / Totaal_rotaties;
formatDuration(Gem_rotatietijd, days1, hours1, minutes1, seconds1);
tft.setCursor(70, 10);
}
}
void displayReset() {
if (displayUpdate == true) {
tft.fillScreen(ST77XX_BLACK);
displayUpdate = false;
} else {
tft.setCursor(150, 100);
tft.setTextColor(ST77XX_RED, ST77XX_BLACK);
tft.setTextSize(2);
tft.print(seconds_left);
}
if (seconds_left <= 0) {
unsigned long reset_complete_time = millis() + 5000;
while (millis() < reset_complete_time) {
// Do nothing, wait for 5 seconds
};
tft.fillScreen(ST77XX_BLACK);
displayBasis();
}
}
void startMotorKlok() {
digitalWrite(CW_MOTOR_PIN, HIGH);
digitalWrite(CCW_MOTOR_PIN, LOW);
}
void startMotorTegen() {
digitalWrite(CW_MOTOR_PIN, LOW);
digitalWrite(CCW_MOTOR_PIN, HIGH);
}
void stopMotor() {
digitalWrite(CW_MOTOR_PIN, LOW);
digitalWrite(CCW_MOTOR_PIN, LOW);
}
void motorKnoppen() {
bool cwButtonState = digitalRead(CW_BUTTON_PIN) == LOW; // Controleer of CW knop ingedrukt is
bool ccwButtonState = digitalRead(CCW_BUTTON_PIN) == LOW; // Controleer of CCW knop ingedrukt is
unsigned long current_time = millis(); // Huidige tijd verkrijgen
if (cwButtonState && ccwButtonState) {
// Beide knoppen tegelijkertijd ingedrukt
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(10, 100);
tft.setTextColor(ST77XX_RED);
tft.setTextSize(3);
tft.print("REBOOT");
displayUpdate = true;
delay(5000);
resetFunc(); // Reset Arduino (vereist een functie resetFunc() die elders gedefinieerd is)
} else if (cwButtonState) {
// Alleen CW knop ingedrukt
startMotorKlok(); // Start de motor met de klok mee
start_tijd = current_time; // Tijd bijhouden wanneer motor is gestart
duur = current_time - start_tijd; // Bereken de verstreken tijd
verbruik = Rollengte * (duur / rotatieduur); // Bereken verbruik
Rolverbruik += verbruik; // Update totaal verbruik
Totaal_rotaties += (verbruik / Afst_rotatie);
} else if (ccwButtonState) {
// Alleen CCW knop ingedrukt
startMotorTegen(); // Start de motor tegen de klok in
start_tijd = current_time; // Tijd bijhouden wanneer motor is gestart
duur = current_time - start_tijd; // Bereken de verstreken tijd
verbruik = Rollengte * (duur / rotatieduur); // Bereken verbruik
Rolverbruik -= verbruik;// Update totaal verbruik (aftrekken bij tegen de klok in)
Totaal_rotaties -= (verbruik / Afst_rotatie);
} else {
// Geen knoppen ingedrukt
stopMotor(); // Stop de motor
duur = 0; // Reset de tijd
}
}
void floatSwitch() {
static unsigned long float_schakel_tijd = 0; // Ensure this is static to maintain value between function calls
bool floatSwitchState = digitalRead(FLOAT_SWITCH_PIN) == LOW; // Reading the state of the float switch
unsigned long current_time = millis(); // Get the current time
if (floatSwitchState) { // If the float switch is LOW
if (float_schakel_tijd == 0) {
float_schakel_tijd = current_time; // Set the switch time
} else if (current_time - float_schakel_tijd >= Float_tijd) {
startMotorKlok(); // Start the motor
delay(rotatieduur); // Wait for the rotation duration
stopMotor(); // Stop the motor
float_schakel_tijd = 0; // Reset the switch time
Totaal_rotaties ++;
Rolverbruik += Afst_rotatie;
Totaal_rotatietijd += (current_time - last_rotation_time);
last_rotation_time = current_time;
}
} else { // If the float switch is HIGH
float_schakel_tijd = 0; // Reset the switch time
}
}
void resetKnop() {
static unsigned long reset_druk_tijd = 0;
bool ResetButtonState = digitalRead(RESET_BUTTON_PIN) == LOW;
unsigned long current_time = millis();
if (ResetButtonState) {
if (reset_druk_tijd == 0) {
reset_druk_tijd = current_time;
displayUpdate = true;
displayReset();
} else {
seconds_left = (Reset_knop - (current_time - reset_druk_tijd)) / 1000; // Update the existing seconds_left variable
if (current_time - reset_druk_tijd >= Reset_knop) {
Rolverbruik = 0;
Totaal_rotaties = 0;
Laatste_rotatie = 0;
Totaal_rotatietijd = 0;
preferences.putFloat("Rolverbruik", Rolverbruik);
preferences.putUInt("Totaal_rotaties", Totaal_rotaties);
preferences.putULong("Laatste_rotatie", Laatste_rotatie);
preferences.putULong("Totaal_rotatietijd", Totaal_rotatietijd);
tft.fillScreen(ST77XX_BLACK);
tft.setCursor(10, 100);
tft.setTextColor(ST77XX_RED);
tft.setTextSize(2);
tft.print("RESET COMPLETE");
delay(5000);
resetFunc();
}
}
} else {
displayUpdate = true;
displayBasis();
reset_druk_tijd = 0;
}
}
void LEDS() {
if (Rolverbruik < 0.75 * Rollengte) {
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
} else if (Rolverbruik < 0.9 * Rollengte) {
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
} else {
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, HIGH);
}
}
void handleLogic(void* parameter) {
motorKnoppen();
floatSwitch();
resetKnop();
}
void handleDisplay(void* parameter) {
displayBasis();
displayReset();
LEDS();
}
void setup() {
Serial.begin(115200);
pinMode(FLOAT_SWITCH_PIN, INPUT_PULLUP);
pinMode(RESET_BUTTON_PIN, INPUT_PULLUP);
pinMode(CW_BUTTON_PIN, INPUT_PULLUP);
pinMode(CCW_BUTTON_PIN, INPUT_PULLUP);
pinMode(CW_MOTOR_PIN, OUTPUT);
pinMode(CCW_MOTOR_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(YELLOW_LED_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
digitalWrite(TFT_LED, HIGH);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
tft.init(240, 320);
tft.invertDisplay(0);
tft.setRotation(1);
preferences.begin("my-app", false);
Rolverbruik = preferences.getFloat("Rolverbruik", 0);
Totaal_rotaties = preferences.getUInt("Totaal_rotaties", 0);
Laatste_rotatie = preferences.getULong("Laatste_rotatie", 0);
Totaal_rotatietijd = preferences.getULong("Totaal_rotatietijd", 0);
connectWiFi();
syncTime();
// Create tasks for both cores
xTaskCreatePinnedToCore(handleLogic, "handleLogic", 4096, NULL, 1, NULL, 0); // Core 0
xTaskCreatePinnedToCore(handleDisplay, "handleDisplay", 4096, NULL, 1, NULL, 1); // Core 1
}
void loop() {
// Main code to run repeatedly here
}