février 4

Ambilight avec Raspi 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 (un Kodi prévu pour Raspi) connecté en USB à un Arduino Uno 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.

Hyperion

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

On indique la rubrique  Hardware :

type = Adalight c’est la librairie Arduino

Output = /dev/ttyACM0, c’est la sortie USB 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

janvier 19

Ambilight avec Teensy

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.

Ca donne un truc comme ça :

Matériel et logiciel

Disposer le ruban aux 4 bords de la télé, il se découpe et permet de relier les morceaux ensemble via 3 fils à souder.
Faire en sorte que les LED haut/bas et droite/gauche soient alignées.
Le mieux je pense est de les placer sur une plaque ou des liteaux, avec un angle de 45°, fixé derrière la télé.
Chaque bloc de LED fond 33 mm, divisé donc la largeur et hauteur de la télé par cette valeur afin de placer les led le plus régulièrement possible.

Dans mon système, ma télé est relié à un PC sur lequel j’ai installé le mediacenter Kodi.

IMPORTANT : Le ruban à un sens, indiqué par une flèche. Mettre la 1er LED sur le ruban haut ou bas.

  • Le mico-controller Teensy 3.2 (le Teensy LC ne fonctionne pas)
  • L’adaptateur OctoWS2811, qui permet la liaison entre les LED et le teensy, via un connecteur RJ45
  • les logiciels Arduino et TeensyDuino
  • La librairie OctoWS2811 pour Adalight
  • Le logiciel Ambibox

Connecter le Teensy en USB au PC et charger la librairie OctoWS2811/Adalight dans Arduino.
Indiquer simplement le nombre de LED utiliser.

  • Une alimentation « solide » à calculer en fonction du nombre de LED utilisé.
Dans mon système, j’utilise 94 LED :
calculer 0.06A par LED + 20%
84 * 0.06 = 5A + 20% = 6,7A
Pour ma part, j’utilise la sortie 5V de l’alim du PC, qui alimente aussi le Teensy via USB

Connexion

+5V et 0V de l’alim vers le ruban LED
data 01 et 0V du RJ45/Octo vers le ruban LED (Normalement fil orange/blanc et orange)

Teensy rélié à l’USB du PC

Ambibox

C’est le logiciel qui permet de faire comprendre au Teensy/Octo/Adalight que l’image que renvoie le PC doit être coordonné au LED.
Son interface est une horreur d’ergonomie et de clarté mais on arrive à ses fins.

IMPORTANT :  via le panneaux de configuration/gestionnaire de périphériques, noter le numéro du port COM attribué au Teensy.
Ce numéro est à indiquer dans Ambibox.

Plusieurs possibilités son disponible, permettant d’afficher une couleur sur toutes les LED (pratique pour un test), de détecter l’image du PC, selon différent mode qui influenceront sur la latence des LED et/ou le consommation du CPU.
Un mode permet aussi de le lier seulement à Kodi, via une extension à installer sur ce dernier.

  • Indiquer le nombre de LED total
  • le numéro du port COM du Teensy
  • Le sens du ruban
  • Un raccourci pour « backlight », qui permettra d’allumer/éteindre le système.

Cliquer sur « More settings » pour avoir accès au bouton « Wizard capture zone » (qui peut être masqué par une zone qui ce place devant le bouton).

Indiquer le nombre de LED haut/bas (il doit en avoir le même nombre) et droite/gauche.
Attention Ambibox rajoute les LED du bout du ruban haut/bas au LED du ruban droite/gauche.
Dans mon cas, j’ai 29 LED haut/bas et 18 droite/gauche (29+29+18+18=94) MAIS je doit indiquer 20 pour droite/gauche ?!?

Faire « apply », à noter que si on revient ensuite dans « Wizard… » les paramètres précédemment  rentrés ne sont pas indiqués.
Mais, si on fait un test avec « troublesootting » on voit que les valeurs ont bien été appliqués ?!?

Ambibox est vraiment obscure !

Notes

Le mode Screen capture permet d’avoir n’importe quelle logiciel qui active ambilight, même Kodi sans extension dédié.
MAIS si Windows est en mode non aero (graphique au minimum), il ne réagit pas.

 

Aide

Catégorie : Teensy/Arduino | Commenter
juillet 30

Récupérer la valeur MIDI du volume

Un croquis permettant de récupérer la valeur MIDI du curseur de volume de Ableton Live et de l’envoyer, via USB/MIDI, sur un Teensy 3.

A noter que, à chaque changement de set Live, la valeur du volume est automatiquement envoyé !

