INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Lampe mit Sternen & Sternzeichen (ESP32 12x PWM)
27.11.2020, 22:37
Beitrag #1
Lampe mit Sternen & Sternzeichen (ESP32 12x PWM)
Hi Leute,

ich habe ein kleines Projekt für eine Kinderzimmer Lampe. Die Lampe besteht aus drei Holz Wolken, die jeweils Sterne, Sternzeichen und an der Seite indirektes LED-Strips haben. Die Sterne sowie die Sternzeichen habe ich per "Glasfaser" an Leds angeschlossen.
Die ganzen Leds sollen einzeln gesteuert werden, deshalb habe ich noch eine kleine Aufsteckplatine selbst erstellt, die 12 Mosfet beinhalten.

[Bild: lampe.JPG]

Die Hardware läuft soweit sehr gut und die Software lief auch gut. Ich musste den MQTT Server im Skript ändern und seitdem habe ich immer ein Fehler und der ESP32 startet neu
Code:
CORRUPT HEAP: multi_heap.c:432 detected at 0x3ffcc8b0
abort() was called at PC 0x4008ba6b on core 1

Der Fehler steckt in der Funktion "void callback" im zusammen hang mit malloc. Aber so richtig weiß ich nicht wie ich das lösen kann.

Hier der komplette Sketch:
Code:
/*
  Beispiel json:
  {"PWM":{"Setup":{"Modul":[true,true],"freq":5000,"resolution":8},"Stripe":{"Zustand":true,"Farbe":[100,0,0,0],"Weissabgleich":[100,100,100,100]},"Sternenhimmel":{"Normal":2,"Min-Max":[60,80],"Zustand":[false,false]}}}
*/

#include <WiFi.h>
#include <PubSubClient.h>
#ifndef MQTT_MAX_PACKET_SIZE
#define MQTT_MAX_PACKET_SIZE 640
#endif
#include <ArduinoJson.h>

#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

struct StripeN {
  byte AnzahlFarbe;
  byte AnzahlWeiss;
  byte Farbe[4];
  boolean Zustand;
  boolean change = false;
} Stripe;

struct SternenhimmelNormal {
  byte Anzahl;
  boolean Zustand;
  boolean change = false;
  byte duty;
} Sterne;

struct SternenhimmelFlash {
  byte Anzahl;
  byte Min;
  byte Max;
  boolean Zustand;
  boolean change = false;
} SterneFlash;

const char* WLAN[] = {"SSID", "PASS", "Client Name"};                 // WiFi STA Parameter
const char* MQTT[] = {"HOST", "PORT", "MQTT-Client-Name", "USER", "PASS"};   // MQTT Server Parameter
const char* inTOPIC = "Kinderzimmer/Licht";

//JSON
char* temp_payload;

DynamicJsonDocument doc(1024);

//PINS & PWM
bool incomming = false;
bool PWMsetup = false;

byte PWMPins[] = {12, 14, 27, 26, 25, 33, 32, 15, 2, 0, 4, 16, 17, 5, 18, 23}; // Brücke von 23 zu 35
byte PWMPinsAnzahl = sizeof(PWMPins) / sizeof(PWMPins[0]);

int PWMmaxduty;
byte PWMduty[16];   // duty Werte zwischenspeichern
byte PWMweiss[16];  // Weißabgleich Werte zwischenspeichern

// Variablen für Timmer
int period = 1000;
unsigned long time_now;
long lastReconnectAttempt = 0;

WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);

void setup() {
  Serial.begin(115200);
  Serial.print(F("\n\rSketch startet ...\n\r"));
  for (byte i = 0; i < PWMPinsAnzahl; i++) {
    pinMode (PWMPins[i], OUTPUT);
  }
  setup_wifi();
  //setup_ota();
  mqtt.setServer(MQTT[0], atoi(MQTT[1]));
  mqtt.setCallback(callback);
  lastReconnectAttempt = 0;
}

void setup_wifi() {
wifi_restart:
  time_now = millis();
  delay(10);
  Serial.printf("\n\rVerbinde zu [%s] ", WLAN[0]);
  WiFi.setHostname(WLAN[2]);
  WiFi.begin(WLAN[0], WLAN[1]);
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print(F("."));
    if (millis() - time_now > (period * 2)) {
      WiFi.mode(WIFI_OFF);
      Serial.print(F(" fehlgeschlagen\n\r"));
      goto wifi_restart;
    }
  }
  WiFi.enableIpV6();
  randomSeed(micros());
  Serial.printf(" verbunden\n\rIP4 address: %s\n\r", (char*) WiFi.localIP().toString().c_str());
}

