analogWrite и WS2818FX.h

DimTs

✩✩✩✩✩✩✩
21 Ноя 2020
17
8
В проекте параллельно в адресной лентой нужно помигивать 2 светодиодами. Светодиоды мыргают по свом подпрограммам.
void GL_BLINK() { // блинк глаза
if (ONflag) {
if (millis() - GL_tmr >= 50) {
GL_tmr = millis();
if (GL_dir) GL_val = GL_val + 254 ; // увеличиваем яркость
else GL_val--; // уменьшаем
if (GL_val >= 255 || GL_val <= 0) GL_dir = !GL_dir; // разворачиваем
analogWrite(LED_GL, getBrightCRTGL(GL_val));
}
}
else analogWrite(LED_GL, 0);
}
При этом на ленте при выполняющемся эффекте появляются "левые" хаотичные разноцветные вспышки . Если analogWrite(LED_GL, getBrightCRTGL(GL_val)); закомментировать, то эффекты работают как положено. Замена getBrightCRTGL(GL_val) на число проблему не решает.
Плата wemos D1 R2&mini, ядро и 2.7.4 и 3.1.12 пробовал. WS2818FX.h пробовал разных версий. К питанию вопросов нет.
WS2818FX.h выбрана из-за наличия нужных эффектов. Для FastLED.h таких готовых не нашел. Сам не сделаю.
Как лечить проблему?
 

Вложения

  • 3 KB Просмотры: 6
Изменено:

DimTs

✩✩✩✩✩✩✩
21 Ноя 2020
17
8
Должен влезть по габариту. Заменить обычные адресными отдельной "лентой" со своим эффектом? :unsure:
Была такая мысли первоначально, но адресные показались избыточным, т.к. надо простые одноцветные мыргалки.
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@Bruzzer,
ну, оно в другой ситуации помогало.
Не в такой, как у топикстартера.

Объяснение предположительное такое:
На плате стоит бракованная память, которая не успевает то ли читать, то ли сохранять из кэша данные функций, работающих в бесконечном цикле без задержек,
а строчка delay даёт ей время на это.
 
  • Лойс +1
Реакции: DimTs и Bruzzer

DimTs

✩✩✩✩✩✩✩
21 Ноя 2020
17
8
Видимо собака тут порылась:

Функция show(), встроенная в Adafruit_NeoPixel, работает отлично,
но у нее есть один недостаток. Это отключает прерывания. Это означает, что
во время обновления светодиодов все фоновые процессы приостанавливаются. На
на ESP8266 обработка Wi-Fi заблокирована, или на Arduino ШИМ-выход
будет зависать. Следует признать, что обновление светодиода происходит очень быстро (около 30 микросекунд
на светодиод), и прерывания приостанавливаются на очень короткий промежуток времени.


delay не помог.
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@DimTs,
а причём тут Show()?
У вас же AnalogWrite вмешивается в работу, а не наоборот.
 

DimTs

✩✩✩✩✩✩✩
21 Ноя 2020
17
8
Не получается.. Делаю отдельным подпрограммой

int HD_tmr1 = 0; //таймер1
int HD_tmr = 0; //таймер2
int HD_val = 0; //яркость
bool HD_dir = true; //прибавляем-отнимаем
int HD = 0; //количество мыргов*2 перед паузой
byte getBrightCRTHD(byte HD_val) {
return ((long)HD_val * HD_val + 255) >> 8;
}

uint16_t Blinki(void) {

if (ONflag) {
if (millis() - HD_tmr >= 20) {
HD_tmr = millis();
if (HD < 4) {
if (HD_dir) HD_val = HD_val + 10 ; // увеличиваем яркость
else HD_val = HD_val - 1 ; // уменьшаем
if (HD_val >= 255 || HD_val <= 0) {
HD++;
HD_dir = !HD_dir;
}// разворачиваем

ws2812fx2.setBrightness(getBrightCRTHD(HD_val));
ws2812fx2.service();

Serial.println(HD);
Serial.println(getBrightCRTHD(HD_val));
delay(5);
}

else {
if (millis() - HD_tmr1 >= 1000) { // Вместо 10000 подставьте нужное вам значение паузы
HD_tmr1 = millis();
HD++;
if (HD == 6) HD = 0;
Serial.println(HD);
}
}
}
}
}

В основной программе
//лента2
#define NUM_LEDS2 10
#define LED_PIN2 D8

//настройки ленты2
WS2812FX ws2812fx2 = WS2812FX(NUM_LEDS2, LED_PIN2, NEO_GRB + NEO_KHZ800);

void setup()
// лента2

ws2812fx2.init();
ws2812fx2.setBrightness(255);
ws2812fx2.setColor(RED);
ws2812fx2.setSpeed(2000);
ws2812fx2.setMode(FX_MODE_CUSTOM);
ws2812fx2.setCustomMode(Blinki);
ws2812fx2.start();

void loop() {
ws2812fx2.service()

Лента молчит. По монитору порта видно, что HD и HD_val меняются в соответствии с алгоритмом. Если вместо FX_MODE_CUSTOM поставить любой эффект, то он работает. По задумке 2 коротких вспышки - пауза на 1 сек по кругу. С analogWrite работало...

@Сотнег , не подскажите в чем накосячил?
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
500
149
@DimTs,
Если не хочется разбираться с FX_MODE_CUSTOM (тут я ничего подсказать не могу), то может просто управлять этим светодиодом напрямую через Adafruit_NeoPixel ?
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@DimTs,
я в этой библиотекой ничего не делал.
Но, судя по вашему коду, лента должна хотя бы красным светить.
Сперва добейтесь этого, потом мигать будете.
 

DimTs

✩✩✩✩✩✩✩
21 Ноя 2020
17
8
если закомментировать в основной ws2812fx2.setCustomMode(Blinki); то горит красным.
 

Сотнег

★★★★★★★
15 Янв 2020
4,455
1,523
@DimTs,
так проверьте, не гасит ли матрицу ваша функция, если из неё убрать вообще весь код.
Может, вы просто яркость выкручиваете в ноль, но начать поиск ошибки лучше с нуля.
 

Bruzzer

★★★✩✩✩✩
23 Май 2020
500
149
@DimTs,

Adafruit_NeoPixel ledGlaz = Adafruit_NeoPixel(1, GLAZ_PIN, NEO_GRB + NEO_KHZ800);

setup
ledGlaz.begin();
ledGlaz.show(); // Initialize all pixels to 'off'

Вместо analogWrite вызывать

ledGlaz.setPixelColor(0, ledGlaz.Color(GL_val, 0, 0)); //0 - первый диод Color R G B GL_val= яркость красного диода
ledGlaz.show();
 
Изменено:
  • Лойс +1
Реакции: DimTs