psieg / Lightpack

Lightpack and Prismatik open repository
GNU General Public License v3.0
1.59k stars 190 forks source link

WS2812B working but not with Prismatik #300

Open keichitokuna opened 4 years ago

keichitokuna commented 4 years ago

Hello everyone,

I discover this fork of Prismatik a few days ago and build a working system with WS2812B (60 leds/m) on macOS.

Then, i decided to buy the same leds but with 144 leds/m, install everything and then... Prismatik isn't working anymore with the 266 LEDs setup.

I use an Arduino Nano with this code :

/*
 * Arduino interface for the use of WS2812 strip LEDs
 * Uses Adalight protocol and is compatible with Boblight, Prismatik etc...
 * "Magic Word" for synchronisation is 'Ada' followed by LED High, Low and Checksum
 * @author: Wifsimster <wifsimster@gmail.com> 
 * @library: FastLED v3.001
 * @date: 11/22/2015
 */
#include "FastLED.h"
#define NUM_LEDS 266
#define DATA_PIN 7

// Baudrate, higher rate allows faster refresh rate and more LEDs (defined in /etc/boblight.conf)
#define serialRate 115200

// Adalight sends a "Magic Word" (defined in /etc/boblight.conf) before sending the pixel data
uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, chk, i;

// Initialise LED-array
CRGB leds[NUM_LEDS];

void setup() {
  // Use NEOPIXEL to keep true colors
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  // Initial RGB flash
  LEDS.showColor(CRGB(255, 0, 0));
  delay(500);
  LEDS.showColor(CRGB(0, 255, 0));
  delay(500);
  LEDS.showColor(CRGB(0, 0, 255));
  delay(500);
  LEDS.showColor(CRGB(0, 0, 0));

  Serial.begin(serialRate);
  // Send "Magic Word" string to host
  Serial.print("Ada\n");
}

void loop() { 
  // Wait for first byte of Magic Word
  for(i = 0; i < sizeof prefix; ++i) {
    waitLoop: while (!Serial.available()) ;;
    // Check next byte in Magic Word
    if(prefix[i] == Serial.read()) continue;
    // otherwise, start over
    i = 0;
    goto waitLoop;
  }

  // Hi, Lo, Checksum  
  while (!Serial.available()) ;;
  hi=Serial.read();
  while (!Serial.available()) ;;
  lo=Serial.read();
  while (!Serial.available()) ;;
  chk=Serial.read();

  // If checksum does not match go back to wait
  if (chk != (hi ^ lo ^ 0x55)) {
    i=0;
    goto waitLoop;
  }

  memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
  // Read the transmission data and set LED values
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    byte r, g, b;    
    while(!Serial.available());
    r = Serial.read();
    while(!Serial.available());
    g = Serial.read();
    while(!Serial.available());
    b = Serial.read();
    leds[i].r = r;
    leds[i].g = g;
    leds[i].b = b;
  }

  // Shows new values
  FastLED.show();
}

The LEDs flash three time on startup, but, even with the good config in Prismatik, nothing happen.

If i upload a test sketch (like turn on white all the LEDs), it is working... but clearly, Prismatik didn't seems to like them.

Is there anyway i can debug that ? I really don't understand the log file, and as it was working with previous LEDs, i don't understand where the issue is...

