février 4

Ambilight avec OpenElec et Arduino

Ambilight est un système, à base de ruban LED rgb disposé à l’arrière d’une télé, permettant de diffuser des couleurs en rapport avec le contenu de l’image affiché à l’écran.

Pour cela, j’utilise un Raspberry 3 avec le mediacenter Openelec (LibreElec fonctionne aussi) connecté en USB à un Arduino Uno (un nano devrait aussi fonctionner) lui même connecté à un ruban de LED WS2812b.

J’ai fabriqué un cadre en bois avec des liteaux de 4X13 mm, fixé via les 2 vis VESA de la télé. Le ruban LED est collé sur les liteaux.
Les liteaux sont inclinés à 45° pour avoir un maximum de projection lumineuse à l’arrière de la télé.

Les fichiers 3D que j’ai créé pour ce montage sont disponible sur mon Thingiverse.

dans mon exemple, j’ai 29 LED en haut et bas et 17 à droite et gauche = 92 au total.

 

J’ai fais des pièces en 3D, tout est disponible sur mon Thingiverse.

Ruban LED

Le ruban est une suite de module de LED que l’on peut découpé et souder. Chaque module fait 33 mm, bien mesuré la longueur des liteaux haut/bas et droite/gauche en multiple de 33 mm, pour que le ruban arrive pile poil au bout.

Le ruban à un sens indiqué par une flêche, le logiciel utilisé par la suite permet de choisir la position de départ et le sens (horaire/anti), on est libre donc, pour ma part, je démarre en bas à droite (vu de l’arrière de la télé)

La ruse est de mettre des LED sur la longueur/largeur de l’écran ET PAS de la télé, si comme moi, elle comporte une bordure sur les bords.
Diviser donc la largeur de l’écran (en mm) par 33 pour avoir le nombre de LED à placer. Si ça tombe pas juste, ajuster au plus proche.

Le ruban comporte 3 connexion : +5V, GND, data, que j’ai relié à un domino fixé au cadre.

Arduino

le code vient de Tweaking4all et  utilise la librairie Adafruit NeoPixel, et fastLED, accessible via le gestionnaire de librairie d’Arduino.

#include <bitswap.h>
#include <chipsets.h>
#include <color.h>
#include <colorpalettes.h>
#include <colorutils.h>
#include <controller.h>
#include <cpp_compat.h>
#include <dmx.h>
#include <FastLED.h>
#include <fastled_config.h>
#include <fastled_delay.h>
#include <fastled_progmem.h>
#include <fastpin.h>
#include <fastspi.h>
#include <fastspi_bitbang.h>
#include <fastspi_dma.h>
#include <fastspi_nop.h>
#include <fastspi_ref.h>
#include <fastspi_types.h>
#include <hsv2rgb.h>
#include <led_sysdefs.h>
#include <lib8tion.h>
#include <noise.h>
#include <pixelset.h>
#include <pixeltypes.h>
#include <platforms.h>
#include <power_mgt.h>



/* t4a_boblight
 * (C) 2014 Hans Luijten, www.tweaking4all.com
 *
 * t4a_boblight is free software and can be distributed and/or modified
 * freely as long as the copyright notice remains in place.
 * Nobody is allowed to charge you for this code.
 * Use of this code is entirely at your own risk.
 */

#include "Adafruit_NeoPixel.h"

// DEFINITIONS

#define STARTCOLOR 0xFFFFFF  // LED colors at start
#define BLACK      0x000000  // LED color BLACK

#define DATAPIN    13        // PIN Arduino connecté à la broche DATA du WS2812
#define LEDCOUNT   92       // Nombre de LED du WS2812 utilisé
#define SHOWDELAY  20       //200 délai (en m/s) avant l'allumage (à reporter dans Hyperion)
#define BAUDRATE   500000    // Serial port 500000 étant prévu pour Arduino
#define BRIGHTNESS 100        // Max. luminosité en % (d'origine à 95)

const char prefix[] = {0x41, 0x64, 0x61, 0x00, 0x5B, 0x0E};  // = 91 LED indiqué par BoblightConfigMaker
char buffer[sizeof(prefix)]; // Temp buffer for receiving prefix data 

// Init LED strand, WS2811/WS2912 specific

// These might work for other configurations:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)

