Compare commits

...

14 Commits

Author SHA1 Message Date
fa74832fb9 docs: update changelog and header for version v1.3.97
All checks were successful
Release Workflow / detect-provider (push) Successful in 3s
Release Workflow / github-release (push) Has been skipped
Release Workflow / gitea-release (push) Successful in 2m47s
2025-02-28 08:53:08 +01:00
2eab3db77d docs: update platformio.ini for version v1.3.97 2025-02-28 08:53:07 +01:00
0a1bf22f7e feat: füge Bestätigungsmeldung für Spool-Einstellung hinzu 2025-02-27 22:07:47 +01:00
d58244c1f8 fix: Speichernutzung optimiert 2025-02-27 21:56:31 +01:00
db626ea516 fix: behebe doppelte http.end() Aufrufe in checkSpoolmanExtraFields 2025-02-27 21:54:47 +01:00
fd8f7685a1 fix: optimiere Verzögerungen und Stackgrößen in NFC-Task-Funktionen 2025-02-27 21:54:32 +01:00
944b156528 feat: verbessere WLAN-Konfiguration und füge mDNS-Unterstützung hinzu 2025-02-27 21:53:48 +01:00
76100593cc refactor: entferne ungenutzte Bibliotheken und Debug-Ausgaben aus main.cpp 2025-02-27 15:50:04 +01:00
732d590344 feat: aktualisiere OLED-Anzeige mit Versionsnummer und verbessere Textausrichtung 2025-02-27 14:35:53 +01:00
46cd953b80 feat: füge regelmäßige WLAN-Verbindungsüberprüfung hinzu 2025-02-27 09:38:54 +01:00
c645035bbe feat: aktualisiere Schaltplan-Bild 2025-02-26 18:29:37 +01:00
9e76620cd3 style: entferne text-shadow von deaktivierten Schaltflächen 2025-02-26 18:07:22 +01:00
faddda6201 feat: zeige Versionsnummer im OLED-Display an 2025-02-26 18:01:35 +01:00
de9c1706c0 docs: füge Link zum Wiki für detaillierte Informationen über die Nutzung hinzu 2025-02-25 20:19:04 +01:00
13 changed files with 298 additions and 183 deletions

View File

@ -1,5 +1,26 @@
# Changelog
## [1.3.97] - 2025-02-28
### Added
- füge Bestätigungsmeldung für Spool-Einstellung hinzu
- verbessere WLAN-Konfiguration und füge mDNS-Unterstützung hinzu
- aktualisiere OLED-Anzeige mit Versionsnummer und verbessere Textausrichtung
- füge regelmäßige WLAN-Verbindungsüberprüfung hinzu
- aktualisiere Schaltplan-Bild
- zeige Versionsnummer im OLED-Display an
### Changed
- update platformio.ini for version v1.3.97
- entferne text-shadow von deaktivierten Schaltflächen
- füge Link zum Wiki für detaillierte Informationen über die Nutzung hinzu
### Fixed
- Speichernutzung optimiert
- behebe doppelte http.end() Aufrufe in checkSpoolmanExtraFields
- optimiere Verzögerungen und Stackgrößen in NFC-Task-Funktionen
- entferne ungenutzte Bibliotheken und Debug-Ausgaben aus main.cpp
## [1.3.96] - 2025-02-25
### Added
- füge Unterstützung für Spoolman-Einstellungen hinzu und aktualisiere die Benutzeroberfläche

View File

