Migrated project to vscode/platformio

This commit is contained in:
Gordon Bolton 2024-06-25 21:04:22 +01:00
commit 78f90b4f6a
29 changed files with 1021 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch

10
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}

39
include/README Normal file
View File

@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

46
lib/README Normal file
View File

@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

20
platformio.ini Normal file
View File

@ -0,0 +1,20 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
lib_deps =
waspinator/AccelStepper@^1.64
marcoschwartz/LiquidCrystal_I2C@^1.1.4
paulstoffregen/OneWire@^2.3.8
milesburton/DallasTemperature@^3.11.0
chris--a/Keypad@^3.1.1

112
src/.cproject Normal file
View File

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="io.sloeber.core.sketch.0">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="io.sloeber.core.sketch.0" moduleId="org.eclipse.cdt.core.settings" name="Release">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.MakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" cleanCommand="rm -f" description="" id="io.sloeber.core.sketch.0" name="Release" parent="io.sloeber.core.configuration.release">
<folderInfo id="io.sloeber.core.sketch.0." name="/" resourcePath="">
<toolChain id="io.sloeber.core.toolChain.release.266003693" name="Arduino Toolchain (Sloeber edition)" superClass="io.sloeber.core.toolChain.release">
<targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.ELF" id="io.sloeber.targetplatform.1007724960" name="Arduino Target" osList="all" superClass="io.sloeber.targetplatform"/>
<builder buildPath="${workspace_loc:/AutoFilmESP32}/Release" id="io.sloeber.sketch.builder.867458112" keepEnvironmentInBuildfile="false" name="Arduino sketch builder" parallelBuildOn="false" superClass="io.sloeber.sketch.builder"/>
<tool id="io.sloeber.tool.sketch.compiler.cpp.2064152583" name="Arduino C++ Compiler" superClass="io.sloeber.tool.sketch.compiler.cpp">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.cpp.sketch.option.incpath.476594594" name="Include Paths (-I)" superClass="io.sloeber.compiler.cpp.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/LiquidCrystal_I2C}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Wire/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Keypad/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/AccelStepper/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/DallasTemperature}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/OneWire}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.cpp.sketch.input.729879768" name="CPP source files" superClass="io.sloeber.compiler.cpp.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.compiler.c.2097396008" name="Arduino C Compiler" superClass="io.sloeber.tool.compiler.c">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.c.sketch.option.incpath.846211118" name="Include Paths (-I)" superClass="io.sloeber.compiler.c.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/LiquidCrystal_I2C}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Wire/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Keypad/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/AccelStepper/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/DallasTemperature}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/OneWire}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.c.sketch.input.1572266114" name="C Source Files" superClass="io.sloeber.compiler.c.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.sketch.compiler.s.134401563" name="Arduino Assembler" superClass="io.sloeber.tool.sketch.compiler.s">
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="io.sloeber.compiler.asm.sketch.option.incpath.1216205204" name="Include Paths (-I)" superClass="io.sloeber.compiler.asm.sketch.option.incpath" valueType="includePath">
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/core}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/core/variant}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/LiquidCrystal_I2C}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Wire/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/Keypad/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/AccelStepper/src}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/DallasTemperature}&quot;"/>
<listOptionValue builtIn="false" value="&quot;${workspace_loc:/AutoFilmESP32/libraries/OneWire}&quot;"/>
</option>
<inputType id="io.sloeber.compiler.S.sketch.input.1763914642" name="Assembly source files" superClass="io.sloeber.compiler.S.sketch.input"/>
</tool>
<tool id="io.sloeber.tool.ar.681784854" name="Arduino archiver" superClass="io.sloeber.tool.ar"/>
<tool id="io.sloeber.tool.combine.1711962012" name="Arduino combiner" superClass="io.sloeber.tool.combine"/>
<tool id="io.sloeber.tool.objcopy.eep.1716717030" name="Arduino tool objcopy command" superClass="io.sloeber.tool.objcopy.eep"/>
<tool id="io.sloeber.tool.size.810947740" name="Arduino tool Print Size" superClass="io.sloeber.tool.size"/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/**/._*" resourcePath="libraries/**/._*">
<toolChain id="io.sloeber.core.toolChain5.969422626" superClass="io.sloeber.core.toolChain5">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/**/._*.375054405" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/test*/**" resourcePath="libraries/?*/**/test*/**">
<toolChain id="io.sloeber.core.toolChain3.833991693" superClass="io.sloeber.core.toolChain3">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/test*/**.1204635795" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/?xtras/**" resourcePath="libraries/?*/**/?xtras/**">
<toolChain id="io.sloeber.core.toolChain2.597375474" superClass="io.sloeber.core.toolChain2">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/?xtras/**.1727460943" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/?xamples/**" resourcePath="libraries/?*/**/?xamples/**">
<toolChain id="io.sloeber.core.toolChain1.904128852" superClass="io.sloeber.core.toolChain1">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/?xamples/**.1109229805" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/**/third-party/**" resourcePath="libraries/?*/**/third-party/**">
<toolChain id="io.sloeber.core.toolChain4.15489890" superClass="io.sloeber.core.toolChain4">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/**/third-party/**.992086312" name=""/>
</toolChain>
</folderInfo>
<folderInfo id="io.sloeber.core.sketch.0.libraries/?*/utility/*/*" resourcePath="libraries/?*/utility/*/*">
<toolChain id="io.sloeber.core.toolChain6.24198140" superClass="io.sloeber.core.toolChain6">
<targetPlatform id="io.sloeber.core.sketch.0.libraries/?*/utility/*/*.1399173716" name=""/>
</toolChain>
</folderInfo>
<sourceEntries>
<entry excluding="libraries/OneWire/util|libraries/OneWire/docs|libraries/?*/**/?xamples/**|libraries/?*/**/?xtras/**|libraries/?*/**/test*/**|libraries/?*/**/third-party/**|libraries/**/._*|libraries/?*/utility/*/*" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
</configuration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="AutoFilmESP32.io.sloeber.core.sketch.1033643333" name="Arduino sketch" projectType="io.sloeber.core.sketch"/>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
</storageModule>
<storageModule moduleId="refreshScope"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
</cproject>

2
src/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/Release/
/sloeber.ino.cpp

75
src/.project Normal file
View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>AutoFilmESP32</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>io.sloeber.core.inoToCpp</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>io.sloeber.arduinonature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
<linkedResources>
<link>
<name>core/core</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/cores/esp32</locationURI>
</link>
<link>
<name>core/variant</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/variants/esp32</locationURI>
</link>
<link>
<name>libraries/AccelStepper</name>
<type>2</type>
<location>C:/Users/gordon/Documents/Arduino/libraries/AccelStepper</location>
</link>
<link>
<name>libraries/DallasTemperature</name>
<type>2</type>
<location>C:/Users/gordon/Documents/Arduino/libraries/DallasTemperature</location>
</link>
<link>
<name>libraries/Keypad</name>
<type>2</type>
<location>C:/Users/gordon/Documents/Arduino/libraries/Keypad</location>
</link>
<link>
<name>libraries/LiquidCrystal_I2C</name>
<type>2</type>
<location>C:/Users/gordon/Documents/Arduino/libraries/LiquidCrystal_I2C</location>
</link>
<link>
<name>libraries/OneWire</name>
<type>2</type>
<location>C:/Users/gordon/Documents/Arduino/libraries/OneWire</location>
</link>
<link>
<name>libraries/Wire</name>
<type>2</type>
<locationURI>ECLIPSE_HOME/arduinoPlugin/packages/esp32/hardware/esp32/3.0.1/libraries/Wire</locationURI>
</link>
</linkedResources>
</projectDescription>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project>
<configuration id="io.sloeber.core.sketch.0" name="Release">
<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider class="io.sloeber.core.toolchain.ArduinoLanguageProvider" console="false" env-hash="-1318735347831635932" id="io.sloeber.languageSettingsProvider" keep-relative-paths="false" name="Arduino Compiler Settings" parameter="${COMMAND} -E -P -v -dD -D__IN_ECLIPSE__ &quot;${INPUTS}&quot;" prefer-non-shared="true">
<language-scope id="org.eclipse.cdt.core.gcc"/>
<language-scope id="org.eclipse.cdt.core.g++"/>
</provider>
</extension>
</configuration>
</project>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

29
src/.sproject Normal file
View File

@ -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

46
src/AutoFilmESP32.ino Normal file
View File

@ -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();
}

43
src/config.cpp Normal file
View File

@ -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
};

41
src/config.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <Arduino.h>
#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// 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

103
src/devSequence.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "devSequence.h"
struct devSequence devSequences[NUM_DEV_SEQUENCES] = {
{
"C41",
7,
{ 180, 195, 45, 180, 60, 60, 30 }, //processTime
{ "Prewarm", "Developer", "Bleach", "Fix", "Rinse 1", "Rinse 2", "Fin Rinse" }, //processName
{
{ 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
{
{ 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
}
},
{
"E6",
12,
{180, 360, 120, 120, 360, 120, 360, 240, 120, 120, 120, 30},
{"Preheat", "FirstDev", "Wash 1", "Reversal", "ColorDev", "PreBleach", "Bleach", "Fixer", "Wash 2", "Wash 3", "Wash 4", "Fin Rinse"},
{
{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}
},
{
{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}
}
},
{
"ECN-2",
9,
{180, 0, 210, 60, 180, 150, 120, 300, 120},
{"Prebath", "RemJet", "Developer", "Stop Bath", "Wash", "Bleach", "Fixer", "Wash 2", "Fin Rinse"},
{
{1, 0, 5.5, 3.5, 3.5, 5.5, 5.5, 3.5, 1},
{1, 0, 5, 3, 3, 5, 5, 3, 1}
},
{
{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}
}
},
{
"B&W",
7,
{510, 30, 300, 60, 90, 120, 30},
{"Developer", "Stop", "Fix", "Rinse 1", "Rinse 2", "Rinse 3", "Fin Rinse"},
{
{ 5.5, 3.5, 3.5, 3.5, 3.5, 3.5, 1},
{ 5, 3, 3, 3, 3, 3, 1}
},
{
{19, 19, 19, 19, 19, 19, 19},
{20, 20, 20, 20, 20, 20, 20},
{21, 21, 21, 21, 21, 21, 21}
}
},
{
"Custom",
4,
{10, 10, 10, 10},
{"Developer", "Stop", "Fix", "Rinse"},
{
{ 5.5, 3.5, 3.5, 3.5},
{ 5, 3, 3, 3}
},
{
{19, 19, 19, 19},
{20, 20, 20, 20},
{21, 21, 21, 21}
}
},
{
"B&WREV",
12,
{720, 300, 300, 60, 120, 60, 120, 360, 60, 300, 60, 60},
{"FirstDev", "Wash 1", "Bleach", "Wash 2", "Clearing", "Wash 3", "Reversal", "SecondDev", "Wash 4", "Fix", "Wash 5", "Fin Rinse"},
{
{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}
},
{
{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* processName) {
for (int i = 0; i < NUM_DEV_SEQUENCES; i++) {
if (strcmp(devSequences[i].processName, processName) == 0) {
return &devSequences[i];
}
}
return NULL; // Return NULL if not found
}

19
src/devSequence.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef DEVSEQUENCE_H
#define DEVSEQUENCE_H
#define NUM_DEV_SEQUENCES 6
#include <Arduino.h>
struct devSequence {
char processName[7];
int cycles;
unsigned long int processTime[20];
char processCycleName[20][10];
float processCycle[2][20];
float processTemp[3][20];
};
extern struct devSequence devSequences[NUM_DEV_SEQUENCES];
struct devSequence* findSequenceByName(const char* processName);
#endif

56
src/display.cpp Normal file
View File

@ -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;
}

13
src/display.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include <LiquidCrystal_I2C.h>
#include "config.h"
void updateTempDisplay(void* parameter);
void startingMenu();
void processHeadings();
void readTemperature();
char* secondsToMinutesSeconds(int seconds);
#endif

181
src/menu.cpp Normal file
View File

@ -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->processCycleName[sequenceStep]);
for (int x = strlen(sequence->processCycleName[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->processCycleName[i]);
for (int x = strlen(currentSequence->processCycleName[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;
}

16
src/menu.h Normal file
View File

@ -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

29
src/motor.cpp Normal file
View File

@ -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
}

15
src/motor.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef MOTOR_H
#define MOTOR_H
#include <AccelStepper.h>
#include "config.h"
struct MotorTaskParams {
float cwRotations;
float ccwRotations;
unsigned long int processEndTime;
};
void runMotorTask(void* parameter);
#endif

30
src/sound.cpp Normal file
View File

@ -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);
}
}

9
src/sound.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef SOUND_H
#define SOUND_H
#include "config.h"
void playTune();
void playAlarmTone();
#endif

2
src/spec.d Normal file
View File

@ -0,0 +1,2 @@
spec.o: \
C:/Users/gordon/Documents/sloeber-workspace/.metadata/.plugins/org.eclipse.cdt.managedbuilder.core/spec.cpp

29
src/temperature.cpp Normal file
View File

@ -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
}

10
src/temperature.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef TEMPERATURE_H
#define TEMPERATURE_H
#include "config.h"
void readTemperature();
void updateTempDisplay();
#endif

17
src/watchdog.h Normal file
View File

@ -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

11
test/README Normal file
View File

@ -0,0 +1,11 @@
This directory is intended for PlatformIO Test Runner and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html