hyperion-project / hyperion.ng

The successor to Hyperion aka Hyperion Next Generation
https://hyperion-project.org/
MIT License
3.04k stars 377 forks source link

No LED output with adalight #197

Closed Paulchen-Panther closed 8 years ago

Paulchen-Panther commented 8 years ago

@redPanther

Ich hab mal wieder seit langen mein Ambilight in der Wohnstube eingeschaltet und auf meiner chromebox hyperion auf hyperion.ng geupdatet. Was soll ich sagen. es funktioniert nicht. Keine LED Ausgabe. In der debug ausgabe von hyperion, nicht außergewöhnliches. Daten werden angeblich geschrieben. Es bleibt alles dunkel. Bevor ich jetzt alles neu aufsetze, wollte ich dich fragen nach was ich als erstes bei der RS232 Device Class schauen kann. Und wie teste ich ob die QTSerial ausgabe überhaupt auf diesem system funktioniert? Mit dem alten hat es ja geklappt. Danke für deine Hilfe.

PP

redPanther commented 8 years ago

von wann ist dein checkout? ist da mein leddevice rework2 schon drin?

adalaight hatte ich damals bei der rs232 umstellung getestet und hat auch gefunzt.

Paulchen-Panther commented 8 years ago

hab ich gerade frisch kompiliert. sollte also aktuell sein

edit: benutze gerade qt 5.7.

redPanther commented 8 years ago

im debug start sollten viele ausgaben kommen: Debug(_log, "write %d ", result); weiterhin sollten die leds deines arduino blinken - dann weißt du das daten ankommen.

Paulchen-Panther commented 8 years ago

Da kommen auch viele Ausgaben. Leider hab ich einen Teensy mit octo Adapter. Da gibts keine onboard LEDs. Und der teensy sitzt hinter der Leinwand. Was könnte ich noch probieren?

redPanther commented 8 years ago

Hast du nen usb zu rs232 adapter? Den einfach anklemmen ... bin jetzt leider bis sonntag unterwegs.

Paulchen-Panther commented 8 years ago

Leider besitze ich so einen Adapter nicht.

tpmodding commented 8 years ago

Wer Hardware brauch einfach mal mich im Forum anschreiben... :-)

Paulchen-Panther commented 8 years ago

Danke @tpmodding. Ich schau mal was sich noch machen lässt. Könnte mir vielleicht jemand die fertigen binarys mit dependencys von Hyperion.ng zur Verfügung stellen?

oCanna commented 8 years ago

@Paulchen-Panther Auch der Teensy hat eine Led onboard. Zumindest bei meinem 3.2 ist das der Fall. Bei mir wird diese z.B. für USB DTR genutzt.

Rein aus Interesse. Wie schaut dein code auf dem teensy aus?

Paulchen-Panther commented 8 years ago

define USE_OCTOWS2811

include

include

// Led strip lengths, (0 if there is no strip):

define STRIP_1 123

define STRIP_2 69

define STRIP_3 123

define STRIP_4 69

define STRIP_5 0

define STRIP_6 0

define STRIP_7 0

define STRIP_8 0

// DEFINITIONS

define STARTCOLOR 0x000000 // LED colors at start

define NUM_STRIPS 8

define LEDS_PER_STRIP 123

define LEDCOUNT STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6 + STRIP_7 + STRIP_8 // Number of LEDs used for boblight

define BAUDRATE 115200 // Serial port speed

define CALIBRATION_TEMPERATURE TypicalLEDStrip // Color correction

define MAX_BRIGHTNESS 250 // 0-255

CRGB leds[NUM_STRIPS * LEDS_PER_STRIP];

const char prefix[] = {0x41, 0x64, 0x61, 0x01, 0x7F, 0x2B}; // Start prefix

// Bytes 0-2 are the magic word "Ada". // Bytes 3 and 4 are the high byte and low byte of the 16-bit LED count. // Boblight counts diodes from 1 and Hyperion from 0 // for Boblight from 1 to 25 for 25 LEDs, or 0x0019 hexadecimal, // for Hyperion from 0 to 24 for 25 LEDs, or 0x0018 hexadecimal. // The checksum equals the high byte XOR the low byte XOR 0x55 // In the 25 LED case again, this would be 0x4D. For 50 LEDs, it would be 0x64.

// 0x41 = 'A' // 0x64 = 'd' // 0x61 = 'a' // 0x01 and 0x7F = Hex Value 0x017F = Decimal Value 383 LEDs // 0x2B = 0x01 XOR 0x7F XOR 0x55