With this code (https://github.com/psieg/Lightpack/issues/191), LEDs are working, but not really great. I read that the limit of 255 LEDs are down, but with "NUM_LEDS 254" in my previous code, Prismatik is working.... So, i think my issue remain.

Thanks !

K.

zomfg commented 4 years ago

which device did you select in Prismatik?

zomfg commented 4 years ago

oh, also, this

 for (uint8_t i = 0; i < NUM_LEDS; i++) {

should be uint16_t

keichitokuna commented 4 years ago

oh, also, this

 for (uint8_t i = 0; i < NUM_LEDS; i++) {

should be uint16_t

Hello,

Thanks for the reply. I guess it should be my error here.

I had some lag issue with 266 LEDs, so i remove everything and put my last build instead (118 LEDs, working great at 30ms interval 115200 baud). Even Try Hyperion with ESP8266 but with no luck as i am on macOS...

Still have some issue with Prismatik (not restarting after computer go to sleep) and Sound Visualization not working anymore (was working before...) but i guess, i will stop here. Spend too much time on it.

Thanks to all developers, i love this work !

K.

zomfg commented 4 years ago

115200 is not enough, hence the lag, read this

I'd like you to detail more your other issues:

keichitokuna commented 4 years ago

Hello,

So, here my actual working code :

/*
 * Arduino interface for the use of WS2812 strip LEDs
 * Uses Adalight protocol and is compatible with Boblight, Prismatik etc...
 * "Magic Word" for synchronisation is 'Ada' followed by LED High, Low and Checksum
 * @author: Wifsimster <wifsimster@gmail.com> 
 * @library: FastLED v3.001
 * @date: 11/22/2015
 */
#include "FastLED.h"
#define NUM_LEDS 114
#define DATA_PIN 7

// Baudrate, higher rate allows faster refresh rate and more LEDs (defined in /etc/boblight.conf)
#define serialRate 115200

// Adalight sends a "Magic Word" (defined in /etc/boblight.conf) before sending the pixel data
uint8_t prefix[] = {'A', 'd', 'a'}, hi, lo, chk, i;

// Initialise LED-array
CRGB leds[NUM_LEDS];

void setup() {
  // Use NEOPIXEL to keep true colors
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);

  // Initial RGB flash
  LEDS.showColor(CRGB(255, 0, 0));
  delay(500);
  LEDS.showColor(CRGB(0, 255, 0));
  delay(500);
  LEDS.showColor(CRGB(0, 0, 255));
  delay(500);
  LEDS.showColor(CRGB(0, 0, 0));

  Serial.begin(serialRate);
  // Send "Magic Word" string to host
  Serial.print("Ada\n");
}

void loop() { 
  // Wait for first byte of Magic Word
  for(i = 0; i < sizeof prefix; ++i) {
    waitLoop: while (!Serial.available()) ;;
    // Check next byte in Magic Word
    if(prefix[i] == Serial.read()) continue;
    // otherwise, start over
    i = 0;
    goto waitLoop;
  }

  // Hi, Lo, Checksum  
  while (!Serial.available()) ;;
  hi=Serial.read();
  while (!Serial.available()) ;;
  lo=Serial.read();
  while (!Serial.available()) ;;
  chk=Serial.read();

  // If checksum does not match go back to wait
  if (chk != (hi ^ lo ^ 0x55)) {
    i=0;
    goto waitLoop;
  }

  memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
  // Read the transmission data and set LED values
  for (uint8_t i = 0; i < NUM_LEDS; i++) {
    byte r, g, b;    
    while(!Serial.available());
    r = Serial.read();
    while(!Serial.available());
    g = Serial.read();
    while(!Serial.available());
    b = Serial.read();
    leds[i].r = r;
    leds[i].g = g;
    leds[i].b = b;
  }

  // Shows new values
  FastLED.show();
}

If i put the baud rate to 256 000 in both code and Prismatik, here the log :

// Baudrate, higher rate allows faster refresh rate and more LEDs (defined in /etc/boblight.conf)
#define serialRate 256000
12:24:27:770 Debug: virtual void LedDeviceAdalight::open() Serial device "cu.wchusbserial14540" open
12:24:27:770 Warning: virtual void LedDeviceAdalight::open() Set data bits 8 fail
12:24:27:770 Debug: void LedDeviceManager::triggerRecreateLedDevice() Will try to recreate device in 1000 msec
12:24:27:770 Debug: void SettingsWindow::ledDeviceOpenSuccess(bool) false
12:24:27:770 Debug: void SettingsWindow::ledDeviceCallSuccess(bool) Backlight::StatusDeviceError
12:24:28:767 Debug: void LedDeviceManager::recreateLedDevice()
12:24:28:767 Warning: QObject::disconnect: No such slot LedDeviceAdalight::ledDeviceUpdateWBAdjustments()
12:24:28:767 Debug: void LedDeviceManager::initLedDevice()
12:24:28:767 Warning: QObject::disconnect: No such slot LedDeviceAdalight::ledDeviceUpdateWBAdjustments()
12:24:28:768 Debug: virtual void LedDeviceAdalight::updateDeviceSettings()
12:24:28:769 Debug: virtual void LedDeviceAdalight::setColorSequence(QString) "RGB"
12:24:28:769 Debug: virtual void LedDeviceAdalight::open() LedDeviceManager(0x7f85d3f71b50)

(and the leds flash red / green / blue in a loop)

Using

  for (uint16_t i = 0; i < NUM_LEDS; i++) {

Works with baud rate 115200 but no with 256000

Thanks !!

K.

zomfg commented 4 years ago
keichitokuna commented 4 years ago

Hello,

1/ I edit

for (uint16_t i = 0; i < NUM_LEDS; i++) {

And it is working.

2/ When i set baud rate to 500 000, i have a forbidden sign for the icon of Prismatik saying "Error with connection device, verbose in logs : https://pasteboard.co/ITNERk2.png (screenshot) https://pasteboard.co/ITNFbzr.png (screenshot)

And the full log when i start Prismatik already configure to 500000 and arduino too. Log file

3/ I set up log level to 3. Here is the log when the screen goes to sleep : Log file

4/ Thanks, uncheck/check again did the work !

zomfg commented 4 years ago
  1. Good news: I have same issue with my Nano on macOS. Bad news: it might be a driver issue. The serial seems way less lenient than the Windows one. On Windows same setup works perfectly well with different baudrates (even non-standard ones). On Mac it looks like there are errors with anything above 230400. You could try a different board (with a different serial chip), baudrates from the datasheet (I had success with 230400, at 460800 it connects fine but the Nano does nothing...). I don't think it's Prismatik. As a consolation (at least for now) you could use your 266 led strip but make it 2 leds per "pixel" in your sketch (and set prismatik to 133leds)

  2. nothing new yet. By screen you mean just the screen, not the full on sleep/hibernation mode?

keichitokuna commented 4 years ago

Hello,

  1. I tried 128000 and 153600 and have the same "Error with connection device, verbose in logs" issue. With 230400, it seems good but the LEDs stay off. Pretty strange.

As i currently use my old 114 LEDs setup, Prismatik seems to work with a grab interval of 30ms (33 FPS) which seems good to me. So, i guess i will stick that way. I will use the two 144 leds/m strips for another project, no problem.

One strange thing is that, i use this small script :

void setup(){};

void loop()
{

  delay(1000);
  Serial.begin(57600);
  Serial.println("\r\rBaud-rate = 57600");
  delay(1000);
  Serial.begin(76800);
  Serial.println("\r\rBaud-rate = 76800");
  delay(1000);
  Serial.begin(115200);
  Serial.println("\r\rBaud-rate = 115200");
  delay(1000);
  Serial.begin(128000);
  Serial.println("\r\rBaud-rate = 128000");
  delay(1000);
  Serial.begin(153600);
  Serial.println("\r\rBaud-rate = 153600");
  delay(1000);
  Serial.begin(230400);
  Serial.println("\r\rBaud-rate = 230400");
  delay(1000);
  Serial.begin(250000);
  Serial.println("\r\rBaud-rate = 250000");
  delay(1000);
  Serial.begin(256000);
  Serial.println("\r\rBaud-rate = 256000");
  delay(1000);
  Serial.begin(460800);
  Serial.println("\r\rBaud-rate = 460800");
  delay(1000);
  Serial.begin(500000);
  Serial.println("\r\rBaud-rate = 500000");
  delay(1000);
  Serial.begin(1000000);
  Serial.println("\r\rBaud-rate = 1000000");
  delay(1000);
  Serial.begin(2000000);
  Serial.println("\r\rBaud-rate = 2000000");
};

And in the monitor configured in the right way, i can totally read the high baudrate text (up to 2M).

  1. In fact, my MacBook is connected to two USB hubs receiving :
    • HUB 1 : power from USB-C port, HDMI FullHD screen 1, SD card reader.
    • HUB 2 : ethernet port (NAS), HDMI FullHD screen 2, Arduino nano board

My Arduino is powered by the USB hub, and i use an external power source, to power the LED strip (ground is share between arduino and led strip).

When i want to cut all the lights, i just turn off both monitors and then use the "Sleep Display" function of macOS, and in Energy saving, i deactivate the deep sleep function. So, by screen, it is really only the screen, yes.

Another bonus question : In Prismatik, you can configure multiple "Profiles" (i use one for sound viz and another for screen grabing), but did it take in account the Device setting ?

Because i would like to have these two profiles and another one for "movie with black bars" with grabbing area slighty diferent.

Thanks again for your time zomfg !

zomfg commented 4 years ago
  1. yes but now send lots of data, fast I tested few things in the sketch and @460800, it never goes past prefix check If I skip prefix check, it kinda works, but with lots of artefacts

  2. what do you mean by turn of monitors and then use sleep? you press their power button?

bonus: look in ~/.Prismatik, you'll know what setting goes where

keichitokuna commented 4 years ago
1. yes but now send lots of data, fast
   I tested few things in the sketch and @460800, it never goes past prefix check
   If I skip prefix check, it kinda works, but with lots of artefacts

Indeed, i was not thinking of that.

2. what do you mean by turn of monitors and then use sleep? you press their power button?

I power off the external monitors then put the macbook to sleep. But i can do the otherway, just an habit.

bonus: look in ~/.Prismatik, you'll know what setting goes where

It is like my second home right now, effectively, found the answer, thanks :)

zomfg commented 4 years ago

are hubs and the board powered when you put MacBook to sleep?

keichitokuna commented 4 years ago

Yes, the hubs & arduino is still powered.