• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Esp8266 (NodeMCU v3) + NeoPixel (WS2812B) Проблема с памятью

funny_hat

New member
Доброй ночи.
Имеется код для работы с ESP по вайфаю из приложения Blynk.

Суть кода - светильник, где можно управлять яркостью, скоростью анимации, выбирать эффекты и цвет, вкл/выкл.
Когда тестировал код, то тестил его на 30 светодиодах и всё работало отлично (как, в прочем и сейчас, если изменить количество на 30, то всё пашет изумительно). В рабочем варианте светодиодов 90 штук и при работе одного из режимов упираюсь в exception:

Код:
Exception (29):
epc1=0x40206c96 epc2=0x00000000 epc3=0x00000000 excvaddr=0x0005007f depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffde0 end: 3fffffc0 offset: 01a0
3fffff80:  00000000 00000000 00000000 00000000
3fffff90:  3fffdad0 00000000 3ffeea24 3ffeea64
3fffffa0:  3fffdad0 00000000 3ffeea24 40204fc8
3fffffb0:  feefeffe feefeffe 3ffe8534 40100d3d
<<<stack<<<

ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1392, room 16
tail 0
chksum 0xd0
csum 0xd0
v3d128e5c
~ld
Благодаря ExceptionDecoder'у расшифровал это как:

Код:
Exception 29: StoreProhibited: A store referenced a page mapped with an attribute that does not permit stores
PC: 0x40206c96
EXCVADDR: 0x0005007f
Вопрос: как это можно (и можно ли) поправить? Спасибо.
 

funny_hat

New member
Код. Часть 1:
Код:
#include "SPI.h"
#include "BlynkSimpleEsp8266.h"
#include "ESP8266WiFi.h"
#include "EEPROM.h"
#include "Adafruit_NeoPixel.h"

#define PIN                     D3
#define PIXELS_NUM              91
Adafruit_NeoPixel pxls = Adafruit_NeoPixel(PIXELS_NUM, PIN, NEO_GRB + NEO_KHZ800);

#define RAINBOW_MODE            1
#define RANDOM_COLORS_MODE      2
#define COLOR_WHEEL_MODE        3
#define STROBE_MODE             4
#define SLOW_MOTION_MODE        5
#define CUSTOM_MODE             6

#define RED_VAL                 0
#define GREEN_VAL               1
#define BLUE_VAL                2
#define BRIGHTNESS_VAL          3
#define LED_EFFECT_VAL          4
#define BRIGHTNESS              127
#define R                       255
#define G                       255
#define B                       255
#define LED_EFFECT_NUM          CUSTOM_MODE

#define STROBE_COUNT            5

#define CHECKPOINT_EEPROM_BYTE  50
#define EEPROM_TIME_DELAY       1000
#define EEPROM_UPDATE_TIME      30000
#define FULL_EEPROM_ARRAY_SIZE  512
#define USER_VAL                1

#define BLYNK_PRINT             Serial
//==================================================================================================//
byte DefaultSettings[] = {R, G, B, BRIGHTNESS, LED_EFFECT_NUM};
byte Settings[] = {0, 0, 0, 0, 0};
byte ColorWheelArr[30][3];

bool EepromUpdateFlag = true;
uint32_t EepromUpdateTimer;
uint32_t EepromSaveTimer = 0;

uint32_t LedEffectTimer;
uint8_t LedEffectNumber = 10;
uint8_t TemporaryEffectNumber;
uint16_t LedEffectTimeDelay = 25;
uint8_t j, k;
uint8_t HsvDegree = 0;

char auth[] = "********************************";
char ssid[] = "********************************";
char pass[] = "********************************";

bool PowerButtonState = false;
bool AnimationReverseFlag = false;
bool RandomColorsState = true;

