Ambilight

Aus EasyVDR Wiki
Wechseln zu: Navigation, Suche
Ambilight.jpg

Vorwort:

Dieses Thema bezieht sich auf einzelne Varianten, die bei der Umsetzung eines Nachbau von Usern gesammelt wurden.

Variante Arduino mit WS2801 LED-Stripe:

Hardware

Arduino Nano ATmega328 mit FTDI Chip

WS2801 5050 RGB LED strip 32 LEDs/m

5V 7-16A Netzteil

Hier variiert die Ampere an der Anzahl der LEDs.

Bei einer Anzahl von über 100LEDs empfiehlt es sich ein Netzteil mit mehr als 10A zu nehmen.

Hinweis: Jeder ist selbst für seine Sicherheit verantwortlich. Den Strom bitte messen und das Netzteil passend zur maximalen Helligkeit+10% Sicherheitszuschlag auswählen. Auch und gerade bei der niederen Spannung können durch Fehler Brände ausgelöst werden

Aufbau

Ambilight Aufbau.png

Beim Strips verlegen unbedingt darauf achten, neben dem WS2801 Chip ist ein kleiner weißer Pfeil für die Verlege-Richtung aufgedruckt. Wird einer der Strips falschen rum eingebunden, passiert ab dem Anschluss nichts.

Ab einer Länge von 2m, sollte unbedingt eine weitere Einspeisung durch das Netzteil erfolgen.

Der Arduino benötigt nur einen gemeinsamen GND vom Netzteil, eine 5V Einspeisung ist nicht nötig, da durch USB versorgt.

In diesem Beispiel (Sketch weiter unten), werden die Stripes mit CK > D13, SI > D6 an den Arduino angeschlossen.


Software

Hier empfiehlt es sich zuerst den x Desktop auf LXDE zu wechseln. Bei openbox ist die USB Unterstützung nicht vollständig ausgebaut, daher kann unter Umständen der Arduino nicht gefunden werden.


-Arduino IDE ( Programmiersoftware )

Getestet wurde bisher mit Arduino IDE Version 1.8.1.

In der Menüleiste, sollte unter "Werkzeuge > Board" als erstes unser Arduino ausgewählt werden. In unserem Fall "Arduino Nano"

Dann bei "Werkzeuge > Prozessor" ATmega328 und zum Schluss "Werkzeuge > Port" /etc/ttyUSBx ( wahlweise, wo der Arduino am USB hängt )

Sollte die Software folgende Meldung anzeigen:

Arduino Aktualisierung.png

Empfiehlt es sich, diese Aktualisierung durchzuführen, andernfalls könnten wichtige Bibliotheken für die Programmierung fehlen.

Über den Bibliotheksmanger (Sketch/Bibiliothek einbinden/ Bibliotheken verwalten) die Bibliotheken aus den "Includes" einbinden.
ArduinoBibliothek.png
In unserem Fall also die FastLED Bibliothek damit die zum Kompilieren geforderte FastLED.h verfügbar ist.

Ist der Sketch geladen und passend zur Hardware angepasst, muss dieser nun nur noch unter Menüleiste "Sketch > Hochladen" aufgespielt werden.


Hinweis: Sollten wir Hyperion, oder einen anderen Dienst welcher auf die USB Schnittstelle zugreift im Vorfeld installiert haben, muss dieser Dienst vor dem aufspielen gestoppt werden. Bei Hyperionsudo stop hyperion


-Arduino Sketch ( Software, die mit Arduino IDE auf den Arduino gespielt wird )

Wahlweise kann hier auch der LED-Typ bei Verwendung von Beispielsweise APA102 individuell angepasst werden, in diesem Fall #define LED_TYPE WS2801 ändern in #define LED_TYPE APA102

Es sollte unbedingt die Anzahl der LED's #define MAX_LEDS 410 angepasst werden. Hier bitte darauf achten, Anzahl der LED's + 1. Haben wir also 128 LED's, sieht der Eintrag wie flogt aus #define MAX_LEDS 129