char buffer[sizeof(prefix)]; // Temp buffer for receiving prefix data

int state; // Define current state

define STATE_WAITING 1 // - Waiting for prefix

define STATE_DO_PREFIX 2 // - Processing prefix

define STATE_DO_DATA 3 // - Handling incoming LED colors

int readSerial; // Read Serial data (1) int currentLED; // Needed for assigning the color to the right LED

void setup() { LEDS.addLeds(leds, LEDS_PER_STRIP);

LEDS.setTemperature( CALIBRATION_TEMPERATURE ); LEDS.setBrightness( MAX_BRIGHTNESS );

setAllLEDs(STARTCOLOR); //Rot

Serial.begin(BAUDRATE); // Init serial speed

state = STATE_WAITING; // Initial state: Waiting for prefix }

void loop() {

switch(state) { case STATE_WAITING: // * Waiting for prefix * if( Serial.available()>0 ) { readSerial = Serial.read(); // Read one character

    if ( readSerial == prefix[0] )   // if this character is 1st prefix char
      { state = STATE_DO_PREFIX; }   // then set state to handle prefix
  }
  break;

case STATE_DO_PREFIX:                // *** Processing Prefix ***
  if( Serial.available() > sizeof(prefix) - 2 ) 
  {
      Serial.readBytes(buffer, sizeof(prefix) - 1);

      for( int Counter = 0; Counter < sizeof(prefix) - 1; Counter++) 
      {
        if( buffer[Counter] == prefix[Counter+1] ) 
        {
          state = STATE_DO_DATA;     // Received character is in prefix, continue
          currentLED = 0;            // Set current LED to the first one
        }
        else 
        {
          state = STATE_WAITING;     // Crap, one of the received chars is NOT in the prefix
          break;                     // Exit, to go back to waiting for the prefix
        } // end if buffer
      } // end for Counter
  } // end if Serial
  break;

case STATE_DO_DATA:                  // *** Process incoming color data ***
  if( Serial.available() > 2 )       // if we receive more than 2 chars
  {
    Serial.readBytes( buffer, 3 );   // Abuse buffer to temp store 3 charaters        
    leds[t3convert(currentLED)].setRGB(buffer[0], buffer[1], buffer[2]);
    currentLED++;        
  }

  if( currentLED >= LEDCOUNT )      // Reached the last LED? Display it!
  {
      LEDS.show();                  // Make colors visible
      state = STATE_WAITING;         // Reset to waiting ...
      currentLED = 0;                // and go to LED one          
      break;                         // and exit ... and do it all over again
  }
  break; 

} // switch(state)

} // loop

void setAllLEDs(CRGB color) { for(int i = 0; i <= NUM_STRIPS * LEDS_PER_STRIP; i++) { leds[i] = color; }

LEDS.show(); // Show all LEDs }

uint16_t t3convert(uint16_t i){ if(i >= 0 && i < STRIP_1) return i; if(i >= STRIP_1 && i < STRIP_1 + STRIP_2) return i + (LEDS_PER_STRIP-STRIP_1); if(i >= STRIP_1 + STRIP_2 && i < STRIP_1 + STRIP_2 + STRIP_3) return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2); if(i >= STRIP_1 + STRIP_2 + STRIP_3 && i < STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4) return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2) + (LEDS_PER_STRIP-STRIP_3); if(i >= STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 && i < STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5){ return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2) + (LEDS_PER_STRIP-STRIP_3) + (LEDS_PER_STRIP-STRIP_4); } if(i >= STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 && i < STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6){ return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2) + (LEDS_PER_STRIP-STRIP_3) + (LEDS_PER_STRIP-STRIP_4) + (LEDS_PER_STRIP-STRIP_5); } if(i >= STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6 && i < STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6 + STRIP_7){ return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2) + (LEDS_PER_STRIP-STRIP_3) + (LEDS_PER_STRIP-STRIP_4) + (LEDS_PER_STRIP-STRIP_5) + (LEDS_PER_STRIP-STRIP_6); } if(i >= STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6 + STRIP_7 && i < STRIP_1 + STRIP_2 + STRIP_3 + STRIP_4 + STRIP_5 + STRIP_6 + STRIP_7 + STRIP_8){ return i + (LEDS_PER_STRIP-STRIP_1) + (LEDS_PER_STRIP-STRIP_2) + (LEDS_PER_STRIP-STRIP_3) + (LEDS_PER_STRIP-STRIP_4) + (LEDS_PER_STRIP-STRIP_5) + (LEDS_PER_STRIP-STRIP_6) + (LEDS_PER_STRIP-STRIP_7); } }

