Проблемы с Ambilight

CARLOS
CARLOS аватар
Offline
Зарегистрирован: 09.11.2016

Всем доброго времени суток!

Решил собрать фоновую подсветку на WS2812b / ARDUINO UNO по примеру https://mysku.ru/blog/aliexpress/28820.html Запитал ленту от компьютерного БП (5В), ардуино от USB компьютера.

Скетч по комментам рабочий

// Slightly modified Adalight protocol implementation that uses FastLED
// library (http://fastled.io) for driving WS2811/WS2812 led stripe
// Was tested only with Prismatik software from Lightpack project
 
#include "FastLED.h"
 
#define NUM_LEDS 116 // Max LED count
#define LED_PIN 6 // arduino output pin
#define GROUND_PIN 10
#define BRIGHTNESS 255 // maximum brightness
#define SPEED 115200 // virtual serial port speed, must be the same in boblight_config 
 
CRGB leds[NUM_LEDS];
uint8_t * ledsRaw = (uint8_t *)leds;
 
// A 'magic word' (along with LED count & checksum) precedes each block
// of LED data; this assists the microcontroller in syncing up with the
// host-side software and properly issuing the latch (host I/O is
// likely buffered, making usleep() unreliable for latch).  You may see
// an initial glitchy frame or two until the two come into alignment.
// The magic word can be whatever sequence you like, but each character
// should be unique, and frequent pixel values like 0 and 255 are
// avoided -- fewer false positives.  The host software will need to
// generate a compatible header: immediately following the magic word
// are three bytes: a 16-bit count of the number of LEDs (high byte
// first) followed by a simple checksum value (high byte XOR low byte
// XOR 0x55).  LED data follows, 3 bytes per LED, in order R, G, B,
// where 0 = off and 255 = max brightness.
 
static const uint8_t magic[] = {
  'A','d','a'};
#define MAGICSIZE  sizeof(magic)
#define HEADERSIZE (MAGICSIZE + 3)
 
#define MODE_HEADER 0
#define MODE_DATA   2
 
// If no serial data is received for a while, the LEDs are shut off
// automatically.  This avoids the annoying "stuck pixel" look when
// quitting LED display programs on the host computer.
static const unsigned long serialTimeout = 150000; // 150 seconds
 
void setup()
{
  pinMode(GROUND_PIN, OUTPUT); 
  digitalWrite(GROUND_PIN, LOW);
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
 
  // Dirty trick: the circular buffer for serial data is 256 bytes,
  // and the "in" and "out" indices are unsigned 8-bit types -- this
  // much simplifies the cases where in/out need to "wrap around" the
  // beginning/end of the buffer.  Otherwise there'd be a ton of bit-
  // masking and/or conditional code every time one of these indices
  // needs to change, slowing things down tremendously.
  uint8_t
    buffer[256],
  indexIn       = 0,
  indexOut      = 0,
  mode          = MODE_HEADER,
  hi, lo, chk, i, spiFlag;
  int16_t
    bytesBuffered = 0,
  hold          = 0,
  c;
  int32_t
    bytesRemaining;
  unsigned long
    startTime,
  lastByteTime,
  lastAckTime,
  t;
  int32_t outPos = 0;
 
  Serial.begin(SPEED); // Teensy/32u4 disregards baud rate; is OK!
 
  Serial.print("Ada\n"); // Send ACK string to host
 
    startTime    = micros();
  lastByteTime = lastAckTime = millis();
 
  // loop() is avoided as even that small bit of function overhead
  // has a measurable impact on this code's overall throughput.
 
  for(;;) {
 
    // Implementation is a simple finite-state machine.
    // Regardless of mode, check for serial input each time:
    t = millis();
    if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) {
      buffer[indexIn++] = c;
      bytesBuffered++;
      lastByteTime = lastAckTime = t; // Reset timeout counters
    } 
    else {
      // No data received.  If this persists, send an ACK packet
      // to host once every second to alert it to our presence.
      if((t - lastAckTime) > 1000) {
        Serial.print("Ada\n"); // Send ACK string to host
        lastAckTime = t; // Reset counter
      }
      // If no data received for an extended time, turn off all LEDs.
      if((t - lastByteTime) > serialTimeout) {
        memset(leds, 0,  NUM_LEDS * sizeof(struct CRGB)); //filling Led array by zeroes
        FastLED.show();
        lastByteTime = t; // Reset counter
      }
    }
 
    switch(mode) {
 
    case MODE_HEADER:
 
      // In header-seeking mode.  Is there enough data to check?
      if(bytesBuffered >= HEADERSIZE) {
        // Indeed.  Check for a 'magic word' match.
        for(i=0; (i<MAGICSIZE) && (buffer[indexOut++] == magic[i++]););
        if(i == MAGICSIZE) {
          // Magic word matches.  Now how about the checksum?
          hi  = buffer[indexOut++];
          lo  = buffer[indexOut++];
          chk = buffer[indexOut++];
          if(chk == (hi ^ lo ^ 0x55)) {
            // Checksum looks valid.  Get 16-bit LED count, add 1
            // (# LEDs is always > 0) and multiply by 3 for R,G,B.
            bytesRemaining = 3L * (256L * (long)hi + (long)lo + 1L);
            bytesBuffered -= 3;
            outPos = 0;
            memset(leds, 0,  NUM_LEDS * sizeof(struct CRGB));
            mode           = MODE_DATA; // Proceed to latch wait mode
          } 
          else {
            // Checksum didn't match; search resumes after magic word.
            indexOut  -= 3; // Rewind
          }
        } // else no header match.  Resume at first mismatched byte.
        bytesBuffered -= i;
      }
      break;
 
    case MODE_DATA:
 
      if(bytesRemaining > 0) {
        if(bytesBuffered > 0) {
          if (outPos < sizeof(leds))
            ledsRaw[outPos++] = buffer[indexOut++];   // Issue next byte
          bytesBuffered--;
          bytesRemaining--;
        }
        // If serial buffer is threatening to underrun, start
        // introducing progressively longer pauses to allow more
        // data to arrive (up to a point).
      } 
      else {
        // End of data -- issue latch:
        startTime  = micros();
        mode       = MODE_HEADER; // Begin next header search
        FastLED.show();
      }
    } // end switch
  } // end for(;;)
}
 