Die Baudrate ist hier schon auf den maximalen Wert eingestellt ( 500000 )#define serialRate 500000 und muß später in Hyperion eingetragen werden.

Programmcode(Adalight) hier drunter einfach in Arduino IDE einfügen.

#include "FastLED.h"
 
#define ANALOG_MODE_AVERAGE  0
#define ANALOG_MODE_LAST_LED 1
 
/**************************************
   S E T U P
 
   set following values to your needs
 **************************************/
 
#define INITIAL_LED_TEST_ENABLED true
#define INITIAL_LED_TEST_BRIGHTNESS 32  // 0..255
 
// Number of leds in your strip. set to "1" and ANALOG_OUTPUT_ENABLED to "true" to activate analog only
// As of 26/1/2017:
// 582 leaves ZERO bytes free and this
// 410 is ok
// tested with 500 leds and is fine (despite the warning)
#define MAX_LEDS 410
 
// type of your led controller, possible values, see below
#define LED_TYPE WS2801 
 
// 3 wire (pwm): NEOPIXEL BTM1829 TM1812 TM1809 TM1804 TM1803 UCS1903 UCS1903B UCS1904 UCS2903 WS2812 WS2852
//               S2812B SK6812 SK6822 APA106 PL9823 WS2811 WS2813 APA104 WS2811_40 GW6205 GW6205_40 LPD1886 LPD1886_8BIT 
// 4 wire (spi): LPD8806 WS2801 WS2803 SM16716 P9813 APA102 SK9822 DOTSTAR
 
// For 3 wire led stripes line Neopixel/Ws2812, which have a data line, ground, and power, you just need to define DATA_PIN.
// For led chipsets that are SPI based (four wires - data, clock, ground, and power), both defines DATA_PIN and CLOCK_PIN are needed
 
// DATA_PIN, or DATA_PIN, CLOCK_PIN
// #define LED_PINS 6        // 3 wire leds
#define LED_PINS 6, 13  // 4 wire leds
 
#define COLOR_ORDER GRB  // colororder of the stripe, set RGB in hyperion
 
#define OFF_TIMEOUT 15000    // ms to switch off after no data was received, set 0 to deactivate
 
// analog rgb uni color led stripe - using of hyperion smoothing is recommended
// ATTENTION  this pin config is default for atmega328 based arduinos, others might work to
//            if you have flickering analog leds this might be caused by unsynced pwm signals
//            try other pins is more or less the only thing that helps
#define ANALOG_OUTPUT_ENABLED false
#define ANALOG_MODE           ANALOG_MODE_LAST_LED  // use ANALOG_MODE_AVERAGE or ANALOG_MODE_LAST_LED
#define ANALOG_GROUND_PIN     8                     // additional ground pin to make wiring a bit easier
#define ANALOG_RED_PIN        9
#define ANALOG_GREEN_PIN      10
#define ANALOG_BLUE_PIN       11
 
// overall color adjustments
#define ANALOG_BRIGHTNESS_RED   255              // maximum brightness for analog 0-255
#define ANALOG_BRIGHTNESS_GREEN 255              // maximum brightness for analog 0-255
#define ANALOG_BRIGHTNESS_BLUE  255              // maximum brightness for analog 0-255
 
#define BRIGHTNESS 255                      // maximum brightness 0-255
#define DITHER_MODE BINARY_DITHER           // BINARY_DITHER or DISABLE_DITHER
#define COLOR_TEMPERATURE CRGB(255,255,255) // RGB value describing the color temperature
#define COLOR_CORRECTION  TypicalLEDStrip   // predefined fastled color correction
//#define COLOR_CORRECTION  CRGB(255,255,255) // or RGB value describing the color correction
 
// Baudrate, higher rate allows faster refresh rate and more LEDs
//#define serialRate 460800      // use 115200 for ftdi based boards
//#define serialRate 115200      // use 115200 for ftdi based boards
#define serialRate 500000         // use 115200 for ftdi based boards
 
 
/**************************************
   A D A L I G H T   C O D E
 
   no user changes needed
 **************************************/
 
// 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;
 
unsigned long endTime;
 