oCanna commented 8 years ago

Ich habe das bei mir etwas anders gelöst:

#define USE_OCTOWS2811
#include<OctoWS2811.h>
#include<FastLED.h>

/* BEGIN OF USER DEFINED VALUES */

// Number of LEDs of the longest channel (1-255)
#define CHAN_LEN 33

// Number of channels in use (1-8)
#define CHAN_NUM_INUSE 4

//Channel order and length matching the serial data 
const uint8_t 
  chan_order[] = {4,2,3,7}, // Channel order (OctoWS2811 channels 0-7) 
  chan_len[] = {33,19,33,19}; // Number of LEDs per channel in the specified channel order (1-255)

/* END OF USER DEFINED VALUES */

// Number of octows2811 channels (default 8)
// Pin layouts on the teensy 3.x:
// OctoWS2811: 2,14,7,8,6,20,21,5
#define CHAN_NUM 8

const int ledPin = 13;

elapsedMillis lastByteTime;
elapsedMillis lastAckTime;

uint8_t
  state = 0,
  led_on = 0;
uint16_t
  count = 0,
  led_cnt = 0,
  led_sum = 0,
  *led_offset;

unsigned char buf[3];
CRGB leds[CHAN_NUM * CHAN_LEN];

void setup()
{
  uint8_t i, e;

  LEDS.addLeds<OCTOWS2811>(leds, CHAN_LEN);
  //LEDS.setBrightness(100);
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
  Serial.begin(115200);

  for (i=0; i<CHAN_NUM_INUSE; i++){
    led_sum += chan_len[i];
  }

  led_offset = (uint16_t*) calloc(led_sum, sizeof(uint16_t));

  for (i=0; i<CHAN_NUM_INUSE; i++){
    for (e=0; e<chan_len[i]; e++){
      led_offset[count] = CHAN_LEN * chan_order[i] + e;
      count++;
    }
  }

}

void led_off(){
  fill_solid(leds, CHAN_NUM * CHAN_LEN, CRGB::Black);
  LEDS.show();
  led_on = 0;
}

void loop()
{
  if (state == 4) {
    if (Serial.available() < 3) goto wait;  
    Serial.readBytes( (char*)(&leds[(led_offset[count])]), 3);
    count++;
    if (count >= led_cnt) {
      LEDS.show();
      led_on = 1;
      state = 0;
    }

  } else if (state == 0) {
    if (Serial.available() == 0) goto wait;
    state = (Serial.read() == 'A') ? 1 : 0;

  } else if (state == 1) {
    if (Serial.available() == 0) goto wait;
    state = (Serial.read() == 'd') ? 2 : 0;

  } else if (state == 2) {
    if (Serial.available() == 0) goto wait;
    state = (Serial.read() == 'a') ? 3 : 0;

  } else if (state == 3) {
    if (Serial.available() < 3) goto wait;
    Serial.readBytes((char *)buf, 3);
    if ((buf[0] ^ buf[1] ^ 0x55) == buf[2]) {
      led_cnt = buf[0] * 256 + buf[1] + 1;
      if (led_cnt > led_sum) led_cnt = led_sum;
      state = 4;
      count = 0;
    } else if (buf[0] == 'A' && buf[1] == 'd' && buf[2] == 'a') {
      state = 3;
    } else if (buf[1] == 'A' && buf[2] == 'd') {
      state = 2;
    } else if (buf[2] == 'A') {
      state = 1;
    } else {
      state = 0;
    }

  } else {
wait:
    if (!Serial.dtr()) {
      digitalWrite(ledPin, LOW);
      led_off();
      while (!Serial.dtr()) ;
      delay(20);
      digitalWrite(ledPin, HIGH);   
      Serial.print("Ada\n");
      lastByteTime = 0;
      lastAckTime = 0;
      state = 0;
      return;
    }
    if (lastAckTime > 1000) {
      lastAckTime = 0;
      while (Serial.available()) Serial.read();
      Serial.print("Ada\n");
      state = 0;
    }
    if (lastByteTime > 10000) {
      lastByteTime = 0;
      if (led_on) led_off();
    }
    return;
  }

  lastAckTime = 0;
  lastByteTime = 0;   

}
Paulchen-Panther commented 8 years ago

Ich schau mir das morgen mal an. Muss erst mal ein wenig schlafen. Arbeit wartet wieder morgen auf mich. Hier noch mal die komplette Datei übersichtlicher: https://gist.github.com/Paulchen-Panther/07da7ada32977b3fe6dfef0000ccbb38

Paulchen-Panther commented 8 years ago

