Глюки в WS2812B (Arduino)

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Сообщения: 546
Зарегистрирован: Вс дек 30, 2012 00:32:06
Откуда: Николаев / Украина

Сообщение forfrends »

Всем привет!
Создаю один проект. В качестве индикации буду использовать адресные светодиоды WS2812B, 16 штук, которые создают визуальную шкалу. Код:
Спойлер#include <Adafruit_NeoPixel.h>

#define BLYNK_PRINT Serial

#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = "1f65de93e395467c9a2bab7f12886742";

char ssid[] = "DIR-615";
char pass[] = "forfrends";

#define LedPIN 13 // Pin D7
// On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 16 // Popular NeoPixel ring size

#define FanPin 13 // D7
int FanSpeed = 500;
bool Ionithation = false;
#define IonPin 2 // D8
#define Button 0 // D3
#define pin_A 14 // D5
#define pin_B 12 // D6
unsigned char encoder_A;
unsigned char encoder_B;
unsigned char encoder_A_prev=0;
unsigned char encoder_B_prev=0;
String input_string = "";
int Pow = 7;

//Adafruit_NeoPixel pixels(NUMPIXELS, LedPIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LedPIN, NEO_GRB + NEO_KHZ800);

void setup()
{
Serial.begin(9600);

Blynk.begin(auth, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8080);
pinMode(pin_A, INPUT);
pinMode(pin_B, INPUT);
pinMode(Button, INPUT);
digitalWrite(Button, HIGH);
pinMode(IonPin, OUTPUT);
digitalWrite(IonPin, LOW);
pinMode(FanPin, OUTPUT);
analogWrite(FanPin, FanSpeed);
pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
pixels.show();
StripUpdate();
}

BLYNK_READ(V0)
{
Blynk.virtualWrite(V0, Pow);
}

BLYNK_WRITE(V1)
{
Pow = param.asInt();
if (Pow > NUMPIXELS) Pow = NUMPIXELS;
else if (Pow < 1) Pow = 1;
StripUpdate();
}

BLYNK_WRITE(V2)
{
Ionithation = param.asInt();
digitalWrite(IonPin, Ionithation);
StripUpdate();
}

void loop()
{
Blynk.run();
// You can inject your own code or combine it with other sketches.
// Check other examples on how to communicate with Blynk. Remember
// to avoid delay() function!

encoder();
button();
}

void button(){
if (!digitalRead(Button)){
Ionithation = !Ionithation;
StripUpdate();
Blynk.virtualWrite(V2, Ionithation);
delay(300);
}
}

void encoder(){
encoder_A = digitalRead(pin_A); // считываем состояние выхода А энкодера
encoder_B = digitalRead(pin_B); // считываем состояние выхода B энкодера
if((!encoder_A) && (encoder_A_prev)){ // если состояние изменилось с положительного к нулю
if(encoder_B) {
if (Pow<NUMPIXELS){
Pow++;
}else{
Pow = NUMPIXELS;
}
StripUpdate();
}
else {
if (Pow > 1){
Pow--;
}else{
Pow=1;
}
StripUpdate();
}
}
else if((!encoder_B) && (encoder_B_prev)){ // если состояние изменилось с положительного к нулю
if(!encoder_A) {
if (Pow<NUMPIXELS){
Pow++;
}else{
Pow = NUMPIXELS;
}
StripUpdate();
}
else {
if (Pow > 1){
Pow--;
}else{
Pow=1;
}
StripUpdate();
}
}
encoder_A_prev = encoder_A; // сохраняем значение А для следующего цикла
encoder_B_prev = encoder_B;
}

