Grundgerüst

This commit is contained in:
Jannis 2026-09-21 19:48:17 +02:00
parent 75714ebf35
commit 38e76e1e6f

343
main.ino
View file

@ -1,22 +1,95 @@
#include <Arduino.h> #include <Arduino.h>
#include <FastAccelStepper.h> #include <FastAccelStepper.h>
#include <WiFi.h>
#include <time.h>
const char* ssid = "DEIN_WLAN_NAME";
const char* password = "DEIN_PASSWORT";
// NTP-Server & Zeitzone für Deutschland
const char* ntpServer = "pool.ntp.org";
const char* tzInfo = "CET-1CEST,M3.5.0,M10.5.0/3";
FastAccelStepperEngine engine = FastAccelStepperEngine(); FastAccelStepperEngine engine = FastAccelStepperEngine();
FastAccelStepper *stepper = NULL; FastAccelStepper *stepper = NULL;
// Pins
#define dirPinStepper D5 #define dirPinStepper D5
#define enablePinStepper D6 #define enablePinStepper D6
#define stepPinStepper D9 #define stepPinStepper D9
#define speedUp D8 #define buttonPlus D8
#define speedDown D7 #define buttonMinus D7
#define buttonStop D10
const int32_t ACCEL_RATE = 2000; #define senTemp
// ################ Variabeln ################
const uint32_t MAX_SPEED_HZ = 106000; const uint32_t MAX_SPEED_HZ = 106000;
bool clickPlus = 0;
bool clickMinus = 0;
bool clickStop = 0;
bool holdPlus = 0;
bool holdMinus = 0;
bool holdStop = 0;
int32_t lastControl = 0; int32_t lastControl = 0;
uint32_t lastPlotTime = 0; uint32_t lastPlotTime = 0;
uint32_t lastDispTime = 0;
bool stop = false;
bool bSettings = false;
uint32_t curTemp = 0;
struct tm timeinfo;
struct settings{
int settingIdx = 0;
int startHour = 0;
int startMin = 0;
int endHour = 0;
int endMin = 0;
bool timerEnabled = false;
bool editMaxTemp = false;
int maxTemp = 50; //in °C
bool editAcc = false;
int32_t accelRate = 2000;
}
enum TimeEditStep {
EDIT_NONE = 0, // Normales Menü (Navigation)
EDIT_START_HOUR, // 1. Start-Stunde einstellen (0-23)
EDIT_START_MIN, // 2. Start-Minute einstellen (0-59)
EDIT_END_HOUR, // 3. End-Stunde einstellen (0-23)
EDIT_END_MIN // 4. End-Minute einstellen (0-59)
};
TimeEditStep timeEditStep = EDIT_NONE;
// Überladung des Präfix-Operators (++timeEditStep)
TimeEditStep& operator++(TimeEditStep& step) {
step = (step == EDIT_END_MIN) ? EDIT_NONE : static_cast<TimeEditStep>(step + 1);
return step;
}
void initWiFiAndTime() {
WiFi.begin(ssid, password);
// Zeitzone und NTP-Server setzen
configTzTime(tzInfo, ntpServer);
// Warten auf Verbindung (optional mit Timeout)
int retries = 0;
while (WiFi.status() != WL_CONNECTED && retries < 20) {
delay(500);
retries++;
}
}
//#######################################################
//####################### Setup #########################
//#######################################################
void setup() { void setup() {
Serial.begin(115200); Serial.begin(115200);
delay(1000); // Zeit für USB-CDC-Verbindung geben delay(1000); // Zeit für USB-CDC-Verbindung geben
@ -31,42 +104,197 @@ void setup() {
stepper->setSpeedInHz(MAX_SPEED_HZ); stepper->setSpeedInHz(MAX_SPEED_HZ);
} }
pinMode(speedUp, INPUT_PULLUP); // Pin Config
pinMode(speedDown, INPUT_PULLUP); pinMode(buttonPlus, INPUT_PULLUP);
pinMode(buttonMinus, INPUT_PULLUP);
pinMode(buttonStop, INPUT_PULLUP);
initWiFiAndTime()
// Start Animation
} }
void loop() { bool getCurrentTime(int &hour, int &minute, int &second) {
if (!stepper) { if (!getLocalTime(&timeinfo, 50)) { // 50ms Timeout
Serial.println("[HALT] Kein Stepper-Objekt aktiv."); return false; // Noch keine NTP-Zeit synchronisiert
delay(1000); }
return; hour = timeinfo.tm_hour;
minute = timeinfo.tm_min;
second = timeinfo.tm_sec;
return true;
}
// Rückgabe von Flanken (Klick) und Pegel (Halten)
void getInputs(bool &clickPlus, bool &clickMinus, bool &clickStop,
bool &holdPlus, bool &holdMinus, bool &holdStop) {
// Physische Pegel einlesen (Active-Low)
bool curPlus = (digitalRead(buttonPlus) == LOW);
bool curMinus = (digitalRead(buttonMinus) == LOW);
bool curStop = (digitalRead(buttonStop) == LOW);
// Speicher für vorherigen Durchlauf
static bool lastPlus = false;
static bool lastMinus = false;
static bool lastStop = false;
// Nur bei Veränderung true (Sperre)
clickPlus = (curPlus && !lastPlus);
clickMinus = (curMinus && !lastMinus);
clickStop = (curStop && !lastStop);
// Dauerzustand (für Stepper-Handbetrieb)
holdPlus = curPlus;
holdMinus = curMinus;
holdStop = curStop;
// Zustand für nächsten Durchlauf merken
lastPlus = curPlus;
lastMinus = curMinus;
lastStop = curStop;
}
// Liefert die Aktuelle Temperatur in °C
int getTempInC(uint8_t senTemp){
int milliVolt = analogReadMilliVolts(senTemp);
return ((milliVolt - 500)/10)
}
// Die Funktion behandelt das gesammte Einstellungs menu
void setting(){
//######### Timer Edit #########
if (timeEditStep != EDIT_NONE) {
//PLUS GEDRÜCKT: Wert erhöhen
if (clickPlus || holdPlus) {
switch (timeEditStep) {
case EDIT_START_HOUR:
settings.startHour = (settings.startHour + 1) % 24;
break;
case EDIT_START_MIN:
settings.startMin = (settings.startMin + 5) % 60;
break;
case EDIT_END_HOUR:
settings.endHour = (settings.endHour + 1) % 24;
break;
case EDIT_END_MIN:
settings.endMin = (settings.endMin + 5) % 60;
break;
default: break;
}
} }
// Bei INPUT_PULLUP: gedrückt = LOW (true) // MINUS GEDRÜCKT: Wert verringern
bool btnUpPressed = (digitalRead(speedUp) == LOW); if (clickMinus) {
bool btnDownPressed = (digitalRead(speedDown) == LOW); switch (timeEditStep) {
case EDIT_START_HOUR:
int32_t control = 0; settings.startHour = (settings.startHour == 0) ? 23 : settings.startHour - 1;
break;
if (btnUpPressed && btnDownPressed) { case EDIT_START_MIN:
stepper->stopMove(); settings.startMin = (settings.startMin == 0) ? 59 : settings.startMin -5;
control = 0; break;
case EDIT_END_HOUR:
settings.endHour = (settings.endHour == 0) ? 23 : settings.endHour - 1;
break;
case EDIT_END_MIN:
settings.endMin = (settings.endMin == 0) ? 59 : settings.endMin - 5;
break;
default: break;
} }
else if (btnUpPressed) {
control = ACCEL_RATE;
}
else if (btnDownPressed) {
control = -ACCEL_RATE;
}
else {
control = 0;
} }
if (control != lastControl) { // STOP GEDRÜCKT: Zum nächsten Wert springen
stepper->moveByAcceleration(control, true); if (clickStop) {
lastControl = control; ++timeEditStep;
} }
return; // Wichtig: Rest der Funktion überspringen, solange editiert wird!
}
//######### Max Temp Edit #########
if(settings.editMaxTemp){
if(clickPlus){
settings.maxTemp = (settings.maxTemp + 5) % 140;
}
if(clickPlus){
settings.maxTemp = (settings.maxTemp == 0) ? -20 : settings.maxTemp - 5;
}
if(clickStop){
settings.editMaxTemp = false;
}
return; // Wichtig: Rest der Funktion überspringen, solange editiert wird!
}
//######### Beschleunigung Edit #########
if(settings.editAcc){
if(clickPlus){
settings.accelRate = (settings.accelRate + 1000) % 20000;
}
if(clickPlus){
settings.accelRate = (settings.accelRate == 0) ? 0 : settings.accelRate - 1000;
}
if(clickStop){
settings.editAcc = false;
}
return; // Wichtig: Rest der Funktion überspringen, solange editiert wird!
}
//######### Menü #########
// Menü bewegen
if(clickPlus){
if(settings.settingIdx <= 2){
settings.settingIdx++;
}
}
if(clickMinus){
if(settings.settingIdx >=1){
settings.settingIdx--;
}
}
// Stop zum bestätigen
if (clickStop) {
if (settings.settingIdx == 0) {
// Zeitschaltuhr-Einstellung starten
timeEditStep = EDIT_START_HOUR;
}
else if (settings.settingIdx == 1) {
// Zeitschaltuhr ON/OFF
settings.timerEnabled = !settings.timerEnabled;
}else if (settings.settingIdx == 2) {
// Temperatur Grenze einstellen
settings.editMaxTemp = true;
}else if (settings.settingIdx == 3) {
// Beschleunigung
settings.editAcc = true;
}else if (settings.settingIdx == 4) {
// Menü verlassen
bSettings = false;
}
}
}
void updateDisplay(){
if (millis() - lastDispTime >= 50) {
lastDispTime = millis();
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
// einstellungs fenster
if(bSettings){
// Mein Menu
// Uhrzeit
// Cursor mit settingIdx
//EDIT_START_HOUR
//EDIT_START_MIN
//EDIT_END_HOUR
//EDIT_END_MIN
}
}
void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickMinus){
// Plotter-Ausgabe alle 50 ms (überflutet den Bus nicht) // Plotter-Ausgabe alle 50 ms (überflutet den Bus nicht)
if (millis() - lastPlotTime >= 50) { if (millis() - lastPlotTime >= 50) {
lastPlotTime = millis(); lastPlotTime = millis();
@ -74,14 +302,61 @@ void loop() {
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
// Format kompatibel für den Arduino Serial Plotter // Format kompatibel für den Arduino Serial Plotter
Serial.print("Current_Speed_Hz:"); Serial.print("Current_Speed_U/Min:");
Serial.print((60*currentSpeed)/3200); Serial.print((60*currentSpeed)/3200);
Serial.print(" Accel_Control:"); Serial.print(" Accel_Control:");
Serial.print(control); Serial.print(speed);
Serial.print(" Btn_Up:"); Serial.print(" Btn_Up:");
Serial.print(btnUpPressed ? 5000 : 0); Serial.print(clickPlus ? 5000 : 0);
Serial.print(" Btn_Down:"); Serial.print(" Btn_Down:");
Serial.print(btnDownPressed ? -5000 : 0); Serial.print(clickMinus ? -5000 : 0);
Serial.println(); Serial.println();
} }
} }
//#############################################################
//#################### MAIN ###################################
//#############################################################
void loop() {
int32_t speed = 0;
if (!stepper) {
Serial.println("[HALT] Kein Stepper-Objekt aktiv.");
delay(1000);
return;
}
// Inputs
getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop);
curTemp = getTempInC(senTemp);
// Main Control
if(bSettings){
settings()
}else if(clickStop || stop){
stepper->stopMove();
speed = 0;
if(clickPlus){
bSettings = true;
settings();
}
}else if(holdPlus){
speed = accelRate;
}else if(holdMinus){
speed = -accelRate;
}else{
speed = 0;
}
// Action
if (speed != lastSpeed) {
stepper->moveByAcceleration(speed, true);
lastSpeed = speed;
}
updateDisplay()
// Status ausgabe auf Terminal
printStatus(stepper, speed, clickPlus, clickMinus);
}
}