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
  Boot loop auf ESP32 nur mit JTAG-Reset zu stoppen miq19 6 129 Gestern 18:04
Letzter Beitrag: miq19
  Esp32-cam Motor und Servo Ansteuerung Noformat 13 160 25.01.2021 22:15
Letzter Beitrag: hotsystems
  ESP32 D1mini: Schiebeschalter für was? AnFi 2 246 16.01.2021 09:16
Letzter Beitrag: AnFi
  ESP32 Board und LCDKeypadShield kjoussen 23 840 11.01.2021 00:04
Letzter Beitrag: kjoussen
  Erfahrungen mit ESP32 und WLAN/MQTT oder was ich beobachtet habe... Arduino4Fun 13 972 10.01.2021 14:18
Letzter Beitrag: nbk83
Question ESP32 als BLE client, int to 2byte Wert reisner 3 244 07.01.2021 18:13
Letzter Beitrag: Tommy56
  ESP32 über OTA luemar 58 2.291 03.01.2021 13:50
Letzter Beitrag: luemar
  Woher Gehäuse für ESP32 ? Steinspiel 36 2.284 28.12.2020 00:43
Letzter Beitrag: Steinspiel
Smile Frage zu Millis im Loop - ESP32 Stargazer 5 735 27.12.2020 06:41
Letzter Beitrag: N1d45
  ESP32 Devkit c4 Oled und RFID RC522 betreiben klappt nicht steffus 1 327 23.12.2020 12:45
Letzter Beitrag: hotsystems

Gehe zu:


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