void setup()
{

}

void loop()
{
int ControleChange, valeur;
  if (usbMIDI.read()) 
  {      // si il y a des messages MIDI
      int ControleChange = usbMIDI.getData1();
      int valeur = usbMIDI.getData2();
    Serial.print("Control change: ");
    Serial.println(ControleChange);   
    Serial.print("Valeur: ");
    Serial.println(valeur);
  }

}//loop
Catégorie : Teensy/Arduino | Commenter
février 27

Clignotement SANS delay()

Sous Arduino ou Teensy, le clignotement d’une LED avec la commande delay() ralentit tout le code.

1 – Avec la fonction elapsedMillis

Heureusement, la fonction elapsedMillis, qui génère un compteur permet de se passer de delay.
J’ai concocté une fonction qui permet d’allumer et d’éteindre une LED x sec toute les x sec.

int LEDcligno = 20; // LED entre pin 20 et la masse, via résistance
int EtatLEDcligno = HIGH;
int ChangeLEDcligno = 0;
elapsedMillis ComptCligno; //compteur

void setup()
{
pinMode(20, OUTPUT); 
}
void loop()
{
ClignoLED(250, 15000); // 1/4 sec, 15 sec
}//loop

void ClignoLED (int on, int off)
{
int intervalle = ComptCligno - ChangeLEDcligno;
if (EtatLEDcligno == HIGH && intervalle > on)
{
    // éteint 
    EtatLEDcligno = LOW;
    digitalWrite(LEDcligno, EtatLEDcligno);
    ChangeLEDcligno = ComptCligno;
}
  else if (EtatLEDcligno == LOW && intervalle > off) 
  {
    // allumé
    EtatLEDcligno = HIGH;
    digitalWrite(LEDcligno, EtatLEDcligno);
    ChangeLEDcligno = ComptCligno;
  }
intervalle = 0;//RAZ
}//void

2 – Avec le cycle d’horloge

Les instructions du Teensy sont exécutés en boucle, à une fréquence de 96Mhz. Entre le début et la fin de la boucle, il se passe donc un certains temps, dépendant principalement du nombre d’instructions que le teensy doit effectuer.

int ComptLED = 1;
int TempsON = 14000;

void setup() {
  pinMode(2, OUTPUT);//LED
  digitalWrite(2, LOW);// démarrer éteint 
  pinMode(4, INPUT_PULLUP);//contact

}

void loop() {
ComptLED = ComptLED+1;
 Serial.println(ComptLED); 
if (digitalRead(4) == LOW)// si contact
{
 digitalWrite(2, HIGH);// allumer la LED
}

if (ComptLED == TempsON)// au bout d'un certains temps
{
  digitalWrite(2, LOW);// éteindre la LED  
   ComptLED = 1;  
}
}//loop

C’est moins précis car il faut ajuster « ComptLED » à la mano mais ça fonctionne.

Catégorie : Teensy/Arduino | Commenter
juillet 19

Envoyer plusieurs données entre Teensy et Xbee

J’avais déjà indiqué comment envoyer une donnée à la fois (en faite un byte à la fois) pour commander en ON/OFF une LED par exemple MAIS si l’on souhaite envoyer plusieurs données en série du style :  Si j’envoie la lettre A alors les 3 données suivantes concerne le groupe A,  ça se complique.

J’ai essayé via la library fournis par Xbee mais je n’arrive à rien !

Le code émetteur

/* testé sur Teensy 3.1 et Xbee série 1.
#define HWSERIAL Serial2 //TX2 pin10


void setup() {/********************** SETUP *****************************/
  HWSERIAL.begin(9600);
}

void loop() {
  
  HWSERIAL.write('a');
  HWSERIAL.write(1);
  HWSERIAL.write(2);
  HWSERIAL.write(3);
  delay(1000);
  
   HWSERIAL.write('b');
  HWSERIAL.write(10);
  HWSERIAL.write(20);
  HWSERIAL.write(30);
  delay(1000);
}//loop

Le code récepteur

/* testé sur Teensy 3.1 
on envoie via serie un write(a ou b), si il est reçu, on reçoit les 3 données suivantes.
*/
#define HWSERIAL Serial1

byte DataSerie[4];
byte InSerie;

void setup(){
   HWSERIAL.begin(9600);
 
}