void setup_ota() {//print Ausgabene verändern
  Serial.print(F("\n\rOTA Service ... gestartet\n\r"));
  ArduinoOTA.setPort(3232);
  ArduinoOTA.setHostname(WLAN[2]); // Hostname defaults to esp3232-[MAC]
  // No authentication by default
  // ArduinoOTA.setPassword("admin");
  // Password can be set with it's md5 value as well
  // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3
  // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3");

  ArduinoOTA
  .onStart([]() {
    char* type;
    if (ArduinoOTA.getCommand() == U_FLASH)
      type = "sketch";
    else // U_SPIFFS
      type = "filesystem";

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.printf("\rStart update %s\n\r", type);
  })
  .onEnd([]() {
    Serial.print(F("\n\rOTA Update Ende\n\r"));
  })
  .onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  })
  .onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) Serial.print(F("Auth Failed\n\r"));
    else if (error == OTA_BEGIN_ERROR) Serial.print(F("Begin Failed\n\r"));
    else if (error == OTA_CONNECT_ERROR) Serial.print(F("Connect Failed\n\r"));
    else if (error == OTA_RECEIVE_ERROR) Serial.print(F("Receive Failed\n\r"));
    else if (error == OTA_END_ERROR) Serial.print(F("End Failed\n\r"));
  });
  ArduinoOTA.begin();
}

void callback(char* topic, byte *payload, unsigned int length) {
  if (!temp_payload || ((String)temp_payload != String((char*)payload))) {
    temp_payload = (char*) malloc(length);
    strcpy(temp_payload, (char*)payload);
    memcpy(temp_payload, payload, length);
    incomming = true;

    Serial.printf("Message arrived [%s]\n\r", topic);
    Serial.write(payload, length);
    Serial.print(F("\n\r\n\r"));
    deserializeJson(doc, payload, length);
  }
}

boolean reconnect() {
  Serial.print(F("\n\rVerbindung zum MQTT Server"));
  if (mqtt.connect(MQTT[2] , MQTT[3] , MQTT[4])) { // Attempt to connect
    Serial.print(F(" ... verbunden\n\r\n\r"));
    mqtt.subscribe(inTOPIC);
  } else {
    Serial.print(F(" ... fehlgeschlagen\n\r"));
    switch (mqtt.state()) {
      case -4:
        Serial.print(F("MQTT_CONNECTION_TIMEOUT - Der Server hat nicht innerhalb der Keepalive-Zeit geantwortet\n\r"));
        break;
      case -3:
        Serial.print(F("MQTT_CONNECTION_LOST - Die Netzwerkverbindung wurde unterbrochen\n\r"));
        break;
      case -2:
        Serial.print(F("MQTT_CONNECT_FAILED - Die Netzwerkverbindung ist fehlgeschlagen\n\r"));
        break;
      case -1:
        Serial.print(F("MQTT_DISCONNECTED - Die Verbindung zum Client wurde ordnungsgemäß getrennt\n\r"));
        break;
      case 0:
        Serial.print(F("MQTT_CONNECTED - Der Client ist verbunden\n\r"));
        break;
      case 1:
        Serial.print(F("MQTT_CONNECT_BAD_PROTOCOL - Der Server unterstützt die angeforderte Version von MQTT nicht\n\r"));
        break;
      case 2:
        Serial.print(F("MQTT_CONNECT_BAD_CLIENT_ID - Der Server hat die Client-ID abgelehnt\n\r"));
        break;
      case 3:
        Serial.print(F("MQTT_CONNECT_UNAVAILABLE - Der Server konnte die Verbindung nicht akzeptieren\n\r"));
        break;
      case 4:
        Serial.print(F("MQTT_CONNECT_BAD_CREDENTIALS - Benutzername / Passwort wurden abgelehnt\n\r"));
        break;
      case 5:
        Serial.print(F("MQTT_CONNECT_UNAUTHORIZED - Der Client war nicht berechtigt, eine Verbindung herzustellen\n\r"));
        break;
    }
  }
  return mqtt.connected();
}

int PWMdown(int PWMchannel, int PWMduty, int PWMstep, int PWMdelay) {
  int var = 0;
  while (var < PWMstep) {
    PWMduty = PWMduty - 10;
    ledcWrite(PWMchannel, PWMduty);
    delay (PWMdelay);
    var++;
    if (var == PWMstep) {
      Serial.print(PWMduty);
      return PWMduty;
    }
  }
  return false;
}