void StripUpdate()
{
FanSpeed = map(Pow, 1, NUMPIXELS, 50, 1023);
analogWrite(FanPin, FanSpeed);
if (Ionithation) {
digitalWrite(IonPin, HIGH);
for(int i=0; i<Pow; i++) {
pixels.setPixelColor(i, pixels.Color(40, 20, 0));
pixels.show();
}
}else{
digitalWrite(IonPin, LOW);
for(int i=0; i<Pow; i++) { // For each pixel...
pixels.setPixelColor(i, pixels.Color(0, 0, 80));
pixels.show();
}
}
if (Pow < NUMPIXELS){
for(int i=Pow; i<NUMPIXELS; i++) { // For each pixel...
pixels.setPixelColor(i, pixels.Color(0, 80, 0));
pixels.show();
}
}

delay(30);
}
Последняя функция StripUpdate() отвечает за формирование цвета на ленте. Переменная Pow содержит текущий уровень шкалы по количеству светодиодов (1-16). NUMPIXELS - максимальный уровень (количество светодиодов, в данном случае - 16).
Суть функции закрашивать Pow количество светодиодов синим (или желтым), а дальше до конца зеленым цветами. Выглядеть это должно быть так: Допустим Pow = 6, значит первые 6 светодиодов светят синим, а остальные (7-16) зеленым....
Но наблюдаются глюки. То цвет не тот, то вместо 16 светит 18 (и более) светодиодов, то вся лента нормально светит, правильно, а один светодиод горит не тем цветом, голубым, или розовам, или вообще красным, в общем совсе не того цвета. Пробовал убирать pixels.show();, и ставить его только в самом конце - это ни на что не влияет.
При этом обычные примеры из NeoPixel работают без проблем и без глюков.
Что можете посоветовать? Что я сделал не так, где ошибся?

Добавлено after 1 hour 14 minutes 23 seconds:
Попробовал тестовый скетч:
Спойлер

Код: Выделить всё

#include <Adafruit_NeoPixel.h>

#define LedPIN    13    // Pin D7
                        // On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 16    // Popular NeoPixel ring size

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LedPIN, NEO_GRB + NEO_KHZ800);
int Pow = 0;
bool Ionithation = false;
void setup() {
    pixels.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
    pixels.show();  
    StripUpdate();

}

void loop() {
    for (Pow = 1; Pow<17; Pow ++)
    {
        StripUpdate();
        delay(400);
    }
    Ionithation = !Ionithation;
}

void StripUpdate()
{
    if (Ionithation) {
        for(int i=0; i<Pow; i++) {
            pixels.setPixelColor(i, pixels.Color(40, 20, 0));
            //pixels.show();
        }
    }else{
        for(int i=0; i<Pow; i++) { // For each pixel...
            pixels.setPixelColor(i, pixels.Color(0, 0, 80));
            //pixels.show();
        }
    }
    if (Pow < 16){
        for(int i=Pow; i<16; i++) { // For each pixel...
            pixels.setPixelColor(i, pixels.Color(0, 80, 0));
            //pixels.show();
        }
    }
    pixels.show();
    delay(30);
}
И... все работает! Значит проблема не в том как написана функция StripUpdate(). Что-то другое нарушает работу NeoPixel. Есть идеи?
Сделать своими руками всегда интересней чем просто купить и пользоваться
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15600
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

На адурине ws2812 пока не запускал - была только проба под ассемблером для тиньки45й...
Уж больно жесткий к дрыголапу протокол.
:(
Как предположения...
Попробовать сделать тест-прогу для "стандартной нанки" - может с реализацией под Еsp8266 сложности...
Или поварьировать со скоростью в параметрах...
:roll:
:dont_know:
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Попробуйте в функции StripUpdate() запретить прерывание, при входе запретить, при выходе разрешить.
Вымогатель припоя
Сообщения: 546
Зарегистрирован: Вс дек 30, 2012 00:32:06
Откуда: Николаев / Украина

Сообщение forfrends »

Все оказалось гораздо проще... все дело в невнимательности. В коде я назначил выходы на ленту и ШИМа на один и тот же пин:
...
#define LedPIN 13 // Pin D7
// On Trinket or Gemma, suggest changing this to 1
#define NUMPIXELS 16 // Popular NeoPixel ring size
#define FanPin 13 // D7
...

Переназначил выводы и глюк пропал.
Сделать своими руками всегда интересней чем просто купить и пользоваться
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Ответить

Вернуться в «AVR»