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-WROVER-DEV funktioniert nicht mehr Twantie 7 261 02.08.2021 11:53
Letzter Beitrag: amithlon
  ESP32 ist nicht gleich ESP32...Problem mit Node32s und Linux Mint 20.2. Uma bm-magic 0 185 29.07.2021 00:58
Letzter Beitrag: bm-magic
  ESP32-Cam mit BLYNK nutzen 4711engel 2 240 24.07.2021 20:57
Letzter Beitrag: 4711engel
  ESP32 T-Watch 2020 Lilygo AnFi 18 6.281 23.07.2021 19:39
Letzter Beitrag: Vapalus
  ESP32-CAM Pan Tilt 4711engel 0 229 22.07.2021 18:35
Letzter Beitrag: 4711engel
  ESP32 und sms kpc 27 4.227 11.07.2021 10:04
Letzter Beitrag: hotsystems
Wink ESP32 IR Empfang auf Core0 Flarki 9 1.077 30.06.2021 19:00
Letzter Beitrag: Flarki
  ESP32 LED D2 blinkt schnell Harry 17 1.940 29.06.2021 19:52
Letzter Beitrag: AnFi
  2 ESP32 laufen nicht zusammen SnecxXx 5 619 24.06.2021 17:08
Letzter Beitrag: hotsystems
  WS2812B LED an ESP32 ? Steinspiel 13 1.534 19.06.2021 22:41
Letzter Beitrag: Bitklopfer

Gehe zu:


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