void loop(){
 while (HWSERIAL.available())
{// on place les 4 bytes reçu dans un tableau

      for (int i=0; i<=3; i++)
      {
byte InSerie = HWSERIAL.read();  
DataSerie[i] = InSerie;
      }//for
if (DataSerie[0] == 'a')// le premier byte envoyé doit être le caractère a 
{
 Serial.println("bien recu a"); 
 Serial.println(byte(DataSerie[1]));
  Serial.println(byte(DataSerie[2]));
   Serial.println(byte(DataSerie[3]));
}
if (DataSerie[0] == 'b')
{
 Serial.println("bien recu b"); 
 Serial.println(byte(DataSerie[1]));
  Serial.println(byte(DataSerie[2]));
   Serial.println(byte(DataSerie[3]));  
}
}//while
}//loop

J’ai délibérément fait simple mais c’est une base pour faire des trucs sympa !

Autre façon de faire

Catégorie : Teensy/Arduino | Commenter
juillet 13

Fonction pour afficher dans le moniteur serie

Il n’est parfois pas facile, vu la vitesse de défilement du moniteur série d’Arduino, de voir la valeur d’une variable.

Placer l’appel de la fonction :

MoniteurSerie(String("Valeur du volume"), ValeurVolume);

Et après le LOOP, la fonction.
Il suffira juste de jouer sur le delay pour ralentir l’affiche de tous les appels à la fonction.

void MoniteurSerie(String texte, int variable)
{
  Serial.print(texte);
  Serial.print(": ");
  Serial.print(variable);
  Serial.println("");
  delay(10); 
}

 

Catégorie : Teensy/Arduino | Commenter
juillet 13

Modification de variable via une liaison série

J’ai fais un montage avec Teensy et Xee permettant à 1 bouton de dire via une liaison série :  si je suis appuyé, la variable MaVariable = 1, sinon MaVariable = 0.

J’ai donc : appuie bouton = envoie série de « on », si pas d’appuie = envoie série de « off ». Problème, au repos, j’envoie sans arret le code « off » ce qui est pas top en terme de gestion de l’énergie.

Je pourrais faire, sur la partie réception : si j’envoie autre chose que « on », alors on considère que c’est « off ».
Le truc est que en même temps, j’envoie d’autres code en série, donc cette solution ne tient pas.

J’ai trouvé l’astuce en jouant sur un compteur.

Si le bouton sur OFF, je compte jusqu’à 3 MAIS SEULEMENT à 2, j’envoie le code série « off ». Le compteur reste bloqué à 3 (donc plus d’envoie série) jusqu’à que je bouton soit « on », quand i l’est, l’incrément du compteur se remet sur 1 et attend donc que le bouton soit « off » pour recompter.

Je ne mat pas le code qui fait : si tu appuie, fait : HWSERIAL.write(« on »);

if(Bouton == 1) // si le bouton est ON, on met le compteur = 1
{
  ComptBouton = 1;
  }
if (Bouton == 0 && ComptBouton <=3)//quand le bouton est OFF, on compte jusqu'à 3
{
for (ComptBouton = 1; ComptBouton <=3; ComptBouton++)
{
if(ComptBouton == 2)// à 2, on envoie le code off
{
HWSERIAL.write("off"); 
}//if
}//for
}//if bouton

Comme j’ai galéré un moment sur ça, je partage !

Catégorie : Teensy/Arduino | Commenter
juillet 9

Volume MIDI via liaison série

Le Teensy 3.1 est reconnu nativement comme un périphérique compatible MIDI et il permet aussi de créer des touches à effleurement (capacitive).
Le Xbee (serie 1) est très simple à configurer, voila de quoi faire une belle télécommande audio.

Code émetteur

/* testé sur Teensy 3.1 :
Un les touches à effleurement incrémentent ou décrémentent une valeur de volume (0 à 127).
Un appuie sur une des deux touches envoie via serie, la lettre 'v' qui indique au récepteur que l'on envoie une valeur de volume.
Ensuite, on evoie la valeur de volume. */

#define HWSERIAL Serial2 //TX2 - pin 8
#include <CapacitiveSensor.h>

/*VOLUME*/
int TestBouton10;
int EtatBouton10;
int TestBouton11;
int EtatBouton11;
int ValeurVolume;
/* au changement de set Ableton, à la 1er impulsion des boutons, le volume se met une fraction de seconde au volume du set précédent (ComptVolume part de la dernière valeur) */
const int latenceVolume = 10; // vitesse du curseur
const int MaxHaut = 127; //127 en MIDI

/* TOUCHE SENSITIVE */
int BoutonCommun = 14; // pin commune
int NBtestBoutons = 30; // nombres de test des boutons
int ValCapacitive = 2000; // valeur de l'entrée capacitive