Adafruit_NeoPixel strip = Adafruit_NeoPixel(LEDCOUNT, DATAPIN, NEO_GRB + NEO_KHZ800);

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()
{
  strip.begin();            // Init LED strand, set all black, then all to startcolor
  
  strip.setBrightness( (255 / 100) * BRIGHTNESS );
  
  setAllLEDs(BLACK, 0);
  setAllLEDs(STARTCOLOR, 5);
  
  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
        strip.setPixelColor( currentLED++, buffer[0], buffer[1], buffer[2]);  // and assing to LEDs
      }
  
      if( currentLED > LEDCOUNT )        // Reached the last LED? Display it!
      {
          strip.show();                  // Make colors visible
          delayMicroseconds(SHOWDELAY);  // Wait a few micro seconds
          
          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


// Sets the color of all LEDs in the strand to 'color'
// If 'wait'>0 then it will show a swipe from start to end
void setAllLEDs(uint32_t color, int wait)
{
  for ( int Counter=0; Counter < LEDCOUNT; Counter++ )      // For each LED
  {
    strip.setPixelColor( Counter, color );      // .. set the color

    if( wait > 0 )                        // if a wait time was set then
    {
      strip.show();                     // Show the LED color
      delay(wait);                      // and wait before we do the next LED
    } // if wait
    
  } // for Counter
  
  strip.show();                         // Show all LEDs
} // setAllLEDs

On indique la pin Arduino connecté à DATA du ruban.

La vitesse du port à 500000 n’est pas conventionnel mais est adapté (d’après ce que j’ai compris) à la fréquence de fonctionnement d’Arduino.

La valeur hexa décimal à indiqué dans le code et qui doit correspondre (en autre) au nombre de LED utilisé. La calcul de cette valeur n’est pas très glamour :https://hyperion-project.org/threads/communication-issues-between-raspberry-and-arduino.507/
41, 64, 61 00 (les 4 premier byte ne changent pas)
ensuite, nombre de LED-1 en hexa, 92-1 = 5B
ensuite, la valeur XOR de 55 et de la valeur précédente (5B) E

Pour ma part, ça ne m’a pas aidé. Jai donc utilisé le logiciel BobLight ConfigMaker , prévu à la base pour le système BobLight.

La grosse ruse est que j’ai du indiqué dans ConfigMaker une valeur de LED inférieur de 1 au nombre réel de LED utilisé. Peut être du fait d’un calcul qui ne prend pas en compte la LED numéro 0 ?!?

Le GND d’Arduino est connecté au GND de l’alimentation des LED. L’alimentation d’Arduino est donc fourni par l’USB venant du raspberry.

Pour infos, chaque LED consomme environ 60 mA (si les 3 couleurs sont allumés ensemble), prévoir donc une alimentation en conséquence mais si dans mon cas, avec une alim de 2.5A ça fonctionne ?!?

Hyperion et Openelec

Hyperion est le système qui va gérer la liaison et les gestion des LED entre Openelec et Arduino.

Il faut donc l’installé sur le raspi qui contient Openelec.

On commence par rendre le dossier Flash accessible en écriture.

mount -o remount,rw /flash

On télécharge l’overlay qui gérera les sorties vers les leds

cd /flash/overlays/
curl -L --output enable-spi-overlay.dtb --get https://dl.dropboxusercontent.com/u/3669512/temp/enable-spi-overlay.dtb

on va ensuite modifier le fichier config.txt (présent sur la carte SD) pour activer le bus SPI

nano /flash/config.txt

A la fin du fichier, on rajoute les lignes suivantes:

device_tree_overlay=overlays/enable-spi-overlay.dtb
dtparam=spi=on

On reboot ensuite le raspberry

reboot

On télécharge et installe ensuite hyperion pour Raspi:

curl -L --output install_hyperion.sh --get https://raw.githubusercontent.com/tvdzwan/hyperion/master/bin/install_hyperion.sh
sh ./install_hyperion.sh

Hyperion démarre automatiquement avec Openelec, aucun de ses réglages n’est accessible depuis ce dernier.

Problème avec la version 8 de OpenElec

Le passage de la version 7 à 8 à supprimer 2 librairie de Openelec (/usr/lib/), indispensable pourtant à Hyperion :

  • libfontconfig.so.1.9.2
  • libfreetype.so.6.13.0

Comme ce dossier est protégé en écriture, il faut les mettre dans le dossier : /storage/hyperion/bin.
MAIS la ruse est qui faut les renommer en :

  • libfontconfig.so.1
  • libfreetype.so.6

pour que ça fonctionne ??

LibrairieHyperion
Source

Hyperion

Tout ce fait via le logiciel HyperionCron, écrit an JAVA, à installer sur un PC ou autre donc.

Un tuto en Français est disponible pour le réglages précis des LED :

On indique la rubrique  Hardware :

type = Adalight c’est la librairie Arduino

Output = /dev/ttyACM0, c’est la sortie USB du raspi
Le port tty peut être trouvé en débranchant/branchant l’Arduino et taper la commande : dmesg -s 1024 pour le Raspi.
Cela affiche les derniers log du Raspi.

baudrate = 500 000, comme indiqué dans le code Arduino

delay = 20, j’ai mis pareil que dans le code Arduino mais je ne sais pas si c’est pertinent.

RGB Byte order = RGB

Le nombre de LED

direction = Le sens du ruban

1st LED offset = La position de la LED de départ

image process = la surface qui va détecter les couleurs sur l’écran, à tester donc.

Blackborder detection = 20, c’est pour qu’il détecte les bords de la vidéo même avec des bandes noir en haut et bas.

La rubrique Process permet de modifier la transition des couleurs et leurs valeurs.

Le paramètre Smoothing permet d’avoir un allumage des LED moins rapide. En cas d’éclair à l’image par exemple, pour avoir un rendu plus naturel.

Dans la rubrique grabber, cocher enabled. Je n’ai pas creusé plus les paramètres.

dans la rubrique external, cocher Kodi checker et indiquer l’adresse IP du raspi.

La rubrique SSH permet d’envoyer la configuration créé directement dans le Raspberry, dans le dossier /storage/.config/

Pour cela, il faut indiquer l’adresse IP de son Raspi, le username Openelec (root), le password (openelec) puis faire « connect ».

Penser à bien cliquer sur « Create Hyperion Configuration » avant d’envoyer cette configuration, via « Send config« .

Faire stop et start pour actualiser la config.

A noter que « inst/upd Hyperion » permet d’installer et de mettre à jour Hyperion sur le Raspi.

Voila, si pas d’erreur, à l’ouverture d’OpenElec le ruban s’allume en blanc 2  fois  puis selon les couleurs de l’interface choisi pour Openelec.

Raspberry et Arduino

J’ai concocté un support en 3D  permettant d’avoir cote à cote le Raspi et Arduino… dispo sur mon Thingiverse


Étiquettes : , ,
Copyright 2017. All rights reserved.

Ecrit 4 février 2017 par Pit dans la catégorie "RASPBERRY PI", "Teensy/Arduino

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

dix-neuf − 8 =