@ -6,10 +6,12 @@ Das System integriert sich nahtlos mit der [Spoolman](https://github.com/Donkie/
![Scale](./img/scale_trans.png)
Weitere Bilder finden Sie im [img Ordner](/img/)
Weitere Bilder finden Sie im [img Ordner](/img/)
oder auf meiner Website: [FilaMan Website](https://www.filaman.app)
Deutsches Erklärvideo: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
### Es gibt jetzt auch ein Wiki, dort sind nochmal alle Funktionen beschrieben: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
### ESP32 Hardware-Funktionen
- **Gewichtsmessung:** Verwendung einer Wägezelle mit HX711-Verstärker für präzise Gewichtsverfolgung.
- **NFC-Tag Lesen/Schreiben:** PN532-Modul zum Lesen und Schreiben von Filamentdaten auf NFC-Tags.

View File

@ -13,6 +13,8 @@ More Images can be found in the [img Folder](/img/)
or my website:[FilaMan Website](https://www.filaman.app)
german explanatory video: [Youtube](https://youtu.be/uNDe2wh9SS8?si=b-jYx4I1w62zaOHU)
### Now more detailed informations about the usage: [Wiki](https://github.com/ManuelW77/Filaman/wiki)
### ESP32 Hardware Features
- **Weight Measurement:** Using a load cell with HX711 amplifier for precise weight tracking.
- **NFC Tag Reading/Writing:** PN532 module for reading and writing filament data to NFC tags.

View File

@ -1015,7 +1015,7 @@ input[type="submit"]:disabled,
color: #000;
vertical-align: middle;
margin-left: 0.5rem;
text-shadow: 0 !important;
text-shadow: none !important;
}
.progress-container {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 283 KiB

After

Width:  |  Height:  |  Size: 283 KiB

View File

@ -9,7 +9,7 @@
; https://docs.platformio.org/page/projectconf.html
[common]
version = "1.3.96"
version = "1.3.97"
##
[env:esp32dev]
platform = espressif32

View File

@ -410,12 +410,13 @@ bool checkSpoolmanExtraFields() {
}
}
}
http.end();
}
Serial.println("-------- ENDE Prüfe Felder --------");
Serial.println();
http.end();
return true;
}

View File