int PWMup(int PWMchannel, int PWMduty, int PWMstep, int PWMdelay) {
  int var = 0;
  while (var < PWMstep) {
    PWMduty = PWMduty + 10;
    ledcWrite(PWMchannel, PWMduty);
    delay (PWMdelay);
    var++;
    if (var == PWMstep) {
      Serial.print(PWMduty);
      return PWMduty;
    }
  }
  return false;
}

void loop() {

  byte wifi_retry = 0;
  while (WiFi.status() != WL_CONNECTED && wifi_retry < 5 ) {
    wifi_retry++;
    Serial.print(F("WiFi nicht verbunden. Versuchen erneut, eine Verbindung herzustellen\n\r"));
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    setup_wifi();
    delay(100);
  }
  if (wifi_retry >= 5) {
    Serial.println(F("\n\rReboot"));
    ESP.restart();
  }
  ArduinoOTA.handle();
  if (!mqtt.connected()) {
    long now = millis();
    if (now - lastReconnectAttempt > 5000) {
      lastReconnectAttempt = now;
      // Attempt to reconnect
      if (reconnect()) {
        lastReconnectAttempt = 0;
      }
    }
  } else {
    mqtt.loop();
    if (incomming) {
      incomming = false;
      bool change = false;
      JsonObject PWM = doc["PWM"];
      JsonObject Setup = PWM["Setup"];
      if (!PWMsetup) { //JSON Auswertung: Setup
        Serial.print(F("JSON Auswertung: S-E-T-U-P\n\r"));
        PWMsetup = true;
        
        
        for (byte i = 0; i < PWMPinsAnzahl; i++) {
          ledcAttachPin(PWMPins[i], i);
          ledcSetup(i, Setup["freq"], Setup["resolution"]);
          ledcWrite(i, 0);
          PWMduty[i] = 0;
          Serial.printf("PWM-Kanal: %d\tPin: %d\tHelligkeit: %d \n\r", i, PWMPins[i], PWMduty[i]);
        }
        PWMmaxduty = pow(2, Setup["resolution"]) - 1;
      }
      if ((bool)Setup["Modul"][0]) { //JSON Auswertung: Stripe
        Serial.print(F("\n\rJSON Auswertung: S-T-R-I-P-E\n\r"));
        JsonObject JSONStripe = PWM["Stripe"];
        if (Stripe.AnzahlFarbe != JSONStripe["Farbe"].size()) {
          Stripe.AnzahlFarbe = JSONStripe["Farbe"].size();
          Stripe.AnzahlWeiss = JSONStripe["Weissabgleich"].size();
          Stripe.change = true;
        }
        if (Stripe.Zustand != (bool)JSONStripe["Zustand"]) {
          Stripe.Zustand = JSONStripe["Zustand"];
          Stripe.change = true;
        }

        // Hat sich eine Wert von Farbe geändert
        for (byte i = 0; i < Stripe.AnzahlFarbe; i++) {
          int Farbe = JSONStripe["Farbe"][i];
          if (PWMduty[i] != Farbe) {
            change = true;
            Stripe.change = true;
            break;
          }
        }
        // Hat sich ein Wert von Weißabgleich geändert
        for (byte i = 0; i < Stripe.AnzahlWeiss; i++) {
          int Weissabgleich = JSONStripe["Weissabgleich"][i];
          if (PWMweiss[i] != Weissabgleich) {
            change = true;
            break;
          }
        }
        // Stripe Zustand hat sich geändert
        if (Stripe.Zustand != (bool)JSONStripe["Zustand"]) {
          Stripe.Zustand = JSONStripe["Zustand"];
          change = true;
          Stripe.change = true;
        }

        // Stripe Zustand true
        if (Stripe.Zustand && change) {
          if (Stripe.AnzahlFarbe == Stripe.AnzahlWeiss) { // Array Farbe und Weissabgleich haben gleiche länge
            for (byte i = 0; i < Stripe.AnzahlFarbe; i++) {
              int Farbe = JSONStripe["Farbe"][i];
              int Weissabgleich = JSONStripe["Weissabgleich"][i];
              PWMduty[i] = Farbe;
              PWMweiss[i] = Weissabgleich;
            }
          } else {
            int Weissabgleich = JSONStripe["Weissabgleich"][0];
            for (byte i = 0; i < Stripe.AnzahlFarbe; i++) {
              int Farbe = JSONStripe["Farbe"][i];
              PWMduty[i] = Farbe;
              PWMweiss[i] = Weissabgleich;
            }
          }
          // Stripe Zustand false
        } else if (!Stripe.Zustand && change) {
          for (byte i = 0; i < Stripe.AnzahlFarbe; i++) {
            PWMduty[i] = 0;
          }
        }

        // PWM Kanäle für Stripe schalten
        if (change) {
          for (byte i = 0; i < Stripe.AnzahlFarbe; i++) {
            Serial.printf("PWM-Kanal: %d\tPin: %d\tHelligkeit: %d\n\r", i, PWMPins[i], PWMduty[i] * PWMweiss[i] / 100);
            ledcWrite(i, PWMduty[i]);
          }
        }
        Serial.printf("\nPWM Kanäle: %d\tZustand: %s\n\r", Stripe.AnzahlFarbe, Stripe.Zustand ? "An" : "Aus");
      }
      if ((bool)Setup["Modul"][1]) { //JSON Auswertung: Sternenhimmel
        JsonObject Sternenhimmel = PWM["Sternenhimmel"];
        Serial.print(F("\n\rJSON Auswertung: S-T-R-I-P-E\n\r"));
        Serial.print(F("\n\rJSON Auswertung: S-T-E-R-N-E-N-H-I-M-M-E-L Normal\n\r"));
        if (Sterne.Anzahl != (byte(Sternenhimmel["Normal"]))) {
          Sterne.Anzahl = (byte(Sternenhimmel["Normal"]));
          Sterne.change = true;
          //SterneFlash.change = true;
        }
        if (Sterne.Zustand != (bool)Sternenhimmel["Zustand"][1]) {
          Sterne.Zustand = Sternenhimmel["Zustand"][1];
          Sterne.change = true;
        }
        if (Sterne.change) {
          Sterne.change = false;
          switch (Sterne.Zustand) {
            case 0: Sterne.duty = 0; break;
            case 1: Sterne.duty = 255; break;
          }
          for (byte i = Stripe.AnzahlFarbe; i < Sterne.Anzahl  + Stripe.AnzahlFarbe; i++) {
            PWMduty[i] = Sterne.duty;
            ledcWrite(i, PWMduty[i]);
            Serial.printf("PWM-Kanal: %d\tPin: %d\tHelligkeit: %d \n\r", i, PWMPins[i], PWMduty[i]);
          }
          Serial.printf("PWM Kanäle: %d\tZustand: %s\n\r", Sterne.Anzahl, Sterne.Zustand ? "An" : "Aus");
        }
        Serial.print(F("\n\rJSON Auswertung: S-T-E-R-N-E-N-H-I-M-M-E-L Flash\n\r"));
        SterneFlash.Anzahl = PWMPinsAnzahl - Stripe.AnzahlFarbe - Sterne.Anzahl;
        if (SterneFlash.Zustand != (bool)Sternenhimmel["Zustand"][0]) {
          SterneFlash.Zustand = Sternenhimmel["Zustand"][0];
          SterneFlash.change = true;
        }
        if (SterneFlash.Min != (byte)Sternenhimmel["Min-Max"][0]) {
          SterneFlash.Min = Sternenhimmel["Min-Max"][0];
          SterneFlash.change = true;
        }
        if (SterneFlash.Max != (byte)Sternenhimmel["Min-Max"][1]) {
          SterneFlash.Max = Sternenhimmel["Min-Max"][1];
          SterneFlash.change = true;
        }
        if (SterneFlash.change) {
          SterneFlash.change = false;
          byte Zufallszahl;
          for (byte i = PWMPinsAnzahl - SterneFlash.Anzahl; i < PWMPinsAnzahl; i++) {
              Zufallszahl = random(SterneFlash.Min, SterneFlash.Max);
              switch (SterneFlash.Zustand) {
                case 0: PWMduty[i] = 0; break;
                case 1: PWMduty[i] = PWMmaxduty * random(SterneFlash.Min, SterneFlash.Max) / 100; break;
              }
              ledcWrite(i, PWMduty[i]);
              Serial.printf("PWM-Kanal: %d\tPin: %d\tHelligkeit: %d \n\r", i, PWMPins[i], PWMduty[i]);
          }
        }
      }
      Serial.printf("\n\rPWM Kanäle: %d\tZustand: %s\n\r", SterneFlash.Anzahl, SterneFlash.Zustand ? "An" : "Aus");
    }
  }
  if (SterneFlash.Zustand) {
    if (millis() > time_now + (period / 10 * random(25, 75)) && SterneFlash.Zustand) { // Sternenhimmer flakern
      time_now = millis();
      int PWM;
      int channel = (random(Stripe.AnzahlFarbe + Sterne.Anzahl, PWMPinsAnzahl));
      int PWMrandom = random(8, 10);
      int PWMdelay = random(800, 1500) / PWMrandom;

      Serial.printf("PWM-Kanal: %d - Schritte: %d - Wartezeit: %d - Richtung: ", channel, PWMrandom, PWMdelay);
      switch (random(2)) {
        case 0:
          Serial.printf("< Helligkeit: %d  < ", PWMduty[channel]);
          PWM = PWMdown(channel, PWMduty[channel], PWMrandom, PWMdelay);
          Serial.print(" > ");
          PWMup(channel, PWM, PWMrandom, PWMdelay);
          break;
        case 1:
          Serial.printf("> - Helligkeit: %d > ", PWMduty[channel]);
          PWM = PWMup(channel, PWMduty[channel], PWMrandom, PWMdelay);
          Serial.print(" < ");
          PWMdown(channel, PWM, PWMrandom, PWMdelay);
          break;
      }
      Serial.println();
    }
  }
}
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.11.2020, 22:54 (Dieser Beitrag wurde zuletzt bearbeitet: 27.11.2020 23:01 von Tommy56.)
Beitrag #2
RE: Lampe mit Sternen & Sternzeichen (ESP32 12x PWM)
Du solltest prüfen, ob malloc einen gültigen Pointer zurück liefert.
Code:
temp_payload = (char*) malloc(length);
if (temp_payload) {
  // mache was damit
}
und Du solltest auch den Pointer wieder frei geben, Weil immer malloc ist der Speicher bald voll.
Ich habe Dein if nicht gecheckt aber Du gibst im Zweifel temp_payload nicht wieder frei und dann ist irgendwann der RAM zu Ende.[/code]