So Jungs und Mädels. Hab den Fehler am Wochenende ausmachen können. Der Fehler liegt mal wieder im Detail. Meine verwendete config basierte auf der default config. Hab halt nur das led array aus der alten kopiert und in die neue eingefügt. So weit so gut. Einen initialEffect wollte ich nicht, hab also wie in der commented config angegeben, den BackgroundEffect und den ForgroundEffect entfernt und nur die Anführungszeichen stehen lassen. Und genau da liegt das Problem. Der FrameGrabber springt nicht an. Entferne ich die komplette initialEffect section, funktioniert wieder alles.

brindosch commented 8 years ago

Und wenn du einen Effekt einsetzt funktioniert es auch wieder? Wir müssen unter Umständen wegen der json schema -> forms nochmal besprechen wie einheitlich die .json denn jetzt sein soll :)

redPanther commented 8 years ago

Ok aber das läst sich leicht lösen. Es sollte auf jedenfall nicht zu dem problem wie beschrieben führen.

Ich hab auch noch tests gemacht. Hmmm und da scheint dennoch was im rs232 code zu sein. Ich schaffe es halbwegs reproduzierbar zu schaffen, das das flush() nicht zutückkommt. Das kann nen hardware prob sein, oder auch nich. Ich bin drann. Die leds flackern manchmal auch komisch.

redPanther commented 8 years ago

Ggf hängt mein prob, aber auch mit https://hyperion-project.org/threads/hyperiond-unter-debian-linux-l%C3%A4uft-nicht-richtig.285/#post-2654

Zusammen. Nur dort ist alter hyperion code am werk und bei mir neuer ...

brindosch commented 8 years ago

Mal kurz zwischen grätschen, für was benötigt man adalightapa102? Wenn man den sketch benutzt für adalight, kann man doch auch so apa102 nutzen? Bringt das irgendwelche Vorteile? Ist das ein apa102 only sketch? (den wir nicht "anbieten")

Paulchen-Panther commented 8 years ago

@brindosch ja. Wenn ich den backgroundeffect hinzufüge, funktioniert es auch.

Paulchen-Panther commented 8 years ago

@brindosch AdalightAPA102 details stehen im alten hyperion PR. https://github.com/hyperion-project/hyperion/pull/393

brindosch commented 8 years ago

Werde daraus aber auch nicht schlauer, wie schon von nicohood geschrieben, lässt sich alles mit fastled regeln?

Paulchen-Panther commented 8 years ago

Es scheint das dieser PR (sowie der User tociek) ursprünglich von Lightberry stammt. Gehe mal davon aus das Lightberry kein FastLED auf ihren Geräten einsetzt (Copyright etc.) Deshalb dieser PR.

Paulchen-Panther commented 8 years ago

@redPanther Also ich kann mein Szenario gut nach voll ziehen. Einfach den internen framegrabber auf x11 stellen, das device auf file umstellen und wie schon weiter oben beschrieben, den Initileffect weglassen bzw. nur die Anführungszeichen stehen lassen. Es wird keine Ausgabe in die datei geschrieben. Löscht man den initialeffect komplett aus der config raus oder fügt einen effect namen ein funktioniert auch der x11 grabber.

Hier noch mal die config ohne initialeffekt bzw. nur die Anführungszeichen: https://gist.github.com/Paulchen-Panther/9f63ee7e3ee5e6bda012aba68a6749e5

und hier mit: https://gist.github.com/Paulchen-Panther/c1eee39a63f08303a57656309547bf93

Paulchen-Panther commented 8 years ago

Ich denke es liegt an dieser Zeile: https://github.com/hyperion-project/hyperion.ng/blob/master/src/hyperiond/hyperiond.cpp#L189

Diese Zeile verhindert das der interne Grabber überhaupt loslegen kann. Hier noch ein screen von hyperion-remote: http://imgur.com/a/j3JUT

redPanther commented 8 years ago

also foreground effect auf irgendwas setzen was es nicht gibt reicht schon .... Was passiert kann man schön mit hyperion-remote -l sehen:

   "priorities" : [
      {
         "active" : true,
         "owner" : "unknown",
         "priority" : 0,
         "visible" : true
      },
      {
         "active" : true,
         "duration_ms" : 138,
         "owner" : "X11",
         "priority" : 900,
         "visible" : false
      },
      {
         "active" : true,
         "owner" : "EFFECT: /media/lager/home/Entwicklung/hyperion/hyperion.ng4/effects/mood-blobs.py",
         "priority" : 2147483646,
         "visible" : false
      },
      {
         "active" : true,
         "owner" : "Off",
         "priority" : 2147483647,
         "visible" : false
      },
      {
         "active" : false,
         "owner" : "UDPLISTENER",
         "priority" : 700,
         "visible" : false
      }
   ],

