V0.1
This commit is contained in:
parent
c1227e20c6
commit
7007552474
5 changed files with 238 additions and 380 deletions
|
|
@ -1 +0,0 @@
|
||||||
{"hostname":"JANNIS-PC","username":"janni"}
|
|
||||||
148
display_ui.cpp
148
display_ui.cpp
|
|
@ -18,6 +18,10 @@ static const unsigned char image_paint_27_bits[] U8X8_PROGMEM = {
|
||||||
0x00,0x00,0x01,0x00
|
0x00,0x00,0x01,0x00
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned char image_checked_bits[] U8X8_PROGMEM = {0x00,0x00,0x40,0x21,0x13,0x0e,0x04,0x00};
|
||||||
|
static const unsigned char image_crossed_bits[] U8X8_PROGMEM = {0x00,0x21,0x12,0x0c,0x1e,0x33,0x00,0x00};
|
||||||
|
|
||||||
|
|
||||||
// Animations-Zähler
|
// Animations-Zähler
|
||||||
//static uint8_t fire_flames_frame = 0;
|
//static uint8_t fire_flames_frame = 0;
|
||||||
//static uint8_t Clock_frame = 0;
|
//static uint8_t Clock_frame = 0;
|
||||||
|
|
@ -58,10 +62,10 @@ static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid,
|
||||||
u8g2.setDrawColor(1); // 1 = Weiß (an)
|
u8g2.setDrawColor(1); // 1 = Weiß (an)
|
||||||
|
|
||||||
// 1. Feste Beschriftungen
|
// 1. Feste Beschriftungen
|
||||||
u8g2.setFont(u8g2_font_5x7_tr);
|
u8g2.setFont(u8g2_font_6x10_tr);
|
||||||
u8g2.drawStr(7, 8, "Geschw");
|
u8g2.drawStr(5, 9, "Geschw");
|
||||||
u8g2.drawStr(7, 19, "Zeituhr");
|
u8g2.drawStr(5, 20, "Zeituhr");
|
||||||
u8g2.drawStr(7, 30, "Temp");
|
u8g2.drawStr(5, 31, "Temp");
|
||||||
|
|
||||||
// 2. Dynamischer Wert: Geschwindigkeit
|
// 2. Dynamischer Wert: Geschwindigkeit
|
||||||
char speedBuf[10];
|
char speedBuf[10];
|
||||||
|
|
@ -79,7 +83,6 @@ static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid,
|
||||||
u8g2.drawStr(89, 19, endBuf);
|
u8g2.drawStr(89, 19, endBuf);
|
||||||
|
|
||||||
// 4. Dynamische Temperatur (Ist & Soll/Max)
|
// 4. Dynamische Temperatur (Ist & Soll/Max)
|
||||||
// Hinweis: Hier kannst du später deine reale Sensortemperatur übergeben
|
|
||||||
char curTempBuf[10];
|
char curTempBuf[10];
|
||||||
snprintf(curTempBuf, sizeof(curTempBuf), "%d", curTemp);
|
snprintf(curTempBuf, sizeof(curTempBuf), "%d", curTemp);
|
||||||
u8g2.drawStr(52, 30, curTempBuf);
|
u8g2.drawStr(52, 30, curTempBuf);
|
||||||
|
|
@ -100,7 +103,7 @@ static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid,
|
||||||
u8g2.drawStr(4, 60, timeBuf);
|
u8g2.drawStr(4, 60, timeBuf);
|
||||||
|
|
||||||
// 6. Lopaka Deko-Bitmap
|
// 6. Lopaka Deko-Bitmap
|
||||||
u8g2.drawXBMP(28, 4, 16, 26, image_paint_27_bits);
|
u8g2.drawXBMP(32, 4, 16, 26, image_paint_27_bits);
|
||||||
|
|
||||||
// 7. Lopaka Animationen abspielen
|
// 7. Lopaka Animationen abspielen
|
||||||
//drawAnimation_fire_flames();
|
//drawAnimation_fire_flames();
|
||||||
|
|
@ -111,7 +114,52 @@ static void drawHomeScreen(int currentSpeed, int curH, int curM, bool timeValid,
|
||||||
// Zeitschaltuhr
|
// Zeitschaltuhr
|
||||||
// #############################################################
|
// #############################################################
|
||||||
static void drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const SystemSettings& settings){
|
static void drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const SystemSettings& settings){
|
||||||
|
u8g2.setFontMode(1);
|
||||||
|
u8g2.setBitmapMode(1);
|
||||||
|
// Von
|
||||||
|
u8g2.setFont(u8g2_font_6x12_tr);
|
||||||
|
u8g2.drawStr(31, 26, "Von:");
|
||||||
|
|
||||||
|
// Start Time
|
||||||
|
u8g2.setFont(u8g2_font_6x10_tr);
|
||||||
|
char startBuf[10];
|
||||||
|
snprintf(startBuf, sizeof(startBuf), "%02d:%02d", settings.startHour, settings.startMin);
|
||||||
|
u8g2.drawStr(66, 26, startBuf);
|
||||||
|
|
||||||
|
// string 23
|
||||||
|
u8g2.setFont(u8g2_font_6x12_tr);
|
||||||
|
u8g2.drawStr(31, 44, "Bis:");
|
||||||
|
|
||||||
|
// End Time
|
||||||
|
u8g2.setFont(u8g2_font_6x10_tr);
|
||||||
|
char endBuf[10];
|
||||||
|
snprintf(endBuf, sizeof(endBuf), "%02d:%02d", settings.endHour, settings.endMin);
|
||||||
|
u8g2.drawStr(66, 44, endBuf);
|
||||||
|
|
||||||
|
// Auswahlbox Zeichnen
|
||||||
|
switch (timeEditStep) {
|
||||||
|
case EDIT_START_HOUR:
|
||||||
|
u8g2.setDrawColor(2); // Invertierungs mode
|
||||||
|
u8g2.drawBox(66, 17, 11, 11);
|
||||||
|
u8g2.setDrawColor(1); // Wieder zurück auf normal
|
||||||
|
break;
|
||||||
|
case EDIT_START_MIN:
|
||||||
|
u8g2.setDrawColor(2); // Invertierungs mode
|
||||||
|
u8g2.drawBox((66+18), 17, 11, 11);
|
||||||
|
u8g2.setDrawColor(1); // Wieder zurück auf normal
|
||||||
|
break;
|
||||||
|
case EDIT_END_HOUR:
|
||||||
|
u8g2.setDrawColor(2); // Invertierungs mode
|
||||||
|
u8g2.drawBox(66, 35, 11, 11);
|
||||||
|
u8g2.setDrawColor(1); // Wieder zurück auf normal
|
||||||
|
break;
|
||||||
|
case EDIT_END_MIN:
|
||||||
|
u8g2.setDrawColor(2); // Invertierungs mode
|
||||||
|
u8g2.drawBox((66+18), 35, 11, 11);
|
||||||
|
u8g2.setDrawColor(1); // Wieder zurück auf normal
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #############################################################
|
// #############################################################
|
||||||
|
|
@ -119,8 +167,96 @@ static void drawTimerScreen(TimeEditStep timeEditStep, uint8_t settingIdx, const
|
||||||
// #############################################################
|
// #############################################################
|
||||||
static void drawSettingsScreen(uint8_t settingIdx, TimeEditStep timeEditStep, const SystemSettings& s) {
|
static void drawSettingsScreen(uint8_t settingIdx, TimeEditStep timeEditStep, const SystemSettings& s) {
|
||||||
|
|
||||||
|
const uint8_t* textFont = u8g2_font_helvB08_tr;
|
||||||
|
const uint8_t* valFont = u8g2_font_helvB08_tr;
|
||||||
|
|
||||||
if(timeEditStep != EDIT_NONE){
|
if(timeEditStep != EDIT_NONE){
|
||||||
drawTimerScreen(timeEditStep, settingIdx, s);
|
drawTimerScreen(timeEditStep, settingIdx, s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8g2.setFontMode(1);
|
||||||
|
u8g2.setBitmapMode(1);
|
||||||
|
u8g2.setDrawColor(1);
|
||||||
|
|
||||||
|
//######################
|
||||||
|
// Zeitschaltuhr Einstellungen
|
||||||
|
//######################
|
||||||
|
u8g2.setFont(textFont);
|
||||||
|
u8g2.drawStr(23, 10, "Zeituhr Einstellung");
|
||||||
|
|
||||||
|
//######################
|
||||||
|
// Zeitschaltuhr Status
|
||||||
|
//######################
|
||||||
|
u8g2.setFont(textFont);
|
||||||
|
u8g2.drawStr(28, 22, "Zeituhr:");
|
||||||
|
|
||||||
|
// Wenn Zeitschaltuhr Aktiviert
|
||||||
|
if(s.timerEnabled){
|
||||||
|
// Draw Check
|
||||||
|
u8g2.drawXBMP(78, 14, 7, 8, image_checked_bits);
|
||||||
|
}else{
|
||||||
|
// Draw X
|
||||||
|
u8g2.drawXBMP(78, 17, 6, 8, image_crossed_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################
|
||||||
|
// Max Temp
|
||||||
|
//######################
|
||||||
|
u8g2.setFont(textFont);
|
||||||
|
u8g2.drawStr(23, 34, "Max Temp:");
|
||||||
|
char maxTempBuf[10];
|
||||||
|
snprintf(maxTempBuf, sizeof(maxTempBuf), "%d", s.maxTemp);
|
||||||
|
u8g2.setFont(valFont);
|
||||||
|
u8g2.drawStr(77, 34, maxTempBuf);
|
||||||
|
|
||||||
|
// Wenn Ausgewählt
|
||||||
|
if(s.editMaxTemp){
|
||||||
|
// Edit Fenster makieren
|
||||||
|
int w = u8g2.getStrWidth(maxTempBuf);
|
||||||
|
u8g2.drawFrame(75, 24, w + 4, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################
|
||||||
|
// Beschleunigung
|
||||||
|
//######################
|
||||||
|
u8g2.setFont(textFont);
|
||||||
|
u8g2.drawStr(23, 46, "Beschleu:");
|
||||||
|
u8g2.setFont(valFont);
|
||||||
|
char accBuf[10];
|
||||||
|
snprintf(accBuf, sizeof(accBuf), "%d", s.accelRate);
|
||||||
|
u8g2.drawStr(77, 47, accBuf);
|
||||||
|
|
||||||
|
// Wenn Ausgewählt
|
||||||
|
if(s.editAcc){
|
||||||
|
// Edit Fenster makieren
|
||||||
|
int w = u8g2.getStrWidth(accBuf);
|
||||||
|
u8g2.drawFrame(75, 37, w + 4, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
//######################
|
||||||
|
// Save
|
||||||
|
//######################
|
||||||
|
u8g2.setFont(textFont);
|
||||||
|
u8g2.drawUTF8(26, 58, "Bestätigung");
|
||||||
|
|
||||||
|
// Wenn nichts bearbeitet wird...
|
||||||
|
if(!s.editAcc || !s.editMaxTemp){
|
||||||
|
// ... Auswahl rahmen anzeigen
|
||||||
|
int rowY = 0;
|
||||||
|
int rowH = 12;
|
||||||
|
|
||||||
|
switch (settingIdx) {
|
||||||
|
case 0: rowY = 1; break; // Zeituhr Einstellung
|
||||||
|
case 1: rowY = 13; break; // Zeituhr An/Aus
|
||||||
|
case 2: rowY = 25; break; // Max Temp
|
||||||
|
case 3: rowY = 37; break; // Beschleunigung
|
||||||
|
case 4: rowY = 49; break; // Bestätigung
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rahmen um die aktive Zeile (von X=2 bis fast zum rechten Rand)
|
||||||
|
u8g2.drawFrame(2, rowY, 124, rowH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <display_ui.h>
|
#include <display_ui.h>
|
||||||
|
|
||||||
|
|
||||||
const char* ssid = "Stockfeld";
|
const char* ssid = "Stockfeld";
|
||||||
const char* password = "70691554384740972413";
|
const char* password = "70691554384740972413";
|
||||||
|
const char* DISCORD_WEBHOOK = "https://discord.com/api/webhooks/1552818996582285372/ChwhTOdajIwIVbdIpweSorYauwGHJTjjzWNGCjzPw1mh31-snlynh0ZW1InSar_aV8IB";
|
||||||
|
|
||||||
// NTP-Server & Zeitzone für Deutschland
|
// NTP-Server & Zeitzone für Deutschland
|
||||||
const char* ntpServer = "pool.ntp.org";
|
const char* ntpServer = "pool.ntp.org";
|
||||||
|
|
@ -33,6 +33,9 @@ uint32_t lastPlotTime = 0;
|
||||||
bool autoStop = false;
|
bool autoStop = false;
|
||||||
bool bSettings = false;
|
bool bSettings = false;
|
||||||
uint32_t curTemp = 0;
|
uint32_t curTemp = 0;
|
||||||
|
bool send = false;
|
||||||
|
|
||||||
|
bool stopMove = false;
|
||||||
|
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
|
|
||||||
|
|
@ -65,7 +68,7 @@ void loadSettings() {
|
||||||
settings.endMin = prefs.getUChar("e_min", 0);
|
settings.endMin = prefs.getUChar("e_min", 0);
|
||||||
settings.timerEnabled = prefs.getBool("t_on", false);
|
settings.timerEnabled = prefs.getBool("t_on", false);
|
||||||
settings.maxTemp = prefs.getShort("max_temp", 70);
|
settings.maxTemp = prefs.getShort("max_temp", 70);
|
||||||
settings.accelRate = prefs.getInt("accel_rate", 2000);
|
settings.accelRate = prefs.getInt("accel_rate", 20000);
|
||||||
|
|
||||||
prefs.end();
|
prefs.end();
|
||||||
Serial.println("[NVS] Einstellungen erfolgreich geladen.");
|
Serial.println("[NVS] Einstellungen erfolgreich geladen.");
|
||||||
|
|
@ -101,6 +104,32 @@ void initWiFiAndTime() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendDiscordNotification(const String& message) {
|
||||||
|
if (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.println("[Discord] Nicht verbunden mit WiFi.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
WiFiClientSecure client;
|
||||||
|
client.setInsecure(); // Überspringt die rechenintensive Zertifikatsketten-Prüfung
|
||||||
|
|
||||||
|
HTTPClient http;
|
||||||
|
if (http.begin(client, DISCORD_WEBHOOK)) {
|
||||||
|
http.addHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
|
// JSON-Payload: {"content": "Deine Nachricht"}
|
||||||
|
String payload = "{\"content\": \"" + message + "\"}";
|
||||||
|
|
||||||
|
int httpResponseCode = http.POST(payload);
|
||||||
|
if (httpResponseCode == 204 || httpResponseCode == 200) {
|
||||||
|
Serial.println("[Discord] Nachricht erfolgreich gesendet.");
|
||||||
|
} else {
|
||||||
|
Serial.printf("[Discord] Fehler beim Senden: HTTP %d\n", httpResponseCode);
|
||||||
|
}
|
||||||
|
http.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//#######################################################
|
//#######################################################
|
||||||
//####################### Setup #########################
|
//####################### Setup #########################
|
||||||
//#######################################################
|
//#######################################################
|
||||||
|
|
@ -200,7 +229,7 @@ void setting(){
|
||||||
//######### Timer Edit #########
|
//######### Timer Edit #########
|
||||||
if (timeEditStep != EDIT_NONE) {
|
if (timeEditStep != EDIT_NONE) {
|
||||||
//PLUS GEDRÜCKT: Wert erhöhen
|
//PLUS GEDRÜCKT: Wert erhöhen
|
||||||
if (clickPlus || holdPlus) {
|
if (clickPlus) {
|
||||||
switch (timeEditStep) {
|
switch (timeEditStep) {
|
||||||
case EDIT_START_HOUR:
|
case EDIT_START_HOUR:
|
||||||
settings.startHour = (settings.startHour + 1) % 24;
|
settings.startHour = (settings.startHour + 1) % 24;
|
||||||
|
|
@ -250,7 +279,7 @@ void setting(){
|
||||||
if(clickPlus){
|
if(clickPlus){
|
||||||
settings.maxTemp = (settings.maxTemp + 5) % 140;
|
settings.maxTemp = (settings.maxTemp + 5) % 140;
|
||||||
}
|
}
|
||||||
if(clickPlus){
|
if(clickMinus){
|
||||||
settings.maxTemp = (settings.maxTemp == 0) ? -20 : settings.maxTemp - 5;
|
settings.maxTemp = (settings.maxTemp == 0) ? -20 : settings.maxTemp - 5;
|
||||||
}
|
}
|
||||||
if(clickStop){
|
if(clickStop){
|
||||||
|
|
@ -264,7 +293,7 @@ void setting(){
|
||||||
if(clickPlus){
|
if(clickPlus){
|
||||||
settings.accelRate = (settings.accelRate + 1000) % 20000;
|
settings.accelRate = (settings.accelRate + 1000) % 20000;
|
||||||
}
|
}
|
||||||
if(clickPlus){
|
if(clickMinus){
|
||||||
settings.accelRate = (settings.accelRate == 0) ? 0 : settings.accelRate - 1000;
|
settings.accelRate = (settings.accelRate == 0) ? 0 : settings.accelRate - 1000;
|
||||||
}
|
}
|
||||||
if(clickStop){
|
if(clickStop){
|
||||||
|
|
@ -277,7 +306,7 @@ void setting(){
|
||||||
//######### Menü #########
|
//######### Menü #########
|
||||||
// Menü bewegen
|
// Menü bewegen
|
||||||
if(clickPlus){
|
if(clickPlus){
|
||||||
if(settings.settingIdx <= 2){
|
if(settings.settingIdx <= 3){
|
||||||
settings.settingIdx++;
|
settings.settingIdx++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -316,8 +345,8 @@ void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickM
|
||||||
if (millis() - lastPlotTime >= 50) {
|
if (millis() - lastPlotTime >= 50) {
|
||||||
lastPlotTime = millis();
|
lastPlotTime = millis();
|
||||||
|
|
||||||
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
int32_t currentSpeed_HZ = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
||||||
|
int32_t currentSpeed = (currentSpeed_HZ * 60)/1600;
|
||||||
// Format kompatibel für den Arduino Serial Plotter
|
// Format kompatibel für den Arduino Serial Plotter
|
||||||
Serial.print("Current_Speed_U/Min:");
|
Serial.print("Current_Speed_U/Min:");
|
||||||
Serial.print((60*currentSpeed)/3200);
|
Serial.print((60*currentSpeed)/3200);
|
||||||
|
|
@ -353,21 +382,49 @@ void loop() {
|
||||||
shouldRun = isTimerActiveNow(curH, curM, settings.startHour, settings.startMin, settings.endHour, settings.endMin);
|
shouldRun = isTimerActiveNow(curH, curM, settings.startHour, settings.startMin, settings.endHour, settings.endMin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(curTemp >= settings.maxTemp){
|
||||||
|
string message = "Kugelmühle überhitzt! Temp = " + String(curTemp) + " °C";
|
||||||
|
sendDiscordNotification(message);
|
||||||
|
send = true;
|
||||||
|
}else{
|
||||||
|
send = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Not-Stopp aktivieren bei Überhitzung ODER Zeitschaltuhr aus
|
||||||
if(curTemp >= settings.maxTemp || !shouldRun){
|
if(curTemp >= settings.maxTemp || !shouldRun){
|
||||||
autoStop = true;
|
autoStop = true;
|
||||||
}else if(curTemp <= COLDTEMP_C){
|
|
||||||
|
// Entsperren NUR wenn abgekühlt UND Zeitschaltuhr aktiv
|
||||||
|
}else if(curTemp <= COLDTEMP_C && shouldRun){
|
||||||
autoStop = false;
|
autoStop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Zeitschaltuhr start
|
||||||
|
if(settings.timerEnabled && shouldRun){
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// 1. Ziel-Geschwindigkeit vorgeben (z. B. 3200 Steps/s = 120 U/min bei 1/8 Schritt)
|
||||||
|
//stepper->setSpeedInHz(3200);
|
||||||
|
|
||||||
|
// 2. Beschleunigungsrampe festlegen
|
||||||
|
//stepper->setAcceleration(settings.accelRate);
|
||||||
|
|
||||||
|
// 3. Dauerfahrt starten (beschleunigt automatisch bis zur Ziel-Geschwindigkeit)
|
||||||
|
// stepper->runForward(); // oder stepper->runBackward();
|
||||||
|
}
|
||||||
|
|
||||||
// Main Control
|
// Main Control
|
||||||
if(bSettings){
|
|
||||||
setting();
|
if(holdStop && clickPlus){
|
||||||
}else if(clickStop || autoStop){
|
|
||||||
stepper->stopMove();
|
|
||||||
speed = 0;
|
|
||||||
if(clickStop && clickPlus){
|
|
||||||
bSettings = true;
|
bSettings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(bSettings){
|
||||||
|
setting();
|
||||||
|
}else if(clickStop){
|
||||||
|
stopMove = true;
|
||||||
}else if(holdPlus){
|
}else if(holdPlus){
|
||||||
speed = settings.accelRate;
|
speed = settings.accelRate;
|
||||||
}else if(holdMinus){
|
}else if(holdMinus){
|
||||||
|
|
@ -376,13 +433,27 @@ void loop() {
|
||||||
speed = 0;
|
speed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action
|
// STOPP
|
||||||
if (speed != lastSpeed) {
|
if(stopMove || autoStop){
|
||||||
|
// stopp befehl nur senden wenn sich der Motor bewegt
|
||||||
|
if (stepper->isRunning()) {
|
||||||
|
stepper->moveByAcceleration(10000, true);
|
||||||
|
stepper->stopMove();
|
||||||
|
}
|
||||||
|
// MOVE
|
||||||
|
}else if (speed != lastSpeed ) {
|
||||||
stepper->moveByAcceleration(speed, true);
|
stepper->moveByAcceleration(speed, true);
|
||||||
lastSpeed = speed;
|
lastSpeed = speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
// Reset der Brems beschleunigung
|
||||||
|
if (!stepper->isRunning()) {
|
||||||
|
stepper->setAcceleration(settings.accelRate);
|
||||||
|
stopMove = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t currentSpeed_HZ = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
||||||
|
int32_t currentSpeed = (currentSpeed_HZ * 60)/1600;
|
||||||
|
|
||||||
bool timeIsValid = getCurrentTime(curH, curM, curS);
|
bool timeIsValid = getCurrentTime(curH, curM, curS);
|
||||||
updateDisplay(bSettings, settings.settingIdx, timeEditStep, settings, currentSpeed, curH, curM, timeIsValid, curTemp);
|
updateDisplay(bSettings, settings.settingIdx, timeEditStep, settings, currentSpeed, curH, curM, timeIsValid, curTemp);
|
||||||
350
main.ino
350
main.ino
|
|
@ -1,350 +0,0 @@
|
||||||
#include <Arduino.h>
|
|
||||||
#include <Preferences.h>
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
//#####################################
|
|
||||||
//########### Hilfsfunktion ###########
|
|
||||||
//#####################################
|
|
||||||
|
|
||||||
// Überladung des Präfix-Operators (++timeEditStep)
|
|
||||||
TimeEditStep& operator++(TimeEditStep& step) {
|
|
||||||
step = (step == EDIT_END_MIN) ? EDIT_NONE : static_cast<TimeEditStep>(step + 1);
|
|
||||||
return step;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Werte aus dem Flash speicher laden
|
|
||||||
void loadSettings() {
|
|
||||||
// Namespace öffnen (Name max. 15 Zeichen, "true" = read-only)
|
|
||||||
prefs.begin("timer_cfg", true);
|
|
||||||
|
|
||||||
// Werte auslesen
|
|
||||||
settings.startHour = prefs.getUChar("s_hour", 0);
|
|
||||||
settings.startMin = prefs.getUChar("s_min", 0);
|
|
||||||
settings.endHour = prefs.getUChar("e_hour", 0);
|
|
||||||
settings.endMin = prefs.getUChar("e_min", 0);
|
|
||||||
settings.timerEnabled = prefs.getBool("t_on", false);
|
|
||||||
settings.maxTemp = prefs.getShort("max_temp", 70);
|
|
||||||
settings.accelRate = prefs.getInt("accel_rate", 2000);
|
|
||||||
|
|
||||||
prefs.end();
|
|
||||||
Serial.println("[NVS] Einstellungen erfolgreich geladen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save Settings in Flash Speichern
|
|
||||||
void saveSettings() {
|
|
||||||
prefs.begin("timer_cfg", false); // "false" = Read/Write
|
|
||||||
|
|
||||||
prefs.putUChar("s_hour", settings.startHour);
|
|
||||||
prefs.putUChar("s_min", settings.startMin);
|
|
||||||
prefs.putUChar("e_hour", settings.endHour);
|
|
||||||
prefs.putUChar("e_min", settings.endMin);
|
|
||||||
prefs.putBool("t_on", settings.timerEnabled);
|
|
||||||
prefs.putShort("max_temp", settings.maxTemp);
|
|
||||||
prefs.putInt("accel_rate", settings.accelRate);
|
|
||||||
|
|
||||||
prefs.end();
|
|
||||||
Serial.println("[NVS] Einstellungen im Flash gespeichert.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
|
||||||
Serial.begin(115200);
|
|
||||||
delay(1000); // Zeit für USB-CDC-Verbindung geben
|
|
||||||
|
|
||||||
engine.init();
|
|
||||||
stepper = engine.stepperConnectToPin(stepPinStepper);
|
|
||||||
|
|
||||||
if (stepper) {
|
|
||||||
stepper->setDirectionPin(dirPinStepper);
|
|
||||||
stepper->setEnablePin(enablePinStepper, true);
|
|
||||||
stepper->setAutoEnable(true);
|
|
||||||
stepper->setSpeedInHz(MAX_SPEED_HZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pin Config
|
|
||||||
pinMode(buttonPlus, INPUT_PULLUP);
|
|
||||||
pinMode(buttonMinus, INPUT_PULLUP);
|
|
||||||
pinMode(buttonStop, INPUT_PULLUP);
|
|
||||||
|
|
||||||
initWiFiAndTime()
|
|
||||||
|
|
||||||
// Start Animation
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getCurrentTime(int &hour, int &minute, int &second) {
|
|
||||||
if (!getLocalTime(&timeinfo, 50)) { // 50ms Timeout
|
|
||||||
return false; // Noch keine NTP-Zeit synchronisiert
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Liefert true wenn der Timer aktuell Active ist und false wenn nicht aktiv
|
|
||||||
bool isTimerActiveNow(int curH, int curM, int startH, int startM, int endH, int endM) {
|
|
||||||
int current = curH * 60 + curM;
|
|
||||||
int start = startH * 60 + startM;
|
|
||||||
int end = endH * 60 + endM;
|
|
||||||
|
|
||||||
// Fall A: Zeitfenster am selben Tag (z. B. 08:00 bis 16:00)
|
|
||||||
if (start <= end) {
|
|
||||||
return (current >= start && current < end);
|
|
||||||
}
|
|
||||||
// Fall B: Zeitfenster über Mitternacht (z. B. 22:00 bis 04:00)
|
|
||||||
else {
|
|
||||||
return (current >= start || current < end);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MINUS GEDRÜCKT: Wert verringern
|
|
||||||
if (clickMinus) {
|
|
||||||
switch (timeEditStep) {
|
|
||||||
case EDIT_START_HOUR:
|
|
||||||
settings.startHour = (settings.startHour == 0) ? 23 : settings.startHour - 1;
|
|
||||||
break;
|
|
||||||
case EDIT_START_MIN:
|
|
||||||
settings.startMin = (settings.startMin == 0) ? 59 : settings.startMin -5;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// STOP GEDRÜCKT: Zum nächsten Wert springen
|
|
||||||
if (clickStop) {
|
|
||||||
++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;
|
|
||||||
// Einstellungen Speichern
|
|
||||||
saveSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickMinus){
|
|
||||||
// Plotter-Ausgabe alle 50 ms (überflutet den Bus nicht)
|
|
||||||
if (millis() - lastPlotTime >= 50) {
|
|
||||||
lastPlotTime = millis();
|
|
||||||
|
|
||||||
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
|
||||||
|
|
||||||
// Format kompatibel für den Arduino Serial Plotter
|
|
||||||
Serial.print("Current_Speed_U/Min:");
|
|
||||||
Serial.print((60*currentSpeed)/3200);
|
|
||||||
Serial.print(" Accel_Control:");
|
|
||||||
Serial.print(speed);
|
|
||||||
Serial.print(" Btn_Up:");
|
|
||||||
Serial.print(clickPlus ? 5000 : 0);
|
|
||||||
Serial.print(" Btn_Down:");
|
|
||||||
Serial.print(clickMinus ? -5000 : 0);
|
|
||||||
Serial.println();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#############################################################
|
|
||||||
//#################### MAIN ###################################
|
|
||||||
//#############################################################
|
|
||||||
void loop() {
|
|
||||||
int32_t speed = 0;
|
|
||||||
|
|
||||||
// Daten aus Flash speicher laden
|
|
||||||
loadSettings();
|
|
||||||
|
|
||||||
if (!stepper) {
|
|
||||||
Serial.println("[HALT] Kein Stepper-Objekt aktiv.");
|
|
||||||
delay(1000);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inputs
|
|
||||||
getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop);
|
|
||||||
curTemp = getTempInC(senTemp);
|
|
||||||
|
|
||||||
// zeitschaltuhr prüfen
|
|
||||||
int curH, curM, curS;
|
|
||||||
if (settings.timerEnabled && getCurrentTime(curH, curM, curS)) {
|
|
||||||
bool shouldRun = isTimerActiveNow(curH, curM, settings.startHour, settings.startMin, settings.endHour, settings.endMin);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(curTemp >= settings.maxTemp || !shouldRun){
|
|
||||||
autoStop = true;
|
|
||||||
}else if(curTemp <= COLDTEMP_C){
|
|
||||||
autoStop = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main Control
|
|
||||||
if(bSettings){
|
|
||||||
setting()
|
|
||||||
}else if(clickStop || autoStop){
|
|
||||||
stepper->stopMove();
|
|
||||||
speed = 0;
|
|
||||||
if(clickStop && clickPlus){
|
|
||||||
bSettings = true;
|
|
||||||
}
|
|
||||||
}else if(holdPlus){
|
|
||||||
speed = accelRate;
|
|
||||||
}else if(holdMinus){
|
|
||||||
speed = -accelRate;
|
|
||||||
}else{
|
|
||||||
speed = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Action
|
|
||||||
if (speed != lastSpeed) {
|
|
||||||
stepper->moveByAcceleration(speed, true);
|
|
||||||
lastSpeed = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t currentSpeed = stepper->getCurrentSpeedInUs() == 0 ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
|
||||||
|
|
||||||
bool timeIsValid = getCurrentTime(curH, curM);
|
|
||||||
updateDisplay(bSettings, settings.settingIdx, timeEditStep, &settings, currentSpeed, timeIsValid, curTemp);
|
|
||||||
|
|
||||||
// Status ausgabe auf Terminal
|
|
||||||
printStatus(stepper, speed, clickPlus, clickMinus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8
types.h
8
types.h
|
|
@ -4,6 +4,8 @@
|
||||||
#include <Preferences.h>
|
#include <Preferences.h>
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <WiFiClientSecure.h>
|
||||||
|
#include <HTTPClient.h>
|
||||||
|
|
||||||
// Pins
|
// Pins
|
||||||
#define dirPinStepper D8
|
#define dirPinStepper D8
|
||||||
|
|
@ -18,7 +20,7 @@
|
||||||
#define I2C_SDA D4
|
#define I2C_SDA D4
|
||||||
#define I2C_SCL D5
|
#define I2C_SCL D5
|
||||||
|
|
||||||
struct settings{
|
struct settingsALT{
|
||||||
int settingIdx = 0;
|
int settingIdx = 0;
|
||||||
int startHour = 0;
|
int startHour = 0;
|
||||||
int startMin = 0;
|
int startMin = 0;
|
||||||
|
|
@ -28,7 +30,7 @@ struct settings{
|
||||||
bool editMaxTemp = false;
|
bool editMaxTemp = false;
|
||||||
int16_t maxTemp = 70; //in °C
|
int16_t maxTemp = 70; //in °C
|
||||||
bool editAcc = false;
|
bool editAcc = false;
|
||||||
int32_t accelRate = 2000;
|
int32_t accelRate = 2000; // einheit
|
||||||
};
|
};
|
||||||
|
|
||||||
enum TimeEditStep {
|
enum TimeEditStep {
|
||||||
|
|
@ -52,7 +54,7 @@ struct SystemSettings {
|
||||||
bool editMaxTemp = false;
|
bool editMaxTemp = false;
|
||||||
int16_t maxTemp = 70; //in °C
|
int16_t maxTemp = 70; //in °C
|
||||||
bool editAcc = false;
|
bool editAcc = false;
|
||||||
int32_t accelRate = 2000;
|
int32_t accelRate = 20000;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue