• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Указатели и оператор разыменования - вызывают ребут ESP8266

Vasiks

Member
Ситуация такова, решил скрестить анолог WS2812 с MQTT, с целью создать цветовое табло с управлением по MQTT. Скрестил два кода стыренных с просторов интернета, получилось вот что:
Код:
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
//++++++++++++++++++++++++++++++
#include <Adafruit_NeoPixel.h>
#define LED_PIN    5
#define LED_COUNT 12
#define NUMPIXELS 12 //
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels(NUMPIXELS, LED_PIN, NEO_GRB + NEO_KHZ800);
//++++++++++++++++++++++++++++++
#define wifi_ssid "111"
#define wifi_password "#12345678#"

#define mqtt_server "192.168.1.15"
#define mqtt_port 1885
#define mqtt_user "Sup"
#define mqtt_password "2222"
#define mqtt_client_name "Soooo"
#define GPIO4     4

int msgString = 0;
int *msgString_ptr = &msgString;

WiFiClient espClient;
PubSubClient client(espClient);

void callback(char *command_01, byte *payload, unsigned int length)
{
  char buff_p[length];
  for (int i = 0; i < length; i++)
    {
    //Serial.println((char)payload[i]);
    buff_p[i] = (char)payload[i];
    }
    buff_p[length] = '\0';
    String msg_p = String(buff_p);
    int msgString = msg_p.toInt(); // to Int
    *msgString_ptr = msgString;
    Serial.println(msgString);
}

void BlinkRED(){
  if (msgString == 1)
    {
      digitalWrite(GPIO4, HIGH);

    pixels.clear();
    pixels.setPixelColor(0, pixels.Color(0, 255, 0)); //RED
    pixels.setPixelColor(1, pixels.Color(0, 255, 0));
    pixels.setPixelColor(2, pixels.Color(0, 255, 0));
    pixels.setPixelColor(3, pixels.Color(0, 255, 0));
    pixels.setPixelColor(4, pixels.Color(0, 255, 0));
    pixels.setPixelColor(5, pixels.Color(0, 255, 0));
    pixels.setPixelColor(6, pixels.Color(0, 255, 0)); //RED
    pixels.setPixelColor(7, pixels.Color(0, 255, 0));
    pixels.setPixelColor(8, pixels.Color(0, 255, 0));
    pixels.setPixelColor(9, pixels.Color(0, 255, 0));
    pixels.setPixelColor(10, pixels.Color(0, 255, 0));
    pixels.setPixelColor(11, pixels.Color(0, 255, 0));
    pixels.show();
    delay(50);
    pixels.clear();
    pixels.show();
    delay(50);
    }
}


void BlinkGREEN(){
  if (msgString == 2)
    {
      digitalWrite(GPIO4, HIGH);
    pixels.setPixelColor(0, pixels.Color(255, 0, 0)); //RED
    pixels.setPixelColor(1, pixels.Color(255, 0, 0));
    pixels.setPixelColor(2, pixels.Color(255, 0, 0));
    pixels.setPixelColor(3, pixels.Color(255, 0, 0));
    pixels.setPixelColor(4, pixels.Color(255, 0, 0));
    pixels.setPixelColor(5, pixels.Color(255, 0, 0));
    pixels.setPixelColor(6, pixels.Color(255, 0, 0)); //RED
    pixels.setPixelColor(7, pixels.Color(255, 0, 0));
    pixels.setPixelColor(8, pixels.Color(255, 0, 0));
    pixels.setPixelColor(9, pixels.Color(255, 0, 0));
    pixels.setPixelColor(10, pixels.Color(255, 0, 0));
    pixels.setPixelColor(11, pixels.Color(255, 0, 0));
    pixels.show();
    }
}

void ledOff(){
  if (msgString == 0)
    {
      pixels.clear();
      pixels.show();
    digitalWrite(GPIO4, LOW);
    }
}

//=================================================================================
//=================================================================================
void setup(void)
{
  Serial.begin(115200);
  pinMode(GPIO4, OUTPUT);
  client.setCallback(callback);
/////////////////////////////////////////////////////
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
/////////////////////////////////////////////////////
//++++++++++++++++++++++++++++++
  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(10); // Set BRIGHTNESS to about 1/5 (max = 255)
  pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
//++++++++++++++++++++++++++++++
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);
  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
//    blink_red();
    delay(480);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
}
//////////////////////////////////////////////////////////////////////////////////////
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection.....");
    if (client.connect(mqtt_client_name, mqtt_user, mqtt_password)) {
      Serial.println("MQTT connected");
      client.subscribe("SetAlarm/command_01");
    } else {
      Serial.print("Connect failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
     // blink_red();
      delay(200);
      //blink_red();
      delay(4760);
    }
  }
}

void loop(void)
{
  if (!client.connected()) {
    reconnect();
    }
    client.loop();
    BlinkRED();
    ledOff();
    BlinkGREEN();
}
В целом всё работает как нужно, отправляю в топик SetAlarm/command_01 единицу, диоды мерцают красным, когда двойку - горят зелёным, ноль выключает...
Но есть непонятная проблема. Хаотично и непонятно отчего и как ESP12S "вылетает" в перезагрузку. Иногда просто зависает и не восстанавливает рабочий режим. Изредка отваливается MQTT, она постоянно пытается подключиться, но не подключается, а лог сервера вообще не видит никакой активности.
 

Vasiks

Member
Вот какие ошибки выплёвывает:
Код:
Decoding stack results
0x4020c5b1: memp_free at core/memp.c line 447
0x401001dc: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_main.cpp line 159
0x401001dc: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_main.cpp line 159
0x4020be51: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x4020c0ed: new_linkoutput at glue-lwip/lwip-git.c line 265
0x4020c4f8: ethernet_output at netif/ethernet.c line 312
0x4020be51: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40213a58: etharp_output_to_arp_index at core/ipv4/etharp.c line 770
0x4020c0de: new_linkoutput at glue-lwip/lwip-git.c line 260
0x40213cac: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x402154a0: ip4_output_if_opt_src at core/ipv4/ip4.c line 1764
0x4020be51: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40100728: umm_free_core(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 316
0x401009b3: free(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 362
0x40215f98: mem_malloc at core/mem.c line 210
0x40215fb8: mem_free at core/mem.c line 237
0x4020fdce: pbuf_free_LWIP2 at core/pbuf.c line 786
0x40210b5f: tcp_output_control_segment at core/tcp_out.c line 1956
0x40100728: umm_free_core(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 316
0x401009b3: free(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 362
0x40211308: tcp_rst at core/tcp_out.c line 2011
0x40215fb8: mem_free at core/mem.c line 237
0x4020c5b1: memp_free at core/memp.c line 447
0x4020c6b0: tcp_free at core/tcp.c line 217
0x40100728: umm_free_core(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 316
0x401009b3: free(void*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\umm_malloc\umm_malloc.cpp line 362
0x4020bd09: operator delete(void*) at /workdir/repo/gcc/libstdc++-v3/libsupc++/del_op.cc line 48
0x40204e31: uart_write(uart_t*, char const*, size_t) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\uart.cpp line 509
0x40202952: WiFiClient::connect(IPAddress, unsigned short) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\libraries\ESP8266WiFi\src\WiFiClient.cpp line 173
0x402035c0: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/HardwareSerial.h line 159
0x402035cc: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/HardwareSerial.h line 160
0x402035c0: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/HardwareSerial.h line 159
0x40203899: Print::write(char const*) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266/Print.h line 60
0x402039a5: Print::printNumber(unsigned long, unsigned char) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\Print.cpp line 260
0x40205a24: PubSubClient::connected() at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\sketchbook\libraries\PubSubClient\src\PubSubClient.cpp line 606
0x40204e31: uart_write(uart_t*, char const*, size_t) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\uart.cpp line 509
0x40204e31: uart_write(uart_t*, char const*, size_t) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\uart.cpp line 509
0x40203fc0: esp_yield() at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_main.cpp line 100
0x4020457f: __delay(unsigned long) at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_wiring.cpp line 54
0x40201406: reconnect() at C:\Users\Ыц\Desktop\arduino-1.8.12_MQTT ard\!__fw\New_progekt_mqtt_s_nulya_04/New_progekt_mqtt_s_nulya_04.ino line 152
0x4020142a: loop() at C:\Users\Ыц\Desktop\arduino-1.8.12_MQTT ard\!__fw\New_progekt_mqtt_s_nulya_04/New_progekt_mqtt_s_nulya_04.ino line 162
0x402040f0: loop_wrapper() at C:\Users\��\Desktop\arduino-1.8.12_MQTT ard\portable\packages\esp8266\hardware\esp8266\2.6.1\cores\esp8266\core_esp8266_main.cpp line 179
Или то же самое на скрине:
6.JPG

Я пробовал разные версии ядра ESP8266, разные версии IDE. Я пробовал залить это в ESP07S, ошибка аналогична.
А теперь вероятная причина - скорее всего это из-за использования конструкции
int msgString = 0;
int *msgString_ptr = &msgString;

Когда я убрал этот метод, а код из void BlinkRED(), void BlinkGREEN(), void ledOff() поместил в цикл void callback(), то в течение двух суток всё работало без проблем вообще. Никаких вылетов, реконнектов и прочего. Конечно, есть вероятность что просто так совпало, но мне не верится, слишком долго продержалось, обычно проблемы возникают или сразу, или через 10\30\60 минут и повторяются с хаотичной периодичностью.
Я лазил по тем файлам, что в репорте обозначены, но в них разобраться мне не под силу.
Библиотеки стандартные, установлены из Arduino IDE
MQTT v.2.7.0 https://github.com/knolleary/pubsubclient/releases/tag/v2.7
Adafruit_NeoPixel v.1.3.5 https://github.com/adafruit/Adafruit_NeoPixel
Правильно ли я работаю с указателями? Какие способы есть передать значение переменной из одного цикла в другой, сделать локальную переменную глобальной? Или как это вообще делается? Всё взять и засунуть в void callback() как-то не удобно, там будет оочень много кода, который к тому же должен вызываться и из других мест и циклов.
Кто видит где ошибка в коде?
 
Сверху Снизу