// Define the array of leds
CRGB leds[MAX_LEDS];
 
// set rgb to analog led stripe
void showAnalogRGB(const CRGB& led) {
  if (ANALOG_OUTPUT_ENABLED) {
    byte r = map(led.r, 0,255,0,ANALOG_BRIGHTNESS_RED);
    byte g = map(led.g, 0,255,0,ANALOG_BRIGHTNESS_GREEN);
    byte b = map(led.b, 0,255,0,ANALOG_BRIGHTNESS_BLUE);
    analogWrite(ANALOG_RED_PIN  , r);
    analogWrite(ANALOG_GREEN_PIN, g);
    analogWrite(ANALOG_BLUE_PIN , b);
  }
}
 
// set color to all leds
void showColor(const CRGB& led) {
  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
  LEDS.showColor(led);
  #endif
  showAnalogRGB(led);
}
 
// switch of digital and analog leds
void switchOff() {
  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
  memset(leds, 0, MAX_LEDS * sizeof(struct CRGB));
  FastLED.show();
  #endif
  showAnalogRGB(leds[0]);
}
 
// function to check if serial data is available
// if timeout occured leds switch of, if configured
bool checkIncommingData() {
  boolean dataAvailable = true;
  while (!Serial.available()) {
    if ( OFF_TIMEOUT > 0 && endTime < millis()) {
      switchOff();
      dataAvailable = false;
      endTime = millis() + OFF_TIMEOUT;
    }
  }
 
  return dataAvailable;
}
 
// main function that setups and runs the code
void setup() {
  Serial.begin(serialRate);
 
  // analog output
  if (ANALOG_OUTPUT_ENABLED) {
    // additional ground pin to make wiring a bit easier
    pinMode(ANALOG_GROUND_PIN, OUTPUT);
    digitalWrite(ANALOG_GROUND_PIN, LOW);
    pinMode(ANALOG_BLUE_PIN , OUTPUT);
    pinMode(ANALOG_RED_PIN  , OUTPUT);
    pinMode(ANALOG_GREEN_PIN, OUTPUT);
  }
 
  // Uncomment/edit one of the following lines for your leds arrangement.
  int ledCount = MAX_LEDS;
  if (ANALOG_MODE == ANALOG_MODE_LAST_LED) {
    ledCount--;
  }
 
  #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
    FastLED.addLeds<LED_TYPE, LED_PINS, COLOR_ORDER>(leds, ledCount);
  #endif
 
  // color adjustments
  FastLED.setBrightness ( BRIGHTNESS );
  FastLED.setTemperature( COLOR_TEMPERATURE );
  FastLED.setCorrection ( COLOR_CORRECTION );
  FastLED.setDither     ( DITHER_MODE );
 
  // initial RGB flash
  #if INITIAL_LED_TEST_ENABLED == true
  Serial.println("initial test");
  showColor(CRGB(INITIAL_LED_TEST_BRIGHTNESS, 0, 0));  delay(400);
  showColor(CRGB(0, INITIAL_LED_TEST_BRIGHTNESS, 0));  delay(400);
  showColor(CRGB(0, 0, INITIAL_LED_TEST_BRIGHTNESS ));  delay(400);
  #endif
  showColor(CRGB(0, 0, 0));
 
  Serial.print("Ada\n"); // Send "Magic Word" string to host
 
 
  boolean transmissionSuccess;
  unsigned long sum_r, sum_g, sum_b;
 
  // loop() is avoided as even that small bit of function overhead
  // has a measurable impact on this code's overall throughput.
  for(;;) {
    // wait for first byte of Magic Word
    for (i = 0; i < sizeof prefix; ++i) {
      // If next byte is not in Magic Word, the start over
      if (!checkIncommingData() || prefix[i] != Serial.read()) {
        i = 0;
      }
    }
 
    // Hi, Lo, Checksum
    if (!checkIncommingData()) continue;
    hi = Serial.read();
    if (!checkIncommingData()) continue;
    lo = Serial.read();
    if (!checkIncommingData()) continue;
    chk = Serial.read();
 
    // if checksum does not match go back to wait
    if (chk != (hi ^ lo ^ 0x55)) continue;
 
    memset(leds, 0, MAX_LEDS * sizeof(struct CRGB));
    transmissionSuccess = true;
    sum_r = 0;
    sum_g = 0;
    sum_b = 0;
 
    int num_leds = min ( MAX_LEDS, (hi<<8) + lo + 1 );
 
    // read the transmission data and set LED values
    for (int idx = 0; idx < num_leds; idx++) {
      byte r, g, b;
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      r = Serial.read();
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      g = Serial.read();
      if (!checkIncommingData()) {
        transmissionSuccess = false;
        break;
      }
      b = Serial.read();
      leds[idx].r = r;
      leds[idx].g = g;
      leds[idx].b = b;
      #if ANALOG_OUTPUT_ENABLED == true && ANALOG_MODE == ANALOG_MODE_AVERAGE
          sum_r += r;
          sum_g += g;
          sum_b += b;
      #endif
    }
 
    // shows new values
    if (transmissionSuccess) {
      endTime = millis() + OFF_TIMEOUT;
      #if MAX_LEDS > 1 || ANALOG_OUTPUT_ENABLED == false
      FastLED.show();
      #endif
 
      #if ANALOG_OUTPUT_ENABLED == true
        #if ANALOG_MODE == ANALOG_MODE_LAST_LED
          showAnalogRGB(leds[MAX_LEDS-1]);
        #else
          showAnalogRGB(CRGB(sum_r/MAX_LEDS, sum_g/MAX_LEDS, sum_b/MAX_LEDS));
         #endif
      #endif
    }
  }
} // end of setup
 