//VOLUME
CapacitiveSensor   Bouton10 = CapacitiveSensor(BoutonCommun, 32); // Volume + (pin 32)
CapacitiveSensor   Bouton11 = CapacitiveSensor(BoutonCommun, 33); // Volume - (pin 33)

void setup() {/********************** SETUP *****************************/
  HWSERIAL.begin(9600); 
}

void loop() {

  //VOLUME
  long TestBouton10 =  Bouton10.capacitiveSensor(NBtestBoutons);
  long TestBouton11 =  Bouton11.capacitiveSensor(NBtestBoutons);

   /**************************************************************** ENVOIE SERIE - VOLUME */
  if (TestBouton10 > ValCapacitive && ValeurVolume < MaxHaut)
  {
       HWSERIAL.write('v');
        ValeurVolume++;
HWSERIAL.write(ValeurVolume);
    delay(latenceVolume);
  }

  if (TestBouton11 > ValCapacitive && ValeurVolume > 0)
  {    
   HWSERIAL.write('v'); 
      ValeurVolume--;
HWSERIAL.write(ValeurVolume);
    delay(latenceVolume);
  }
Serial.println(ValeurVolume);
}//loop

Code récepteur

/* testé sur Teensy 3.1 
on envoie via serie un write('v') et ensuite un write avec une valeur numérique.
si le a est reçu, alors on affiche la valeur numérisue.
*/
#define HWSERIAL Serial1

byte DataSerie[1]; //tableau de 2 valeurs (0 et 1)
byte InSerie;
int i;

void setup(){
   HWSERIAL.begin(9600);
 
}


void loop(){
 while (HWSERIAL.available())
{// on place les 2 byte recu dans un tableau
i = 0;
      for (i=0; i<=2; i++)
      {
byte InSerie = HWSERIAL.read();  
DataSerie[i] = InSerie;

if (char(DataSerie[0]) == 'v')// le premier byte envoyé doit être le caractère v 
{
 Serial.println("bien recu v"); 
 int ValeurVolume = byte(DataSerie[1]);
 usbMIDI.sendControlChange(12, ValeurVolume, 1); //ProgramChange 12, canal MIDI 1
 Serial.println(ValeurVolume );
}
      }//for
      i = 0;
}//while
 
          }//loop



Limitation

Si on envoie d’autre données série en même temps, cela perturbe  le système, les autres données s’intercalant entre la lettre déclencheur ‘v’ et la valeur du volume.
L’idéal serait d’envoyer une seule donnée du style V+ValeurVolume et de découper ensuite en 2 dans la partie récepteur.

 

Catégorie : Teensy/Arduino | Commenter
juin 8

Envoyer une donnée entre Teensy et Xbee

Le pitch étant d’envoyer une phrase, ou une variable, entre 2 Teensy 3.1, relié chacun à un Xbee serie 1.

La connexion

  • 1 = 3.3 Volt –> vers pin 3.3 Volts du Teensy
  • 2 = Digital OUT —> vers pin 0 (RX1) du Teensy
  • 3 = Digital IN —> vers pin 1 (TX1) du Teensy
  • 10 = GND –> vers pin GND du Teensy

xbee-pins teensy31_front_pinout

 

Pour ma part, je n’ai pas eu besoin de programmer quoi que ce soit sur les Xbee.
J’ai un couple Teensy/Xbee sur mon PC fixe et un autre couple sur mon portable.

La programmation

J’ai vu beaucoup d’exemples divers de sketch Arduino ou Teensy, vers comme souvent, les gens n’indique pas la version de leur matos. Donc, j’ai fais ma petite sauce, qui fonctionne sur Teensy 3.1.

Envoie

/* Testé sur Teensy 3.1 */ 
#define HWSERIAL Serial1 // pin 0 et 1
void setup() {
HWSERIAL.begin(9600);
}
void loop() {
HWSERIAL.println("Hello"); //ln pour avoir un retour à la ligne après "hello"
delay(500);
}

Réception

/* Testé sur Teensy 3.1 et Xbee serie 1 */
#define HWSERIAL Serial1

void setup() {
HWSERIAL.begin(9600);
}
 
void loop() {
if (HWSERIAL.available())// si des données sont présentes
{
Serial.print(char(HWSERIAL.read())); // char ) caractère, rien ou int = code ASCII
} 
}//loop

 

Dans la console moniteur serie du récepteur, on récupère le mot ou la phrase envoyé.