@ -23,6 +23,11 @@ const char* bambu_username = "bblp";
const char* bambu_ip = nullptr;
const char* bambu_accesscode = nullptr;
const char* bambu_serialnr = nullptr;
String g_bambu_ip = "";
String g_bambu_accesscode = "";
String g_bambu_serialnr = "";
bool bambu_connected = false;
bool autoSendToBambu = false;
int autoSetToBambuSpoolId = 0;
@ -69,6 +74,11 @@ bool loadBambuCredentials() {
String ip = doc["bambu_ip"].as<String>();
String code = doc["bambu_accesscode"].as<String>();
String serial = doc["bambu_serialnr"].as<String>();
g_bambu_ip = ip;
g_bambu_accesscode = code;
g_bambu_serialnr = serial;
if (doc["autoSendToBambu"].is<bool>()) autoSendToBambu = doc["autoSendToBambu"].as<bool>();
if (doc["autoSendTime"].is<int>()) autoSetBambuAmsCounter = doc["autoSendTime"].as<int>();
@ -77,9 +87,9 @@ bool loadBambuCredentials() {
serial.trim();
// Dynamische Speicherallokation für die globalen Pointer
bambu_ip = strdup(ip.c_str());
bambu_accesscode = strdup(code.c_str());
bambu_serialnr = strdup(serial.c_str());
bambu_ip = g_bambu_ip.c_str();
bambu_accesscode = g_bambu_accesscode.c_str();
bambu_serialnr = g_bambu_serialnr.c_str();
report_topic = "device/" + String(bambu_serialnr) + "/report";
//request_topic = "device/" + String(bambu_serialnr) + "/request";
@ -112,6 +122,7 @@ FilamentResult findFilamentIdx(String brand, String type) {
}
doc.clear();
}
doc.clear();
// Laden der bambu_filaments.json
if (!loadJsonValue("/bambu_filaments.json", doc))
@ -185,7 +196,7 @@ FilamentResult findFilamentIdx(String brand, String type) {
return {"GFL99", "PLA"};
}
bool sendMqttMessage(String payload) {
bool sendMqttMessage(const String& payload) {
Serial.println("Sending MQTT message");
Serial.println(payload);
if (client.publish(report_topic.c_str(), payload.c_str()))
@ -303,16 +314,102 @@ void autoSetSpool(int spoolId, uint8_t trayId) {
Serial.println(spoolInfo.as<String>());
setBambuSpool(spoolInfo.as<String>());
oledShowMessage("Spool set");
}
// id wieder zurücksetzen damit abgeschlossen
autoSetToBambuSpoolId = 0;
}
void updateAmsWsData(JsonDocument& doc, JsonArray& amsArray, int& ams_count, JsonObject& vtTray) {
// Fortfahren mit der bestehenden Verarbeitung, da Änderungen gefunden wurden
ams_count = amsArray.size();
for (int i = 0; i < ams_count && i < 16; i++) {
JsonObject amsObj = amsArray[i];
JsonArray trayArray = amsObj["tray"].as<JsonArray>();
ams_data[i].ams_id = i; // Setze die AMS-ID
for (int j = 0; j < trayArray.size() && j < 4; j++) { // Annahme: Maximal 4 Trays pro AMS
JsonObject trayObj = trayArray[j];
ams_data[i].trays[j].id = trayObj["id"].as<uint8_t>();
ams_data[i].trays[j].tray_info_idx = trayObj["tray_info_idx"].as<String>();
ams_data[i].trays[j].tray_type = trayObj["tray_type"].as<String>();
ams_data[i].trays[j].tray_sub_brands = trayObj["tray_sub_brands"].as<String>();
ams_data[i].trays[j].tray_color = trayObj["tray_color"].as<String>();
ams_data[i].trays[j].nozzle_temp_min = trayObj["nozzle_temp_min"].as<int>();
ams_data[i].trays[j].nozzle_temp_max = trayObj["nozzle_temp_max"].as<int>();
//ams_data[i].trays[j].setting_id = trayObj["setting_id"].as<String>();
ams_data[i].trays[j].cali_idx = trayObj["cali_idx"].as<String>();
}
}
// Setze ams_count auf die Anzahl der normalen AMS
ams_count = amsArray.size();
// Wenn externe Spule vorhanden, füge sie hinzu
if (doc["print"]["vt_tray"].is<JsonObject>()) {
//JsonObject vtTray = doc["print"]["vt_tray"];
int extIdx = ams_count; // Index für externe Spule
ams_data[extIdx].ams_id = 255; // Spezielle ID für externe Spule
ams_data[extIdx].trays[0].id = 254; // Spezielle ID für externes Tray
ams_data[extIdx].trays[0].tray_info_idx = vtTray["tray_info_idx"].as<String>();
ams_data[extIdx].trays[0].tray_type = vtTray["tray_type"].as<String>();
ams_data[extIdx].trays[0].tray_sub_brands = vtTray["tray_sub_brands"].as<String>();
ams_data[extIdx].trays[0].tray_color = vtTray["tray_color"].as<String>();
ams_data[extIdx].trays[0].nozzle_temp_min = vtTray["nozzle_temp_min"].as<int>();
ams_data[extIdx].trays[0].nozzle_temp_max = vtTray["nozzle_temp_max"].as<int>();
if (doc["print"]["vt_tray"]["tray_type"].as<String>() != "")
{
//ams_data[extIdx].trays[0].setting_id = vtTray["setting_id"].as<String>();
ams_data[extIdx].trays[0].cali_idx = vtTray["cali_idx"].as<String>();
}
else
{
ams_data[extIdx].trays[0].setting_id = "";
ams_data[extIdx].trays[0].cali_idx = "";
}
ams_count++; // Erhöhe ams_count für die externe Spule
}
// Erstelle JSON für WebSocket-Clients
JsonDocument wsDoc;
JsonArray wsArray = wsDoc.to<JsonArray>();
for (int i = 0; i < ams_count; i++) {
JsonObject amsObj = wsArray.add<JsonObject>();
amsObj["ams_id"] = ams_data[i].ams_id;
JsonArray trays = amsObj["tray"].to<JsonArray>();
int maxTrays = (ams_data[i].ams_id == 255) ? 1 : 4;
for (int j = 0; j < maxTrays; j++) {
JsonObject trayObj = trays.add<JsonObject>();
trayObj["id"] = ams_data[i].trays[j].id;
trayObj["tray_info_idx"] = ams_data[i].trays[j].tray_info_idx;
trayObj["tray_type"] = ams_data[i].trays[j].tray_type;
trayObj["tray_sub_brands"] = ams_data[i].trays[j].tray_sub_brands;
trayObj["tray_color"] = ams_data[i].trays[j].tray_color;
trayObj["nozzle_temp_min"] = ams_data[i].trays[j].nozzle_temp_min;
trayObj["nozzle_temp_max"] = ams_data[i].trays[j].nozzle_temp_max;
trayObj["setting_id"] = ams_data[i].trays[j].setting_id;
trayObj["cali_idx"] = ams_data[i].trays[j].cali_idx;
}
}
serializeJson(wsArray, amsJsonData);
wsDoc.clear();
Serial.println("AMS data updated");
sendAmsData(nullptr);
}
// init
void mqtt_callback(char* topic, byte* payload, unsigned int length) {
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
@ -320,6 +417,7 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
// JSON-Dokument parsen
JsonDocument doc;
DeserializationError error = deserializeJson(doc, message);
message = "";
if (error)
{
Serial.print("Fehler beim Parsen des JSON: ");
@ -372,9 +470,13 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
// Vergleiche die Trays
for (int j = 0; j < trayArray.size() && j < 4 && !hasChanges; j++) {
JsonObject trayObj = trayArray[j];
if (trayObj["tray_type"].as<String>() == "") ams_data[storedIndex].trays[j].setting_id = "";
if (trayObj["setting_id"].isNull()) trayObj["setting_id"] = "";
if (trayObj["tray_info_idx"].as<String>() != ams_data[storedIndex].trays[j].tray_info_idx ||
trayObj["tray_type"].as<String>() != ams_data[storedIndex].trays[j].tray_type ||
trayObj["tray_color"].as<String>() != ams_data[storedIndex].trays[j].tray_color ||
(trayObj["setting_id"].as<String>() != "" && trayObj["setting_id"].as<String>() != ams_data[storedIndex].trays[j].setting_id) ||
trayObj["cali_idx"].as<String>() != ams_data[storedIndex].trays[j].cali_idx) {
hasChanges = true;
break;
@ -383,150 +485,53 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
}
// Prüfe die externe Spule
if (!hasChanges && doc["print"]["vt_tray"].is<JsonObject>()) {
JsonObject vtTray = doc["print"]["vt_tray"];
bool foundExternal = false;
JsonObject vtTray = doc["print"]["vt_tray"];
if (doc["print"]["vt_tray"].is<JsonObject>()) {
for (int i = 0; i < ams_count; i++) {
if (ams_data[i].ams_id == 255) {
foundExternal = true;
if (vtTray["tray_type"].as<String>() == "") ams_data[i].trays[0].setting_id = "";
if (vtTray["setting_id"].isNull()) vtTray["setting_id"] = "";
if (vtTray["tray_info_idx"].as<String>() != ams_data[i].trays[0].tray_info_idx ||
vtTray["tray_type"].as<String>() != ams_data[i].trays[0].tray_type ||
vtTray["tray_color"].as<String>() != ams_data[i].trays[0].tray_color ||
(vtTray["setting_id"].as<String>() != "" && vtTray["setting_id"].as<String>() != ams_data[i].trays[0].setting_id) ||
(vtTray["tray_type"].as<String>() != "" && vtTray["cali_idx"].as<String>() != ams_data[i].trays[0].cali_idx)) {
hasChanges = true;
}
break;
}
}
//if (!foundExternal) hasChanges = true;
}
if (!hasChanges) return;
// Fortfahren mit der bestehenden Verarbeitung, da Änderungen gefunden wurden
ams_count = amsArray.size();
for (int i = 0; i < ams_count && i < 16; i++) {
JsonObject amsObj = amsArray[i];
JsonArray trayArray = amsObj["tray"].as<JsonArray>();
ams_data[i].ams_id = i; // Setze die AMS-ID
for (int j = 0; j < trayArray.size() && j < 4; j++) { // Annahme: Maximal 4 Trays pro AMS
JsonObject trayObj = trayArray[j];
ams_data[i].trays[j].id = trayObj["id"].as<uint8_t>();
ams_data[i].trays[j].tray_info_idx = trayObj["tray_info_idx"].as<String>();
ams_data[i].trays[j].tray_type = trayObj["tray_type"].as<String>();
ams_data[i].trays[j].tray_sub_brands = trayObj["tray_sub_brands"].as<String>();
ams_data[i].trays[j].tray_color = trayObj["tray_color"].as<String>();
ams_data[i].trays[j].nozzle_temp_min = trayObj["nozzle_temp_min"].as<int>();
ams_data[i].trays[j].nozzle_temp_max = trayObj["nozzle_temp_max"].as<int>();
ams_data[i].trays[j].setting_id = trayObj["setting_id"].as<String>();
ams_data[i].trays[j].cali_idx = trayObj["cali_idx"].as<String>();
}
}
// Setze ams_count auf die Anzahl der normalen AMS
ams_count = amsArray.size();
// Wenn externe Spule vorhanden, füge sie hinzu
if (doc["print"]["vt_tray"].is<JsonObject>()) {
JsonObject vtTray = doc["print"]["vt_tray"];
int extIdx = ams_count; // Index für externe Spule
ams_data[extIdx].ams_id = 255; // Spezielle ID für externe Spule
ams_data[extIdx].trays[0].id = 254; // Spezielle ID für externes Tray
ams_data[extIdx].trays[0].tray_info_idx = vtTray["tray_info_idx"].as<String>();
ams_data[extIdx].trays[0].tray_type = vtTray["tray_type"].as<String>();
ams_data[extIdx].trays[0].tray_sub_brands = vtTray["tray_sub_brands"].as<String>();
ams_data[extIdx].trays[0].tray_color = vtTray["tray_color"].as<String>();
ams_data[extIdx].trays[0].nozzle_temp_min = vtTray["nozzle_temp_min"].as<int>();
ams_data[extIdx].trays[0].nozzle_temp_max = vtTray["nozzle_temp_max"].as<int>();
if (doc["print"]["vt_tray"]["tray_type"].as<String>() != "")
{
ams_data[extIdx].trays[0].setting_id = vtTray["setting_id"].as<String>();
ams_data[extIdx].trays[0].cali_idx = vtTray["cali_idx"].as<String>();
}
else
{
ams_data[extIdx].trays[0].setting_id = "";
ams_data[extIdx].trays[0].cali_idx = "";
}
ams_count++; // Erhöhe ams_count für die externe Spule
}
// Erstelle JSON für WebSocket-Clients
JsonDocument wsDoc;
JsonArray wsArray = wsDoc.to<JsonArray>();
for (int i = 0; i < ams_count; i++) {
JsonObject amsObj = wsArray.add<JsonObject>();
amsObj["ams_id"] = ams_data[i].ams_id;
JsonArray trays = amsObj["tray"].to<JsonArray>();
int maxTrays = (ams_data[i].ams_id == 255) ? 1 : 4;
for (int j = 0; j < maxTrays; j++) {
JsonObject trayObj = trays.add<JsonObject>();
trayObj["id"] = ams_data[i].trays[j].id;
trayObj["tray_info_idx"] = ams_data[i].trays[j].tray_info_idx;
trayObj["tray_type"] = ams_data[i].trays[j].tray_type;
trayObj["tray_sub_brands"] = ams_data[i].trays[j].tray_sub_brands;
trayObj["tray_color"] = ams_data[i].trays[j].tray_color;
trayObj["nozzle_temp_min"] = ams_data[i].trays[j].nozzle_temp_min;
trayObj["nozzle_temp_max"] = ams_data[i].trays[j].nozzle_temp_max;
trayObj["setting_id"] = ams_data[i].trays[j].setting_id;
trayObj["cali_idx"] = ams_data[i].trays[j].cali_idx;
}
}
serializeJson(wsArray, amsJsonData);
Serial.println("AMS data updated");
sendAmsData(nullptr);
updateAmsWsData(doc, amsArray, ams_count, vtTray);
}
// Neue Bedingung für ams_filament_setting
if (doc["print"]["command"] == "ams_filament_setting") {
int amsId = doc["print"]["ams_id"].as<int>();
int trayId = doc["print"]["tray_id"].as<int>();
String settingId = doc["print"]["setting_id"].as<String>();
String settingId = (doc["print"]["setting_id"].is<String>()) ? doc["print"]["setting_id"].as<String>() : "";
// Finde das entsprechende AMS und Tray
for (int i = 0; i < ams_count; i++) {
if (ams_data[i].ams_id == amsId) {
// Update setting_id im entsprechenden Tray
ams_data[i].trays[trayId].setting_id = settingId;
// Erstelle neues JSON für WebSocket-Clients
JsonDocument wsDoc;
JsonArray wsArray = wsDoc.to<JsonArray>();
for (int j = 0; j < ams_count; j++) {
JsonObject amsObj = wsArray.add<JsonObject>();
amsObj["ams_id"] = ams_data[j].ams_id;
JsonArray trays = amsObj["tray"].to<JsonArray>();
int maxTrays = (ams_data[j].ams_id == 255) ? 1 : 4;
for (int k = 0; k < maxTrays; k++) {
JsonObject trayObj = trays.add<JsonObject>();
trayObj["id"] = ams_data[j].trays[k].id;
trayObj["tray_info_idx"] = ams_data[j].trays[k].tray_info_idx;
trayObj["tray_type"] = ams_data[j].trays[k].tray_type;
trayObj["tray_sub_brands"] = ams_data[j].trays[k].tray_sub_brands;
trayObj["tray_color"] = ams_data[j].trays[k].tray_color;
trayObj["nozzle_temp_min"] = ams_data[j].trays[k].nozzle_temp_min;
trayObj["nozzle_temp_max"] = ams_data[j].trays[k].nozzle_temp_max;
trayObj["setting_id"] = ams_data[j].trays[k].setting_id;
trayObj["cali_idx"] = ams_data[j].trays[k].cali_idx;
if (trayId == 254)
{
// Suche AMS mit ID 255 (externe Spule)
for (int j = 0; j < ams_count; j++) {
if (ams_data[j].ams_id == 255) {
ams_data[j].trays[0].setting_id = settingId;
break;
}
}
}
// Aktualisiere das globale amsJsonData
amsJsonData = "";
serializeJson(wsArray, amsJsonData);
else
{
ams_data[i].trays[trayId].setting_id = settingId;
}
// Sende an WebSocket Clients
Serial.println("Filament setting updated");
sendAmsData(nullptr);
@ -538,15 +543,16 @@ void mqtt_callback(char* topic, byte* payload, unsigned int length) {
void reconnect() {
// Loop until we're reconnected
uint8_t retries = 0;
while (!client.connected()) {
Serial.println("Attempting MQTT connection...");
Serial.println("Attempting MQTT re/connection...");
bambu_connected = false;
oledShowTopRow();
// Attempt to connect
if (client.connect(bambu_serialnr, bambu_username, bambu_accesscode)) {
Serial.println("... re-connected");
// ... and resubscribe
Serial.println("MQTT re/connected");
client.subscribe(report_topic.c_str());
bambu_connected = true;
oledShowTopRow();
@ -556,14 +562,23 @@ void reconnect() {
Serial.println(" try again in 5 seconds");
bambu_connected = false;
oledShowTopRow();
// Wait 5 seconds before retrying
yield();
vTaskDelay(5000 / portTICK_PERIOD_MS);
if (retries > 5) {
Serial.println("Disable Bambu MQTT Task after 5 retries");
//vTaskSuspend(BambuMqttTask);
vTaskDelete(BambuMqttTask);
break;
}
retries++;
}
}
}
void mqtt_loop(void * parameter) {
Serial.println("Bambu MQTT Task gestartet");
for(;;) {
if (pauseBambuMqttTask) {
vTaskDelay(10000);
@ -577,6 +592,7 @@ void mqtt_loop(void * parameter) {
}
client.loop();
yield();
esp_task_wdt_reset();
vTaskDelay(100);
}
}
@ -617,7 +633,7 @@ bool setupMqtt() {
xTaskCreatePinnedToCore(
mqtt_loop, /* Function to implement the task */
"BambuMqtt", /* Name of the task */
10000, /* Stack size in words */
8192, /* Stack size in words */
NULL, /* Task input parameter */
mqttTaskPrio, /* Priority of the task */
&BambuMqttTask, /* Task handle. */

View File

@ -20,9 +20,9 @@ void setupDisplay() {
// the library initializes this with an Adafruit splash screen.
display.setTextColor(WHITE);
display.display();
delay(1000); // Pause for 2 seconds
oledShowTopRow();
delay(2000);
oledShowMessage("FilaMan v" + String(VERSION));
vTaskDelay(2000 / portTICK_PERIOD_MS);
}
void oledclearline() {
@ -139,8 +139,9 @@ void oledShowMultilineMessage(String message, uint8_t size) {
int totalHeight = lines.size() * lineHeight;
int startY = OLED_DATA_START + ((OLED_DATA_END - OLED_DATA_START - totalHeight) / 2);
uint8_t lineDistance = (lines.size() == 2) ? 5 : 0;
for (size_t i = 0; i < lines.size(); i++) {
display.setCursor(oled_center_h(lines[i]), startY + (i * lineHeight));
display.setCursor(oled_center_h(lines[i]), startY + (i * lineHeight) + (i == 1 ? lineDistance : 0));
display.print(lines[i]);
}

View File

@ -1,6 +1,4 @@
#include <Arduino.h>
#include <DNSServer.h>
#include <ESPmDNS.h>
#include <Wire.h>
#include <WiFi.h>
@ -35,7 +33,6 @@ void setup() {
initWiFi();
// Webserver
Serial.println("Starte Webserver");
setupWebserver(server);
// Spoolman API
@ -43,19 +40,9 @@ void setup() {
initSpoolman();
// Bambu MQTT
// bambu.cpp
setupMqtt();
// mDNS
Serial.println("Starte MDNS");
if (!MDNS.begin("filaman")) { // Set the hostname to "esp32.local"
Serial.println("Error setting up MDNS responder!");
while(1) {
delay(1000);
}
}
Serial.println("mDNS responder started");
// NFC Reader
startNfc();
uint8_t scaleCalibrated = start_scale();
@ -99,12 +86,20 @@ const unsigned long amsSendInterval = 60000; // 1 minute
uint8_t weightSend = 0;
int16_t lastWeight = 0;
uint8_t wifiErrorCounter = 0;
unsigned long lastWifiCheckTime = 0;
const unsigned long wifiCheckInterval = 60000; // Überprüfe alle 60 Sekunden (60000 ms)
// ##### PROGRAM START #####
void loop() {
unsigned long currentMillis = millis();
// Überprüfe regelmäßig die WLAN-Verbindung
if (millis() - lastWifiCheckTime > wifiCheckInterval) {
checkWiFiConnection();
lastWifiCheckTime = millis();
}
// Send AMS Data min every Minute
if (currentMillis - lastAmsSendTime >= amsSendInterval)
{

View File

@ -238,12 +238,14 @@ void writeJsonToTag(void *parameter) {
hasReadRfidTag = 3;
vTaskSuspend(RfidReaderTask);
vTaskDelay(500 / portTICK_PERIOD_MS);
vTaskDelay(50 / portTICK_PERIOD_MS);
//pauseBambuMqttTask = true;
// aktualisieren der Website wenn sich der Status ändert
sendNfcData(nullptr);
vTaskDelay(100 / portTICK_PERIOD_MS);
oledShowMessage("Waiting for NFC-Tag");
// Wait 10sec for tag
uint8_t success = 0;
String uidString = "";
@ -331,7 +333,7 @@ void startWriteJsonToTag(const char* payload) {
xTaskCreate(
writeJsonToTag, // Task-Funktion
"WriteJsonToTagTask", // Task-Name
4096, // Stackgröße in Bytes
5115, // Stackgröße in Bytes
(void*)payloadCopy, // Parameter
rfidWriteTaskPrio, // Priorität
NULL // Task-Handle (nicht benötigt)
@ -456,7 +458,7 @@ void startNfc() {
BaseType_t result = xTaskCreatePinnedToCore(
scanRfidTask, /* Function to implement the task */
"RfidReader", /* Name of the task */
10000, /* Stack size in words */
5115, /* Stack size in words */
NULL, /* Task input parameter */
rfidTaskPrio, /* Priority of the task */
&RfidReaderTask, /* Task handle. */

View File

@ -3,16 +3,20 @@
#include <WiFi.h>
#include <esp_wifi.h>
#include <WiFiManager.h>
#include <DNSServer.h>
#include <ESPmDNS.h>
#include "display.h"
#include "config.h"
WiFiManager wm;
bool wm_nonblocking = false;
uint8_t wifiErrorCounter = 0;
void initWiFi() {
void wifiSettings() {
// Optimierte WiFi-Einstellungen
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
WiFi.setSleep(false); // disable sleep mode
WiFi.setHostname("FilaMan");
esp_wifi_set_ps(WIFI_PS_NONE);
// Maximale Sendeleistung
@ -23,33 +27,103 @@ void initWiFi() {
// Aktiviere WiFi-Roaming für bessere Stabilität
esp_wifi_set_rssi_threshold(-80);
if(wm_nonblocking) wm.setConfigPortalBlocking(false);
wm.setConfigPortalTimeout(320); // Portal nach 5min schließen
oledShowTopRow();
oledShowMessage("WiFi Setup");
bool res;
// res = wm.autoConnect(); // auto generated AP name from chipid
res = wm.autoConnect("FilaMan"); // anonymous ap
// res = wm.autoConnect("spoolman","password"); // password protected ap
if(!res) {
Serial.println("Failed to connect or hit timeout");
// ESP.restart();
oledShowTopRow();
oledShowMessage("WiFi not connected Check Portal");
}
else {
wifiOn = true;
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
oledShowTopRow();
display.display();
}
void startMDNS() {
if (!MDNS.begin("filaman")) {
Serial.println("Error setting up MDNS responder!");
while(1) {
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
}
Serial.println("mDNS responder started");
}
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
oledShowTopRow();
oledShowMessage("WiFi Config Mode");
}
void initWiFi() {
// load Wifi settings
wifiSettings();
wm.setAPCallback(configModeCallback);
wm.setSaveConfigCallback([]() {
Serial.println("Configurations updated");
ESP.restart();
});
if(wm_nonblocking) wm.setConfigPortalBlocking(false);
//wm.setConfigPortalTimeout(320); // Portal nach 5min schließen
wm.setWiFiAutoReconnect(true);
wm.setConnectTimeout(5);
oledShowTopRow();
oledShowMessage("WiFi Setup");
//bool res = wm.autoConnect("FilaMan"); // anonymous ap
if(!wm.autoConnect("FilaMan")) {
Serial.println("Failed to connect or hit timeout");
// ESP.restart();
oledShowTopRow();
oledShowMessage("WiFi not connected Check Portal");
}
else {
wifiOn = true;
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
oledShowTopRow();
display.display();
vTaskDelay(500 / portTICK_PERIOD_MS);
// mDNS
startMDNS();
}
}
void checkWiFiConnection() {
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("WiFi connection lost. Reconnecting...");
wifiOn = false;
oledShowTopRow();
oledShowMessage("WiFi reconnecting");
WiFi.reconnect(); // Versuche, die Verbindung wiederherzustellen
vTaskDelay(5000 / portTICK_PERIOD_MS); // Warte 5 Sekunden, bevor erneut geprüft wird
if (WiFi.status() != WL_CONNECTED)
{
Serial.println("Failed to reconnect. Restarting WiFi...");
WiFi.disconnect();
Serial.println("WiFi disconnected.");
vTaskDelay(1000 / portTICK_PERIOD_MS);
wifiErrorCounter++;
//wifiSettings();
WiFi.reconnect();
Serial.println("WiFi reconnecting...");
WiFi.waitForConnectResult();
}
else
{
Serial.println("WiFi reconnected.");
wifiErrorCounter = 0;
wifiOn = true;
oledShowTopRow();
startMDNS();
}
}
if (wifiErrorCounter >= 5)
{
Serial.println("Too many WiFi errors. Restarting...");
ESP.restart();
}
}

View File

@ -4,5 +4,6 @@
#include <Arduino.h>
void initWiFi();
void checkWiFiConnection();
#endif