void loop() {
  // Not used. See note in setup() function.
}

-Hyperion

Installation:

cd /tmp
curl -k -L --output install_hyperion.sh --get https://raw.githubusercontent.com/hyperion-project/hyperion/master/bin/install_hyperion.sh
chmod +x install_hyperion.sh
sudo sh ./install_hyperion.sh

Nun benötigen wir noch das Konfigurationstool HyperCon.

sudo apt-get install openjdk-7-jre
cd /home/vdr
wget https://sourceforge.net/projects/hyperion-project/files/hypercon/HyperCon.jar

Konfiguration:

Starten können wir hypercon dann im X Desktop an einem xTerminal. Hierfür folgendes in den xTerminal eingeben.

su easyvdr
sudo su 
java -jar /home/vdr/HyperCon.jar

Im Konfigurationsprogramm,

Hypercon.png

müssen wir nun den Sketch Adalight, Schnittstelle USB und die Geschwindigkeit 500000 auswählen. Weitere Einträge wie RGB Anzahl der LED's an allen vier Seiten und Verlegerichtung obliegt der jeweiligen Hardware Konfiguration.

Sollten wir die Grafik-Ausgabe über Nvidia betreiben, muss in hypercon der boblight Service aktiviert werden.

Die Einstellungen müssen wir nun mit dem Button "Generiere Konfiguration für Hyperion" unter /etc/hyperion abspeichern.

Sollte alles stimmen, geben wir im Terminal

restart hyperion 
hyperion-x11

ein und die LED's sollten hell werden.

Haben wir zuvor den hyperion Dienst gestoppt muss der Dienst mit start und nicht mit restart angestoßen werden.

-Boblight

Boblight Plugin und einige Treiber benötigen wir nur, sollte die Ausgabe über Nvidia erfolgen. Bei Intel (vaapi) ist boblight nicht notwendig.

Installation:

sudo apt-get update
sudo apt-get install libboblight
sudo apt-get install vdr-plugin-boblight

Nun noch das boblight Plugin in vdr aktivieren und vdr neu starten.


Abschließend für den Dauerbetrieb: Hyperion x11 Server in Autostart von LXDE eintragen:

Unter /var/lib/vdr/.config/lxsession/LXDE die autostart um einen Eintrag erweitern @hyperion-x11

Fazit: Sollten Probleme/Fragen bei diesen Tread auftreten, bitte in unserem Forum einen gesonderten Post erstellen.