OK mais le top c’est que ça serve à quelque chose. On va donc tacher d’envoyer une variable précise qui va déclencher l’allumage de la LED interne du Teensy.

/* Testé sur Teensy 3.1 et Xbee serie 1.
Xbee sur pin 0 et 1 du Teensy */
#define HWSERIAL Serial1
byte InSerie;

void setup() {
HWSERIAL.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
 
void loop() {

if (HWSERIAL.available())
{
byte InSerie = HWSERIAL.read();
Serial.println(InSerie);
if (InSerie == 'A')
{
Serial.print("recu");// pour vérification
digitalWrite(13, HIGH);
}
else
{
digitalWrite(13, LOW);  
}
}
}//loop

Amélioration

La fonction Print est plus dédié à l’affichage dans une console ou un afficheur LCD, lisible pour un humain.

Dans mon cas, je souhaite envoyer des valeurs, parfois sur plusieurs chiffres. dans ce cas, la fonction write et byte est préférable.

Envoie

#define HWSERIAL Serial1

void setup() {
HWSERIAL.begin(9600); 
}

void loop() {
HWSERIAL.write(1);
delay(1000);
HWSERIAL.write(0);
delay(1000);
}//loop

Réception

#define HWSERIAL Serial1
byte InSerie;

void setup() {
HWSERIAL.begin(9600);
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
}
 
void loop() {

if (HWSERIAL.available()>0)
{
InSerie = HWSERIAL.read();
Serial.println(byte(InSerie) );
if (InSerie == 1)
{
digitalWrite(13, HIGH);
}
if (InSerie == 0)
{
digitalWrite(13, LOW); 
}
}
}//loop

La pour le coup, on peut commencer à vraiment commander des trucs entre les 2 teensy.

Notes sur la liaison série

Le protocole série n’envoie par des lettres et/ou des symboles mais des nombres, du code  binaire, hexadécimal… qui sont en correspondance.

Selon ce tableau, faire un Serial.write(‘a’); et Serial.write(97);  (97 en décimal = ‘a’) enverra le même code. On ne peux pas dire au Teensy de faire : si tu reçois ‘a’, fait ça et si tu reçois 97 fait ça; L’action sera la même.

Catégorie : Teensy/Arduino | Commenter
mai 24

Les modules Xbee

Présentation

Ce sont des petits modules électroniques, compatible Arduino et Teensy, permettant d’envoyer des données « serie » sans-fil.
Il y a malheureusement plusieurs types de modules (serie 1, serie 2, XeeBee, Znet) créant je trouve une grande confusion.
La serie 1 est aussi appelé 802.15.4 et la serie 2 ZB ou ZigBee.

A priori, avec la serie 1 c’est automatique, les Xbbe communiquent même sans passer par la case programmation.
Pour les serie 2, vu les différents « mode » disponible, la programmation est indispensable.

Pour ma part, j’ai eu des résultats très « chaotiques », je déconseille donc l’utilisation de la serie 2, du moins pour un projet simple de envoie/réception de donnée.

(difference entre serie 1 et 2)

xbee-comparaisons

  • les modules des séries 1 et 2 ne sont pas compatibles entre eux ;
  • la portée et la consommation sont sensiblement les mêmes ;
  • le nombre d’entrées et sorties est différent et surtout la série 2 ne possède pas de sorties analogiques PWM ;
  • les topologies de réseaux possibles ne sont pas les mêmes :
    • Avec la série 1, l’architecture est simple : point à point (pair) ou multipoint (star).
    • La série 2 permet en plus de créer des réseaux plus complexes : maillés (mesh) ou en « arbre » (cluster tree).

xbee-reseaux

 

Hardware

De plus, différente version hardware existe aussi (antenne intégrée, connecteur antenne, antenne extérieur…)

xbee-antenne

 

  • wire :  min antenne omnidirectionnelle
  • chip : antenne intégrée, sous forme de puce (le signal est atténué dans certaines directions) ;
  • U.FL : antenne intégrée ( à vérifier) et une mini prise pour une antenne externe
  • RPSMA : plus gros que le connecteur U.FL, permet de placer son antenne à l’extérieur d’un boîtier.

Même le logiciel (Xctu) servant à programmer les modules à changé de version et de look… difficile donc de si retrouver avec les nombreux tutos présents sur le net, comme souvent qui ne précise pas avec quelle version de ce *** de Xbee il font leur tuto.

Le brochage des pins est le même entre la serie 1 et la serie 2

xbee-pins

Chaque XBee dispose d’une adresse 64 bits imprimé sur le dos.
Le début ou la partie « HIGH » de l’adresse seront 0013A200 (pré-attribué pour Digi). La dernière partie ou «LOW» de l’adresse sera différent pour chaque Xbee. Notez ces chiffres, ça peut servir pour la suite.

xbee-etiquette

 

Connexion

L’écarts des pins du Xbee n’est pas au pas standard (veroboard, breadboard…)
Il faut donc passer par des interface (Arduino ou USB) pour tester la bête.

Xbee-pin-board xbee-usb-board

 

Configuration

L’interface USB SparkFun, permet de le brancher directement sur un PC, afin qu’il soit reconnu par le logiciel dédié à sa configuration (voir plus bas).

xbee-usb-pc

Cette interface dispose d’un bouton permettant faire un « reset » du Xbee, en cas de problème de mise à jour par exemple.
Ce bouton fait juste un court-circuit entre la broche 5 et la broche 10 (gnd).

La connexion vers Arduino ou autre est des plus simple :

  • 1 = 3.3 Volt (pas de 5 Volt)
  • 2 = Digital OUT —> vers RX arduino (receive)
  • 3 = Digital IN —> vers TX arduino (transmitte)
  • 10 = GND

Avec Teensy 3.1, on peut utiliser un sketch permettant de faire un « pont » entre les données « serie » et le port USB.
Ce système permet d’utiliser la prise USB du Teensy pour le programmer mais surtout, de le faire reconnaître par le logiciel X-CTU, pour sa configuration.

Il suffit de connecter le Xbee au Teensy (parmis les 3 ports série disponible), de charger le sketch : Fichier/exemples/Teensy/USB_Serial/USBtoSerial, de mettre Teensy en mode serie : Outils/USB type = Serial. Une fois le teensy connecté en USB au PC, X-CTU devrait le voir.

Attention : bien prendre note de la vitesse serie indiqué dans le sketch lors de la recherche du Xbbe par X-CTU.

Programmation

La programmation des Xbee se fait via  un logiciel dédié, à savoir X-CTU.

Les modes

AT = Transparent

C’est le mode par défaut, le plus simple à configurer

API = Application Programming Interface

« …envoyer et recevoir des données vers et à partir de série UART de la radio. L’API est une alternative au mode transparent par défaut. L’API permet au programmeur la possibilité de: Modifier les paramètres sans passer en mode de commande (XBee seulement) Voir RSSI et l’adresse de la source sur un paquet par base de paquets Recevez la confirmation de livraison de paquets sur chaque paquet transmis… »

Le mode API n’est possible qu’avec une connexion locale en série et filaire avec l’ordinateur et Arduino, pas entre modules XBee.

COMMAND

Il permet de configurer le module : ses entrées, ses sorties, son adresse, l’adresse de destination de ses messages, etc.

Ouvrez le terminal choisi. Avant tout, il faut signaler au XBee que l’on veut quitter le mode TRANSPARENT pour entrer dans le mode COMMAND. Pour cela il faut prendre le coup de main, suivez bien ces instructions à la lettre :

  • Taper +++ et attendre 1 seconde sans appuyer sur aucune autre touche, le message OK devrait alors s’afficher comme sur l’image du terminal.
    Par ce OK, le XBee nous signale qu’il passe en mode COMMAND et qu’il est prêt à recevoir les messages de configuration.
  • Si vous attendez plus de 10 secondes sans appuyer sur une touche, le XBee revient en mode TRANSPARENT. V
    ous devez alors retaper +++ pour revenir en mode COMMAND.

Dans les télécommunications, l’ensemble de commandes Hayes est un langage de commandes spécifiques développé pour le modem Hayes SmartModem 300 en 1981. Les commandes sont une série de mots courts qui permettent de contrôler le modem avec un langage simple (composer un numéro de téléphone, connaître l’état de la ligne, régler le volume sonore…) Ce jeu de commandes s’est ensuite retrouvé dans tous les modems produits
(sources :http://fr.wikipedia.org/wiki/Commandes_Hayes , http://en.wikipedia.org/wiki/Hayes_command_set ).

Pour avoir un aperçu rapide des commandes disponibles pour le XBee, télécharger le guide de référence des commandes AT de Sparkfun .

Sources:

http://www.pobot.org/-Reseaux-ZigBee-.html

http://jeromeabel.net/ressources/xbee-arduino

https://docs.digi.com/display/XCTU/Configure+your+modules

Catégorie : Teensy/Arduino | Commenter