void loop()
{
  // Not used.  See note in setup() function.
}

Настроил AMBIBOX по зонам в соответствии с моим расположением отдельных светодиодов (116 шт), задал направление данных - запустил подсветку. https://cloud.mail.ru/public/KyAV/nhRLBoy5U - светодиоды горят произвольным цветом в хаотичном порядке, однако реакция на перемещающееся окно на мониторе есть. При этом, ленту запитал в 5 точках - https://cloud.mail.ru/public/LKt5/3rAhkxadi, напряжение в районе 5,2В. 

Прогрузил пример DemoREEL100 из библиотеки FASTled - лента идеально работает по всей её длине, значит дело не в железе.

Думал на длиный USB провод от ПК до ардуины - поставил "родной" короткий - проблема не решилась.

Пробовал другой скетч из этого же форума - ситуация такая же.

При любых настройках Ambibox (изменения стилей / порядка RGB и т д / МОНОПОДСВЕТКИ - СВЕТОДИОДЫ ГОРЯТ ТАКЖЕ ХАОТИЧНО В ХАОТИЧНОМ ПОРЯДКЕ) ситуация такая же, использовал ПО Prizmatic - ситуация такая же....

Быть может кто и сталкивался.....Заранее спасибо

 

 

b707
Offline
Зарегистрирован: 26.05.2017

ну если лента в тестовом режиме работает, а с этим скетчем - нет, значит дело в скетче. Раз у других людей он работает - значит вы в нем что-то меняли, и, судя по результату - неудачно.

признавайтесь.

CARLOS
CARLOS аватар
Offline
Зарегистрирован: 09.11.2016

b707 пишет:

ну если лента в тестовом режиме работает, а с этим скетчем - нет, значит дело в скетче. Раз у других людей он работает - значит вы в нем что-то меняли, и, судя по результату - неудачно.

признавайтесь.

 

Менял....количество пикселей....строка 007

v00d00m4n
Offline
Зарегистрирован: 23.01.2019

Возможно я поздно - но у меня была такая же проблема с китайскими друинами с дешевым усб контроллером и с китайскими лентами.

Проблемла решилась установкой скорости serial com port на 500000 как в счетке так и в софте (при 115 были жуткие лаги вывода цвета и периодически вообще не выводило), и заодно исправлением установки ленты 

astLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);

на

astLED.addLeds<WS2812, LED_PIN, GRB>(leds, NUM_LEDS);

по какой-то непонятной мне причине или китайские ленты не совсем ws2812b как заявлено или это какой-то баг в фастлед библиотеке, но нормально работает только если указывать ws2812.