//==================================================================================================//
void setup() {
  Serial.begin(115200);
  Blynk.begin(auth, ssid, pass);
  pxls.begin();
  randomSeed(analogRead(A0));
  EEPROM.begin(FULL_EEPROM_ARRAY_SIZE);

  if (EEPROM.read(CHECKPOINT_EEPROM_BYTE) == USER_VAL) {
    for (int i = 0; i < (sizeof(Settings) / sizeof(Settings[0])); i++) {
      byte EepromCurrentValue = EEPROM.read(i);
      Settings[i] = EepromCurrentValue;
    }
  }
  else {
    for (int i = 0; i < (sizeof(Settings) / sizeof(Settings[0])); i++) {
      Settings[i] = DefaultSettings[i];
    }
  }
  TemporaryEffectNumber = Settings[LED_EFFECT_VAL];
  for (int i = 0; i < PIXELS_NUM; i++) {
    pxls.setPixelColor(i,
                       pxls.Color(0,
                                  0,
                                  0));
  }
  pxls.show();
}
//==================================================================================================//
void loop() {
  Blynk.run();
  //================================================================================================//
  if(Settings[LED_EFFECT_VAL] != CUSTOM_MODE && PowerButtonState){
    if(Settings[LED_EFFECT_VAL] == RAINBOW_MODE){
      if(millis() - LedEffectTimer > LedEffectTimeDelay){
        LedEffectTimer = millis();
        j++;
        for (int i = 0; i < PIXELS_NUM; i++) {
            k=((uint16_t)(i*256 / PIXELS_NUM) + j);
            if(k < 85) {           Settings[RED_VAL]=k*3;                    Settings[GREEN_VAL]=255-Settings[RED_VAL]; Settings[BLUE_VAL]=0;                       } else
            if(k < 170){ k -= 85;  Settings[RED_VAL]=255-Settings[BLUE_VAL]; Settings[GREEN_VAL]=0;                     Settings[BLUE_VAL]=k*3;                     } else
                       { k -= 170; Settings[RED_VAL]=0;                      Settings[GREEN_VAL]=k*3;                   Settings[BLUE_VAL]=255-Settings[GREEN_VAL]; }
            pxls.setPixelColor(i,
                               pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                          map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                          map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
        }
        pxls.show();
      }
    }
    else if(Settings[LED_EFFECT_VAL] == RANDOM_COLORS_MODE){
      if(millis() - LedEffectTimer > LedEffectTimeDelay){
        LedEffectTimer = millis();
        for (int i = 0; i < PIXELS_NUM; i++) {
          int8_t n = random(3);
          if(n == 0){Settings[RED_VAL]   = 0;} else {Settings[RED_VAL]   = random(255);}
          if(n == 1){Settings[GREEN_VAL] = 0;} else {Settings[GREEN_VAL] = random(255);}
          if(n == 2){Settings[BLUE_VAL]  = 0;} else {Settings[BLUE_VAL]  = random(255);}
          pxls.setPixelColor(i,
                             pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                        map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                        map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
        }
        pxls.show();
      }
    }
    else if(Settings[LED_EFFECT_VAL] == COLOR_WHEEL_MODE){
      if(millis() - LedEffectTimer > LedEffectTimeDelay*2){
        LedEffectTimer = millis();
        if(HsvDegree == 0  ){HsvDegree = 42; } else
        if(HsvDegree == 42 ){HsvDegree = 85; } else
        if(HsvDegree == 85 ){HsvDegree = 127;} else
        if(HsvDegree == 127){HsvDegree = 170;} else
        if(HsvDegree == 170){HsvDegree = 212;} else
        if(HsvDegree == 212){HsvDegree = 0;  }
        if(HsvDegree < 85) {Settings[BLUE_VAL]  = 0; Settings[RED_VAL]   = HsvDegree*3; Settings[GREEN_VAL] = 255 - Settings[RED_VAL];  } else
        if(HsvDegree < 170){Settings[GREEN_VAL] = 0; Settings[BLUE_VAL]  = HsvDegree*3; Settings[RED_VAL]   = 255 - Settings[BLUE_VAL]; } else
                           {Settings[RED_VAL]   = 0; Settings[GREEN_VAL] = HsvDegree*3; Settings[BLUE_VAL]  = 255 - Settings[GREEN_VAL];}
        pxls.fill(pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                             map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                             map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
        pxls.show();
      }
    }
    else if(Settings[LED_EFFECT_VAL] == STROBE_MODE){
      if(millis() - LedEffectTimer > LedEffectTimeDelay){
        LedEffectTimer = millis();
        for(int j = 0; j < STROBE_COUNT; j++) {
          pxls.fill(pxls.Color(map(R, 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                               map(G, 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                               map(B, 0, 255, 0, Settings[BRIGHTNESS_VAL])));
          pxls.show();
          delay(LedEffectTimeDelay / 2);
          pxls.fill(0,0,0);
          pxls.show();
          delay(LedEffectTimeDelay / 2);
        }
      }
    }
    else if(Settings[LED_EFFECT_VAL] == SLOW_MOTION_MODE){
      if(millis() - LedEffectTimer > LedEffectTimeDelay){
        LedEffectTimer = millis();
        if(RandomColorsState){
          RandomColorsState = false;
          for (int i = 0; i < PIXELS_NUM; i++) {
            int8_t RandomNumber = random(3);
            if(RandomNumber == 0){ColorWheelArr[i][RED_VAL]   = 0;} else {ColorWheelArr[i][RED_VAL]   = random(255);}
            if(RandomNumber == 1){ColorWheelArr[i][GREEN_VAL] = 0;} else {ColorWheelArr[i][GREEN_VAL] = random(255);}
            if(RandomNumber == 2){ColorWheelArr[i][BLUE_VAL]  = 0;} else {ColorWheelArr[i][BLUE_VAL]  = random(255);}
          }
        }
        if(!AnimationReverseFlag){
          for(int j = 0; j <= Settings[BRIGHTNESS_VAL]; j++){
           if (j == Settings[BRIGHTNESS_VAL]) {AnimationReverseFlag = true;}
           for (int i = 0; i < PIXELS_NUM; i++) {
            pxls.setPixelColor(i,
                               pxls.Color(map(ColorWheelArr[i][RED_VAL],   0, 255, 0, j),
                                          map(ColorWheelArr[i][GREEN_VAL], 0, 255, 0, j),
                                          map(ColorWheelArr[i][BLUE_VAL],  0, 255, 0, j)));
            pxls.show();
           }
           delay(LedEffectTimeDelay / 2);
          }
        }
        else {
          for(int j = Settings[BRIGHTNESS_VAL]; j >= 0; j--){
           if (j == 0) {AnimationReverseFlag = false; RandomColorsState = true;}
           for (int i = 0; i < PIXELS_NUM; i++) {
            pxls.setPixelColor(i,
                               pxls.Color(map(ColorWheelArr[i][RED_VAL],   0, 255, 0, j),
                                          map(ColorWheelArr[i][GREEN_VAL], 0, 255, 0, j),
                                          map(ColorWheelArr[i][BLUE_VAL],  0, 255, 0, j)));
            pxls.show();
           }
           delay(LedEffectTimeDelay / 2);
          }
        }
      }
    }
  }
}
 

funny_hat

New member
Код. Часть 2:
Код:
//==================================================================================================//
BLYNK_WRITE(V1) { // BRIGHTNESS HORIZONTAL SLIDER
  Settings[BRIGHTNESS_VAL] = param.asInt();
  if (PowerButtonState) {
    for (int i = 0; i < PIXELS_NUM; i++) {
      pxls.setPixelColor(i,
                         pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                    map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                    map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
      pxls.show();
    }
  }
}
//==================================================================================================//
BLYNK_WRITE(V2) { // ANIMATION SPEED HORIZONTAL SLIDER
  LedEffectTimeDelay = param.asInt();
}
//==================================================================================================//
BLYNK_WRITE(V3) { // POWER BUTTON
  PowerButtonState = param.asInt();
  if (PowerButtonState) {
    Settings[LED_EFFECT_VAL] = TemporaryEffectNumber;
    if(Settings[LED_EFFECT_VAL] == CUSTOM_MODE){
      for (int i = 0; i < PIXELS_NUM; i++) {
        pxls.setPixelColor(i,
                           pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                      map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                      map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
      }
      pxls.show();
    }
    else {
      LedEffectTimer = millis() - LedEffectTimeDelay;
    }
  }
  else {
    TemporaryEffectNumber = Settings[LED_EFFECT_VAL];
    Settings[LED_EFFECT_VAL] = CUSTOM_MODE;
    for (int i = 0; i < PIXELS_NUM; i++) {
      pxls.setPixelColor(i,
                         pxls.Color(0,
                                    0,
                                    0));
    }
    pxls.show();
  }
}
//==================================================================================================//
BLYNK_WRITE(V4) { // ZeRGBa
  Settings[RED_VAL]   = param[0].asInt();
  Settings[GREEN_VAL] = param[1].asInt();
  Settings[BLUE_VAL]  = param[2].asInt();
  if (PowerButtonState) {
    for (int i = 0; i < PIXELS_NUM; i++) {
      pxls.setPixelColor(i,
                         pxls.Color(map(Settings[RED_VAL],   0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                    map(Settings[GREEN_VAL], 0, 255, 0, Settings[BRIGHTNESS_VAL]),
                                    map(Settings[BLUE_VAL],  0, 255, 0, Settings[BRIGHTNESS_VAL])));
      pxls.show();
    }
  }
}
//==================================================================================================//
BLYNK_WRITE(V5) { // LED EFFECTS MENU
  switch (param.asInt()) {
    case 1:  Settings[LED_EFFECT_VAL] = RAINBOW_MODE;        LedEffectTimer = millis() - LedEffectTimeDelay; break;
    case 2:  Settings[LED_EFFECT_VAL] = RANDOM_COLORS_MODE; LedEffectTimer = millis() - LedEffectTimeDelay; break;
    case 3:  Settings[LED_EFFECT_VAL] = COLOR_WHEEL_MODE;    LedEffectTimer = millis() - LedEffectTimeDelay; break;
    case 4:  Settings[LED_EFFECT_VAL] = STROBE_MODE;         LedEffectTimer = millis() - LedEffectTimeDelay; break;
    case 5:  Settings[LED_EFFECT_VAL] = SLOW_MOTION_MODE;    LedEffectTimer = millis() - LedEffectTimeDelay; break;
    case 6:  Settings[LED_EFFECT_VAL] = CUSTOM_MODE;         LedEffectTimer = millis() - LedEffectTimeDelay; break;
  }
}
//==================================================================================================//
BLYNK_WRITE(V6) { // EEPROM WRITE
  int pinValue = param.asInt();
  if (pinValue && PowerButtonState && (millis() - EepromSaveTimer > EEPROM_TIME_DELAY)) {
    EepromSaveTimer = millis();
    EEPROM.write(CHECKPOINT_EEPROM_BYTE, 1);
    for (int i = 0; i < (sizeof(Settings) / sizeof(Settings[0])); i++) {
      byte EepromCurrentValue = Settings[i];
      EEPROM.write(i, EepromCurrentValue);
    }
    EEPROM.commit();
  }
}
//==================================================================================================//
 

funny_hat

New member
Вопрос частично решился изменением размера массива с 30 до PIXELS_NUM, однако через раз всё же происходит зависание.
 

funny_hat

New member
в коде были так же Serial принты проверочные, после того, как их убрал всё стало работать как надо. Спасибо, разобрался сам :)
 
Сверху Снизу