Auf prio 0 hängt für unendlich die farbe schwarz (color wird noch nicht vernünftig in dem prio register erfasst ...). Ohne jetzt ganz genau geschaut zu haben wird das von der effect engine der fallback sein, wenn man nen ungültigen effektnamen angibt ... ich werd dann mal was basteln.

wegen adalightapa102: was ich nich ganz kapier, wieso ändern die leightberry leute das adalight protokoll. Ich mein ob fastled oder nicht is doch egal ... Streng genmmen dürfte man das garnich adalight nennen ...

redPanther commented 8 years ago

... ach super @Paulchen-Panther da haben wir beide gleichzeitig geschrieben ... ja stimmt, das is aber noch einfacher zu beheben ...

Paulchen-Panther commented 8 years ago

Ich denke da reicht ein einfaches hyperion.clear mit prio von foreground effect

redPanther commented 8 years ago

die zeile einfach in:

hyperion->setColor(FG_PRIORITY, ColorRgb::BLACK, 100, false);

ändern

Paulchen-Panther commented 8 years ago

Super. Danke dir noch mal. Dann mach mal ein PR. :-)

Paulchen-Panther commented 8 years ago

@redPanther noch mal auf das adalightapa102 zurück zu kommen. Adalight wurde doch ursprünglich von adafruit entworfen. könnte vielleicht auch so eine sache sein, das sich lightberry nicht in copyright sachen verwickeln wollte. Ist aber nur so eine Vermutung.

P.S.: warum fragt ihr den User @tociek nicht selber???

brindosch commented 8 years ago

@tociek I have a question regarding the adalightapa102 implementation, could we remove it? Or could you tell us in which circumstance you use this? We need documentation/sources(sketch) for this. So is there a reason why the adalight implementation is not enough? Users regularly use this by mistake (and a mistake is a support request and a support request is our time :) )

redPanther commented 8 years ago

hab jetzt nich den nerv für nen pr .. habs direkt im master committed, also die o.g. änderung is schon drin.

naja das is ja nur nen biliges protokoll (wenns wenigstens was inovatives wär) ... ich vermute eher: da die bestimmt kein fastled nutzen, werden die die daten auf pc seite so vorbereiten, das man die via spi leicht rausschieben kann.

@brindosch I think this is needed to use lightberry hd usb version. look here: http://support.lightberry.eu/#lightberry-hd-specification This is the "arduino" directly from lightberry with firmware preloaded

tociek commented 8 years ago

@brindosch adalightapa102 is needed to use APA102 leds with sketch modified from original adalight (which is for ws2801). The firmware is no secret and has been added to regular hyperion some time ago: hyperion/dependencies/LightberryHDUSBAPA1021.1.zip . Please do not remove it. Feel free to rename it to Lightberry HD USB :) Needless to say protocol for APA102 is different than WS2801

brindosch commented 8 years ago

Oh And FastLED means you need a led count and type, which results always in a new binary for a setup. And the people currently use "adalight" also with FastLED sketches which transforms everything vom ws2801 to -ledtype-?

OT: Maybe you should add a disclaimer regarding support :) https://hyperion-project.org/threads/config-problem.332/

tociek commented 8 years ago

We have not used FastLED library. I modified Adalight code. Yes, arduino code requires led count. The link you shared is for GPIO version of Lightberry HD, not USB (adalightapa102), which (USB) was programmed in a way to eliminate any artefacts that hyperion may send (as we know in some configurations unused leds remain on, when SPI is in use, like ws2801 via RPi's GPIO)

redPanther commented 8 years ago

as we know in some configurations unused leds remain on

you can set ledcount for hwleds independently from configured/used leds. see:

68 #77

redPanther commented 8 years ago

@tociek is it possible to change the firmware? it's a pitty that it sends ada back. Better would be it sends some custom string. Then we can auto configure rs232 leds protocol

tociek commented 8 years ago

Yes, we can change the firmware if the change would not be significant and it brings some benefits to the users. I think it would be cool to have hyperion printing information that certain device has been detected - frankly speaking, I was not aware that hyperion actually receives Ada back and does something with it.

redPanther commented 8 years ago

currently it doesn't evaluate the "ada" string, but I'm sure we will do in future. The only change I suppose is to change the ada sting to "lba" (for lightberry apa) - or something else, if you have a suggestion. Length should be 3 chars.