Gruß Tommy

Außerdem solltest Du Dich entscheiden, ob Du mit String oder char-Arrays arbeiten willst. Die Mischung ist in der Regel tödlich.

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.11.2020, 23:11 (Dieser Beitrag wurde zuletzt bearbeitet: 27.11.2020 23:12 von Panicer.)
Beitrag #3
RE: Lampe mit Sternen & Sternzeichen (ESP32 12x PWM)
Du meinst glaub ich die if Abfrage im void Callback
Code:
if (!temp_payload || ((String)temp_payload != String((char*)payload))) {
die soll Prüfen ob temp_payload schon einen Inhalt hat oder temp_payload ungleich payload ist. Damit er nicht bei jedem Empfang was macht und void Loop dann arbeiten kann.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
27.11.2020, 23:26
Beitrag #4
RE: Lampe mit Sternen & Sternzeichen (ESP32 12x PWM)
Ich glaube das || oder ist falsch.

Du solltest erst prüfn, ob irgendwas ungleich ist, wenn ja, ob temp_payload Null ist. Wenn nein, temp_payload frei geben und dann neu belegen.

Aber wie bereits gesagt, die Mischung aus String und char-Array wird Dir im Endeffekt das Genick brechen. Entscheide Dich.
Welchen Prozessor nutzt Du?

Gruß Tommy

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  ESP32 Daten aus HTML Roger100499 11 169 Heute 15:00
Letzter Beitrag: Tommy56
  Erfahrungen mit ESP32 und WLAN/MQTT oder was ich beobachtet habe... Arduino4Fun 23 3.280 09.04.2021 16:15
Letzter Beitrag: amshh
  Suche Erfahrungen und Hilfe mit ESP32-CAM WiFi + Bluetooth Modul Kamera Modul esp32 Christian_Moba-Arduino 28 1.427 04.04.2021 08:24
Letzter Beitrag: amithlon
  ESP32 CAM Flashlamp schalten RaspiUser0815 13 3.077 28.03.2021 21:51
Letzter Beitrag: Grufti99
  ESP32-cam WAV´s einmalig auf GPI0 25/26 abspielen Sarastro 2 309 28.03.2021 10:45
Letzter Beitrag: Sarastro
  Led-Matrix 8x32 mit Esp32 Zerrus 5 390 27.03.2021 14:16
Letzter Beitrag: hotsystems
  Esp32 MD-Parola Scrolltext wwilhelm 3 324 26.03.2021 22:35
Letzter Beitrag: Tommy56
  ESP32 und Interrupts - ein Erfahrungsbericht - und eine Frage ;) MicroBahner 6 540 24.03.2021 09:18
Letzter Beitrag: MicroBahner
Brick Tiefgehende ESP32 Schnittstellen-Dokumentation gesucht Roland53425 6 733 22.03.2021 18:54
Letzter Beitrag: Bitklopfer
  Fehler beim Kompilieren für das Board ESP32 Dev Module. FoxFactoy 17 2.784 06.03.2021 21:56
Letzter Beitrag: bm-magic

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste