diff --git a/AutoFilmESP32/.cproject b/AutoFilmESP32/.cproject
new file mode 100644
index 0000000..7f5fb0d
--- /dev/null
+++ b/AutoFilmESP32/.cproject
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AutoFilmESP32/.gitignore b/AutoFilmESP32/.gitignore
new file mode 100644
index 0000000..dcd90ee
--- /dev/null
+++ b/AutoFilmESP32/.gitignore
@@ -0,0 +1,2 @@
+/Release/
+/sloeber.ino.cpp
diff --git a/AutoFilmESP32/.project b/AutoFilmESP32/.project
new file mode 100644
index 0000000..322346a
--- /dev/null
+++ b/AutoFilmESP32/.project
@@ -0,0 +1,75 @@
+
+
+ AutoFilmESP32
+
+
+
+
+
+ io.sloeber.core.inoToCpp
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.core.ccnature
+ io.sloeber.arduinonature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+
+
+
+ core/core
+ 2
+ ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/cores/esp32
+
+
+ core/variant
+ 2
+ ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/variants/esp32
+
+
+ libraries/AccelStepper
+ 2
+ C:/Users/gordon/Documents/Arduino/libraries/AccelStepper
+
+
+ libraries/DallasTemperature
+ 2
+ C:/Users/gordon/Documents/Arduino/libraries/DallasTemperature
+
+
+ libraries/Keypad
+ 2
+ C:/Users/gordon/Documents/Arduino/libraries/Keypad
+
+
+ libraries/LiquidCrystal_I2C
+ 2
+ C:/Users/gordon/Documents/Arduino/libraries/LiquidCrystal_I2C
+
+
+ libraries/OneWire
+ 2
+ C:/Users/gordon/Documents/Arduino/libraries/OneWire
+
+
+ libraries/Wire
+ 2
+ ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/libraries/Wire
+
+
+
diff --git a/AutoFilmESP32/.settings/language.settings.xml b/AutoFilmESP32/.settings/language.settings.xml
new file mode 100644
index 0000000..842132e
--- /dev/null
+++ b/AutoFilmESP32/.settings/language.settings.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/AutoFilmESP32/.settings/org.eclipse.core.resources.prefs b/AutoFilmESP32/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/AutoFilmESP32/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/=UTF-8
diff --git a/AutoFilmESP32/.sproject b/AutoFilmESP32/.sproject
new file mode 100644
index 0000000..7ef5964
--- /dev/null
+++ b/AutoFilmESP32/.sproject
@@ -0,0 +1,29 @@
+Config.Release.board.BOARD.ID=esp32
+Config.Release.board.BOARD.MENU.CPUFreq=240
+Config.Release.board.BOARD.MENU.DebugLevel=error
+Config.Release.board.BOARD.MENU.EraseFlash=none
+Config.Release.board.BOARD.MENU.EventsCore=0
+Config.Release.board.BOARD.MENU.FlashFreq=80
+Config.Release.board.BOARD.MENU.FlashMode=qio
+Config.Release.board.BOARD.MENU.FlashSize=4M
+Config.Release.board.BOARD.MENU.JTAGAdapter=bridge
+Config.Release.board.BOARD.MENU.LoopCore=1
+Config.Release.board.BOARD.MENU.PSRAM=enabled
+Config.Release.board.BOARD.MENU.PartitionScheme=default
+Config.Release.board.BOARD.MENU.UploadSpeed=921600
+Config.Release.board.BOARD.MENU.ZigbeeMode=default
+Config.Release.board.BOARD.TXT=C:\Users\gordon\Sloeber\arduinoPlugin\packages\esp32\hardware\esp32\3.0.1\boards.txt
+Config.Release.board.PROGRAMMER.NAME=Esptool
+Config.Release.board.UPLOAD.PORT=COM10
+Config.Release.compile.sloeber.extra.all=
+Config.Release.compile.sloeber.extra.archive=
+Config.Release.compile.sloeber.extra.assembly=
+Config.Release.compile.sloeber.extra.c.compile=
+Config.Release.compile.sloeber.extra.compile=
+Config.Release.compile.sloeber.extra.cpp.compile=
+Config.Release.compile.sloeber.extra.link=
+Config.Release.compile.sloeber.size.custom=
+Config.Release.compile.sloeber.size.type=RAW_RESULT
+Config.Release.compile.sloeber.warning_level=NONE
+Config.Release.compile.sloeber.warning_level.custom=
+Config.Release.other.IS_VERSION_CONTROLLED=false
diff --git a/AutoFilmESP32/AutoFilmESP32.ino b/AutoFilmESP32/AutoFilmESP32.ino
new file mode 100644
index 0000000..b0422a0
--- /dev/null
+++ b/AutoFilmESP32/AutoFilmESP32.ino
@@ -0,0 +1,46 @@
+#include "config.h"
+#include "motor.h"
+#include "temperature.h"
+#include "display.h"
+#include "menu.h"
+#include "devSequence.h"
+#include "sound.h"
+#include "watchdog.h"
+
+// Function declarations
+void setup();
+void loop();
+
+void setup() {
+ Serial.begin(115200);
+
+ // Disable the watchdog timers
+ disableWatchdogTimers();
+
+ // Initialize LCD
+ Wire.begin(21, 22);
+ lcd.init();
+ lcd.backlight();
+
+ lcd.createChar(0, thermometer);
+
+ // Set pin modes
+ pinMode(EN_PIN, OUTPUT);
+ digitalWrite(EN_PIN, HIGH); // Disable motor initially
+ pinMode(beeperPin, OUTPUT);
+ // Set stepper motor properties
+ stepper.setMaxSpeed(SPEED);
+ stepper.setAcceleration(9600); // Set acceleration
+
+ // Display welcome message
+ lcd.setCursor(6, 1);
+ lcd.print("AUTOFILM");
+ lcd.setCursor((20 - strlen(version)) / 2, 3);
+ lcd.print(version);
+ delay(1000);
+ lcd.clear();
+}
+
+void loop() {
+ startingMenu();
+}
diff --git a/AutoFilmESP32/config.cpp b/AutoFilmESP32/config.cpp
new file mode 100644
index 0000000..9d78bd7
--- /dev/null
+++ b/AutoFilmESP32/config.cpp
@@ -0,0 +1,43 @@
+#include "config.h"
+
+// Global variables definition
+const char* version = "V0.1.0 20240625";
+const byte ROWS = 5;
+const byte COLS = 4;
+byte rowPins[ROWS] = { 19, 18, 5, 17, 16 };
+byte colPins[COLS] = { 15, 2, 0, 4 };
+
+char keys[ROWS][COLS] = {
+ { 'F', 'E', '#', '*' },
+ { '1', '2', '3', 'U' },
+ { '4', '5', '6', 'D' },
+ { '7', '8', '9', 'X' },
+ { 'L', '0', 'R', 'E' }
+};
+
+Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
+LiquidCrystal_I2C lcd(0x27, LCD_COLUMNS, LCD_ROWS);
+AccelStepper stepper(AccelStepper::DRIVER, PULSE_PIN, DIR_PIN);
+OneWire oneWire(TEMP_SENSOR_PIN);
+DallasTemperature sensors(&oneWire);
+
+String devPgm = "";
+int run;
+const int beeperPin = 25;
+
+TaskHandle_t motorTaskHandle = NULL;
+TaskHandle_t tempTaskHandle = NULL;
+
+unsigned long processStartTime;
+unsigned long processTimeMillis;
+
+byte thermometer[8] = {
+ B00100,
+ B01100,
+ B00100,
+ B01100,
+ B00100,
+ B01110,
+ B01110,
+ B01110
+};
diff --git a/AutoFilmESP32/config.h b/AutoFilmESP32/config.h
new file mode 100644
index 0000000..0352c99
--- /dev/null
+++ b/AutoFilmESP32/config.h
@@ -0,0 +1,41 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+// Constants and definitions
+#define LCD_COLUMNS 20
+#define LCD_ROWS 4
+#define PULSE_PIN 12
+#define DIR_PIN 14
+#define EN_PIN 27
+#define STEPS_PER_REV 4800
+#define RPM 60
+#define SPEED (RPM * STEPS_PER_REV / 60.0)
+#define TEMP_SENSOR_PIN 13
+#define NUM_DEV_SEQUENCES 6
+
+extern const char* version;
+extern Keypad keypad;
+extern LiquidCrystal_I2C lcd;
+extern AccelStepper stepper;
+extern OneWire oneWire;
+extern DallasTemperature sensors;
+extern String devPgm;
+extern int run;
+extern const int beeperPin;
+extern byte thermometer[8];
+
+extern TaskHandle_t motorTaskHandle;
+extern TaskHandle_t tempTaskHandle;
+
+extern unsigned long processStartTime;
+extern unsigned long processTimeMillis;
+
+#endif
diff --git a/AutoFilmESP32/devSequence.cpp b/AutoFilmESP32/devSequence.cpp
new file mode 100644
index 0000000..89c337b
--- /dev/null
+++ b/AutoFilmESP32/devSequence.cpp
@@ -0,0 +1,103 @@
+#include "devSequence.h"
+
+struct devSequence devSequences[NUM_DEV_SEQUENCES] = {
+ {
+ .name = "C41",
+ .cycles = 7,
+ .processTime = { 180, 195, 45, 180, 60, 60, 30 }, //processTime
+ .processName = { "Prewarm", "Developer", "Bleach", "Fix", "Rinse 1", "Rinse 2", "Fin Rinse" }, //processName
+ .processCycle = {
+ { 1, 5.5, 5.5, 5.5, 3.5, 3.5, 1 }, //CW rotations processCycle
+ { 1, 5, 5, 5, 3, 3, 1 }
+ }, //CCW rotations processCycle
+ .processTemp = {
+ { 37.8, 37.8, 32, 32, 32, 32, 32 }, //min processTemp
+ { 38, 38, 38, 38, 38, 38, 38 }, //preferred processTemp
+ { 38.2, 38.2, 38.2, 38.2, 38.2, 38.2, 38.2 } //max processTemp
+ }
+ },
+ {
+ .name = "E6",
+ .cycles = 12,
+ .processTime = {180, 360, 120, 120, 360, 120, 360, 240, 120, 120, 120, 30},
+ .processName = {"Preheat", "FirstDev", "Wash 1", "Reversal", "ColorDev", "PreBleach", "Bleach", "Fixer", "Wash 2", "Wash 3", "Wash 4", "Fin Rinse"},
+ .processCycle = {
+ {1, 5.5, 3.5, 5, 5.5, 5.5, 5.5, 5.5, 3.5, 3.5, 3.5, 3.5},
+ {1, 5, 3, 5.5, 5, 5.5, 5.5, 5.5, 3, 3, 3, 3}
+ },
+ .processTemp = {
+ {37.5, 37.7, 33.0, 37.7, 37.0, 37, 37.5, 37.5, 33.0, 33.0, 33.0, 19.0},
+ {38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0, 20.0},
+ {38.5, 38.3, 38.0, 38.3, 39.0, 38, 38.5, 38.5, 38.5, 38.5, 38.5, 21.0}
+ }
+ },
+ {
+ .name = "ECN-2",
+ .cycles = 9,
+ .processTime = {180, 0, 210, 60, 180, 150, 120, 300, 120},
+ .processName = {"Prebath", "RemJet", "Developer", "Stop Bath", "Wash", "Bleach", "Fixer", "Wash 2", "Fin Rinse"},
+ .processCycle = {
+ {1, 0, 5.5, 3.5, 3.5, 5.5, 5.5, 3.5, 1},
+ {1, 0, 5, 3, 3, 5, 5, 3, 1}
+ },
+ .processTemp = {
+ {27.0, 0, 40.8, 27.0, 27.0, 27.0, 27.0, 27.0, 27.0},
+ {38.0, 0, 41.0, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0},
+ {38.0, 0, 41.2, 38.0, 38.0, 38.0, 38.0, 38.0, 38.0}
+ }
+ },
+ {
+ .name = "B&W",
+ .cycles = 7,
+ .processTime = {510, 30, 300, 60, 90, 120, 30},
+ .processName = {"Developer", "Stop", "Fix", "Rinse 1", "Rinse 2", "Rinse 3", "Fin Rinse"},
+ .processCycle = {
+ { 5.5, 3.5, 3.5, 3.5, 3.5, 3.5, 1},
+ { 5, 3, 3, 3, 3, 3, 1}
+ },
+ .processTemp = {
+ {19, 19, 19, 19, 19, 19, 19},
+ {20, 20, 20, 20, 20, 20, 20},
+ {21, 21, 21, 21, 21, 21, 21}
+ }
+ },
+ {
+ .name = "Custom",
+ .cycles = 4,
+ .processTime = {10, 10, 10, 10},
+ .processName = {"Developer", "Stop", "Fix", "Rinse"},
+ .processCycle = {
+ { 5.5, 3.5, 3.5, 3.5},
+ { 5, 3, 3, 3}
+ },
+ .processTemp = {
+ {19, 19, 19, 19},
+ {20, 20, 20, 20},
+ {21, 21, 21, 21}
+ }
+ },
+ {
+ .name = "B&WREV",
+ .cycles = 12,
+ .processTime = {720, 300, 300, 60, 120, 60, 120, 360, 60, 300, 60, 60},
+ .processName = {"FirstDev", "Wash 1", "Bleach", "Wash 2", "Clearing", "Wash 3", "Reversal", "SecondDev", "Wash 4", "Fix", "Wash 5", "Fin Rinse"},
+ .processCycle = {
+ {5.5, 3.5, 5.5, 3.5, 5.5, 3.5, 5.5, 5.5, 3.5, 5.5, 3.5, 3.5},
+ {5, 3, 5, 3, 5, 3, 5, 5, 3, 5, 3, 3}
+ },
+ .processTemp = {
+ {19.5, 15.5, 19.5, 15.5, 19.5, 15.5, 19.5, 19.5, 15.5, 19.5, 15.5, 15.5},
+ {20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0, 20.0},
+ {20.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5, 22.5}
+ }
+ }
+};
+
+struct devSequence* findSequenceByName(const char* name) {
+ for (int i = 0; i < NUM_DEV_SEQUENCES; i++) {
+ if (strcmp(devSequences[i].name, name) == 0) {
+ return &devSequences[i];
+ }
+ }
+ return NULL; // Return NULL if not found
+}
diff --git a/AutoFilmESP32/devSequence.h b/AutoFilmESP32/devSequence.h
new file mode 100644
index 0000000..21320d1
--- /dev/null
+++ b/AutoFilmESP32/devSequence.h
@@ -0,0 +1,19 @@
+#ifndef DEVSEQUENCE_H
+#define DEVSEQUENCE_H
+#define NUM_DEV_SEQUENCES 6
+#include
+
+struct devSequence {
+ char name[7];
+ int cycles;
+ unsigned long int processTime[20];
+ char processName[20][10];
+ float processCycle[2][20];
+ float processTemp[3][20];
+};
+
+extern struct devSequence devSequences[NUM_DEV_SEQUENCES];
+
+struct devSequence* findSequenceByName(const char* name);
+
+#endif
diff --git a/AutoFilmESP32/display.cpp b/AutoFilmESP32/display.cpp
new file mode 100644
index 0000000..828232a
--- /dev/null
+++ b/AutoFilmESP32/display.cpp
@@ -0,0 +1,56 @@
+#include "display.h"
+#include "menu.h"
+
+
+void startingMenu() {
+ lcd.clear();
+ lcd.setCursor(0, 0);
+ lcd.print("Select Programme:");
+ lcd.setCursor(0, 1);
+ lcd.print("1. C41");
+ lcd.setCursor(0, 2);
+ lcd.print("2. E6");
+ lcd.setCursor(0, 3);
+ lcd.print("3. B&W");
+ lcd.setCursor(10, 1);
+ lcd.print("4. ECN-2");
+ lcd.setCursor(10, 2);
+ lcd.print("5. Custom");
+ lcd.setCursor(10, 3);
+ lcd.print("6. B&W Rev");
+
+ while (devPgm == "") {
+ getMenuInput();
+ }
+ lcd.print(devPgm);
+
+ if (devPgm == "C41" || devPgm == "E6" || devPgm == "B&W" || devPgm == "ECN-2" || devPgm == "Custom" || devPgm == "B&WREV") {
+ startDev();
+ }
+}
+
+void processHeadings() {
+ lcd.clear();
+ lcd.setCursor(0, 0);
+ lcd.print("Step");
+ lcd.setCursor(10, 0);
+ lcd.print("Time");
+ lcd.setCursor(16, 0);
+ lcd.print("Temp");
+}
+
+
+
+char* secondsToMinutesSeconds(int seconds) {
+ char* result = (char*)malloc(6 * sizeof(char));
+ if (result == NULL) {
+ return NULL;
+ }
+
+ int minutes = seconds / 60;
+ int secs = seconds % 60;
+
+ snprintf(result, 6, "%02d:%02d", minutes, secs);
+
+ return result;
+}
diff --git a/AutoFilmESP32/display.h b/AutoFilmESP32/display.h
new file mode 100644
index 0000000..d4fbd3a
--- /dev/null
+++ b/AutoFilmESP32/display.h
@@ -0,0 +1,13 @@
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include
+#include "config.h"
+
+void updateTempDisplay(void* parameter);
+void startingMenu();
+void processHeadings();
+void readTemperature();
+char* secondsToMinutesSeconds(int seconds);
+
+#endif
diff --git a/AutoFilmESP32/menu.cpp b/AutoFilmESP32/menu.cpp
new file mode 100644
index 0000000..fbfab48
--- /dev/null
+++ b/AutoFilmESP32/menu.cpp
@@ -0,0 +1,181 @@
+#include "menu.h"
+
+void getMenuInput() {
+ char key = keypad.getKey();
+ if (key != NO_KEY) {
+ switch (key) {
+ case '1':
+ devPgm = "C41";
+ break;
+ case '2':
+ devPgm = "E6";
+ break;
+ case '3':
+ devPgm = "B&W";
+ break;
+ case '4':
+ devPgm = "ECN-2";
+ break;
+ case '5':
+ devPgm = "Custom";
+ break;
+ case '6':
+ devPgm = "B&WREV";
+ break;
+ }
+ }
+}
+
+
+char getScrollEntEscInput() {
+ while (true) {
+ char key = keypad.getKey();
+ if (key != NO_KEY) {
+ if (key == 'U' || key == 'D' || key == 'X' || key == 'E' || key == 'L' || key == 'R') {
+ return key;
+ }
+ }
+ if (millis() % 1000 == 0) {
+ readTemperature();
+ }
+ }
+}
+
+char getEntEscInput() {
+ while (true) {
+ char key = keypad.getKey();
+ if (key != NO_KEY) {
+ if (key == 'X' || key == 'E') {
+ return key;
+ }
+ }
+ if (millis() % 1000 == 0) {
+ readTemperature();
+ }
+ }
+}
+
+int startProcessing(struct devSequence* sequence, int sequenceStep) {
+ run = 1;
+ lcd.clear();
+ lcd.setCursor(0, 0);
+ lcd.print(sequence->processName[sequenceStep]);
+ for (int x = strlen(sequence->processName[sequenceStep]); x < 10; x++) {
+ lcd.print(" ");
+ }
+
+ lcd.setCursor(10, 0);
+ lcd.print(secondsToMinutesSeconds(sequence->processTime[sequenceStep]));
+ lcd.setCursor(16, 0);
+ lcd.print(" " + (String)(int)sequence->processTemp[1][sequenceStep] + "C");
+
+ lcd.setCursor(0, 1);
+ lcd.print("Ent:start Esc:quit");
+
+ char key = getEntEscInput();
+ if (key == 'X') {
+ devPgm = "";
+ run = 0;
+ return 0;
+ }
+ processTimeMillis = (unsigned long)sequence->processTime[sequenceStep] * 1000;
+ processStartTime = millis();
+
+ MotorTaskParams* params = new MotorTaskParams();
+ params->cwRotations = sequence->processCycle[0][sequenceStep];
+ params->ccwRotations = sequence->processCycle[1][sequenceStep];
+ params->processEndTime = processStartTime + processTimeMillis;
+
+ Serial.print("Starting Motor Task with CW Rotations: ");
+ Serial.print(params->cwRotations);
+ Serial.print(", CCW Rotations: ");
+ Serial.print(params->ccwRotations);
+ Serial.print(", Process End Time: ");
+ Serial.println(params->processEndTime);
+
+ xTaskCreatePinnedToCore(
+ runMotorTask,
+ "MotorTask",
+ 8192,
+ (void*)params,
+ 1,
+ &motorTaskHandle,
+ 0);
+
+ while (millis() < processStartTime + processTimeMillis) {
+ lcd.setCursor(0, 1);
+ lcd.print("Remaining: " + (String)secondsToMinutesSeconds((processStartTime + processTimeMillis - millis()) / 1000) + " ");
+ delay(410);
+ Serial.println("before temp read" + (String) millis() + "\n");
+ readTemperature();
+ Serial.println("after temp read" + (String) millis() + "\n");
+ }
+
+ if (motorTaskHandle != NULL) {
+ vTaskDelete(motorTaskHandle);
+ motorTaskHandle = NULL;
+ }
+ playAlarmTone();
+
+ delete params;
+ return 1;
+}
+
+void startDev() {
+ const char* searchName = devPgm.c_str();
+ struct devSequence* currentSequence = findSequenceByName(searchName);
+
+ for (int i = 0; i < currentSequence->cycles; i++) {
+ if (run == 1) {
+ run = startProcessing(currentSequence, i);
+ continue;
+ }
+
+ processHeadings();
+ lcd.setCursor(0, 1);
+ lcd.print(currentSequence->processName[i]);
+ for (int x = strlen(currentSequence->processName[i]); x < 10; x++) {
+ lcd.print(" ");
+ }
+
+ lcd.setCursor(10, 1);
+ lcd.print(secondsToMinutesSeconds(currentSequence->processTime[i]));
+ lcd.setCursor(16, 1);
+ lcd.print(" " + (String)(int)currentSequence->processTemp[1][i] + "C");
+
+ lcd.setCursor(0, 2);
+ lcd.print("Scroll / Esc / Ent");
+
+ char key = getScrollEntEscInput();
+ if (key == 'U') {
+ if (i > 0) {
+ i--;
+ }
+ i--;
+ } else if (key == 'D' && i < currentSequence->cycles - 1) {
+ continue;
+ } else if (key == 'D' && i == currentSequence->cycles - 1) {
+ i--;
+ continue;
+ } else if (key == 'X') {
+ devPgm = "";
+ run = 0;
+ return;
+ } else if (key == 'E') {
+ int run = 1;
+ startProcessing(currentSequence, i);
+ } else if (key == 'L') {
+ currentSequence->processTime[i] -= 5;
+ lcd.setCursor(10, 1);
+ lcd.print(secondsToMinutesSeconds(currentSequence->processTime[i]));
+ i--;
+ } else if (key == 'R') {
+ currentSequence->processTime[i] += 5;
+ lcd.setCursor(10, 1);
+ lcd.print(secondsToMinutesSeconds(currentSequence->processTime[i]));
+ i--;
+ }
+ }
+ devPgm = "";
+ run = 0;
+}
diff --git a/AutoFilmESP32/menu.h b/AutoFilmESP32/menu.h
new file mode 100644
index 0000000..b4cad5f
--- /dev/null
+++ b/AutoFilmESP32/menu.h
@@ -0,0 +1,16 @@
+#ifndef MENU_H
+#define MENU_H
+
+#include "config.h"
+#include "devSequence.h"
+#include "motor.h"
+#include "display.h"
+#include "sound.h"
+
+void getMenuInput();
+char getScrollEntEscInput();
+char getEntEscInput();
+int startProcessing(struct devSequence* sequence, int sequenceStep);
+void startDev();
+
+#endif
diff --git a/AutoFilmESP32/motor.cpp b/AutoFilmESP32/motor.cpp
new file mode 100644
index 0000000..411b535
--- /dev/null
+++ b/AutoFilmESP32/motor.cpp
@@ -0,0 +1,29 @@
+#include "motor.h"
+
+void runMotorTask(void* parameter) {
+ MotorTaskParams* params = (MotorTaskParams*)parameter;
+
+ // Enable the motor
+ digitalWrite(EN_PIN, LOW);
+ while (true) {
+ // Rotate clockwise
+ Serial.println("Rotating CW" + (String)params->cwRotations);
+ stepper.setCurrentPosition(0);
+ stepper.moveTo(STEPS_PER_REV * params->cwRotations);
+ while (stepper.distanceToGo() != 0) {
+ stepper.run();
+ }
+
+ // Rotate counter-clockwise
+ Serial.println("Rotating CCW" + (String)params->ccwRotations);
+ stepper.setCurrentPosition(0);
+ stepper.moveTo(-STEPS_PER_REV * params->ccwRotations);
+ while (stepper.distanceToGo() != 0) {
+ stepper.run();
+ }
+ }
+ // Disable the motor
+ digitalWrite(EN_PIN, HIGH);
+
+ vTaskDelete(NULL); // Delete the task when done
+}
diff --git a/AutoFilmESP32/motor.h b/AutoFilmESP32/motor.h
new file mode 100644
index 0000000..1372a29
--- /dev/null
+++ b/AutoFilmESP32/motor.h
@@ -0,0 +1,15 @@
+#ifndef MOTOR_H
+#define MOTOR_H
+
+#include
+#include "config.h"
+
+struct MotorTaskParams {
+ float cwRotations;
+ float ccwRotations;
+ unsigned long int processEndTime;
+};
+
+void runMotorTask(void* parameter);
+
+#endif
diff --git a/AutoFilmESP32/sound.cpp b/AutoFilmESP32/sound.cpp
new file mode 100644
index 0000000..4b5154f
--- /dev/null
+++ b/AutoFilmESP32/sound.cpp
@@ -0,0 +1,30 @@
+#include "sound.h"
+
+
+int melody[] = {
+ 262, 294, 330, 349, 392, 440, 494, 523, 587, 659, 698, 784, 880, 988, 1047
+};
+int noteDurations[] = {
+ 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250
+};
+
+void playTune() {
+ for (int thisNote = 0; thisNote < 15; thisNote++) {
+ int noteDuration = noteDurations[thisNote];
+ tone(beeperPin, melody[thisNote], noteDuration);
+
+ int pauseBetweenNotes = noteDuration * 1.30;
+ delay(pauseBetweenNotes);
+
+ noTone(beeperPin);
+ }
+}
+
+void playAlarmTone() {
+ for (int i = 1; i <= 10; i++) {
+ tone(beeperPin, 2000);
+ delay(500);
+ noTone(beeperPin);
+ delay(250);
+ }
+}
diff --git a/AutoFilmESP32/sound.h b/AutoFilmESP32/sound.h
new file mode 100644
index 0000000..67c48f0
--- /dev/null
+++ b/AutoFilmESP32/sound.h
@@ -0,0 +1,9 @@
+#ifndef SOUND_H
+#define SOUND_H
+
+#include "config.h"
+
+void playTune();
+void playAlarmTone();
+
+#endif
diff --git a/AutoFilmESP32/spec.d b/AutoFilmESP32/spec.d
new file mode 100644
index 0000000..fbd4303
--- /dev/null
+++ b/AutoFilmESP32/spec.d
@@ -0,0 +1,2 @@
+spec.o: \
+ C:/Users/gordon/Documents/sloeber-workspace/.metadata/.plugins/org.eclipse.cdt.managedbuilder.core/spec.cpp
diff --git a/AutoFilmESP32/temperature.cpp b/AutoFilmESP32/temperature.cpp
new file mode 100644
index 0000000..e30293a
--- /dev/null
+++ b/AutoFilmESP32/temperature.cpp
@@ -0,0 +1,29 @@
+#include "temperature.h"
+
+void readTemperature() {
+ sensors.requestTemperatures();
+ float temperatureC = sensors.getTempCByIndex(0);
+ lcd.setCursor(13, 3);
+ lcd.write(byte(0));
+ if (temperatureC == DEVICE_DISCONNECTED_C) {
+ lcd.print("--");
+ } else {
+ lcd.print(temperatureC, 1);
+ lcd.print("C");
+ }
+}
+
+void updateTempDisplay(void* parameter) {
+ sensors.requestTemperatures();
+ float temperatureC = sensors.getTempCByIndex(0);
+ lcd.setCursor(13, 3);
+ lcd.write(byte(0));
+ if (temperatureC == DEVICE_DISCONNECTED_C) {
+ lcd.print("--");
+ } else {
+ lcd.print(temperatureC, 1);
+ lcd.print("C");
+ }
+
+ vTaskDelete(NULL); // Delete the task when done
+}
diff --git a/AutoFilmESP32/temperature.h b/AutoFilmESP32/temperature.h
new file mode 100644
index 0000000..4bbec4b
--- /dev/null
+++ b/AutoFilmESP32/temperature.h
@@ -0,0 +1,10 @@
+#ifndef TEMPERATURE_H
+#define TEMPERATURE_H
+
+#include "config.h"
+
+void readTemperature();
+
+void updateTempDisplay();
+
+#endif
diff --git a/AutoFilmESP32/watchdog.h b/AutoFilmESP32/watchdog.h
new file mode 100644
index 0000000..e9c8a49
--- /dev/null
+++ b/AutoFilmESP32/watchdog.h
@@ -0,0 +1,17 @@
+#ifndef WATCHDOG_H
+#define WATCHDOG_H
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "esp_task_wdt.h"
+
+// Disable the watchdog timers
+void disableWatchdogTimers() {
+ esp_task_wdt_deinit();
+ TaskHandle_t idle_0 = xTaskGetIdleTaskHandleForCPU(0);
+ TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
+ esp_task_wdt_delete(idle_0);
+ esp_task_wdt_delete(idle_1);
+}
+
+#endif