juin 1

Ambilight multi-source HDMI

J’avais déjà fait des système ambilight connecté à un Openelec par exemple MAIS, comme beaucoup de monde, j’ai plusieurs source vidéo chez moi (Freebox, Chromecast, Raspberry…) et je voulais que toutes ces sources bénéficies de l’ambilight.

Le principe est de séparer la source sélectionné en HDMI, via un convertisseur HDMI/composite, vers un grabber USB qui va convertir le signal composite en flux vidéo exploitable en USB. Ce flux vidéo sera analysé par le logiciel Hyperion, installé sur un Raspberry Pi.

Le montage

Le matériel

On aura donc besoin :

D’un Raspberry Pi pour Hyperion, la version 1 B+ suffit car Hyperion n’a pas besoin de beaucoup de puissance.

D’un grabber USB, là on doit faire attention à en avoir un qui utilise la puce UTV007, afin d’être bien reconnu par le Raspi.

D’un convertisseur HDMI/composite, il comporte une alimentation microUSB mais dans mon cas, je n’ai pas eu besoin de l’alimenter.

D’un splitter HDMI, pour sélectionner les diverses sources. Celui que j’utilise comporte un bouton de sélection dessus (et une affreux LED bleu) et une télécommande infra-rouge (d’une portée de 20 cm ?!?).

Un ruban LED WS2801, attention car la version WS2812 ne fonctionne pas avec le Raspi.

D’une alimentation 5V, pour alimenter tout ce beau monde. Pour infos, les Internet indiquent que le ruban LED devrait consommer environ 60mA par LED, ma mesure, avec 89 LED allumé en blanc et le rapi ne consomme que 1 A. (Théoriquement on devrait avoir 0.05 X 89 = 4.45 A ?!?).

De cables HDMI, faire attention à la qualité car certains ne sont pas compatible avec le splitter HDMI et ne laisse par passer le son ou les commandes CeC. faire des tests donc avec différentes combinaisons.

Raspberry et ruban LED

Adafruit a publié plusieurs recommandations pour la mise en œuvre de ces LED.
On retiendra le fait de monter sur l’alimentation un condensateur de 1000µF pour absorber les pics de tension à la mise en route et l’ajout éventuel d’une résistance d’environ 500Ω en série entre le micro-contrôleur et la LED de tête lorsque le fil est long pour empêcher le signal de se réfléchir et de perturber la transmission.
Une résistance de 10kΩ entre DI et GND garantit également que la LED de tête ne reçoit pas un signal incohérent alors que la broche du micro-contrôleur n’a pas encore été programmée en sortie.
Pour ma part, j’ai juste mis le condensateur.

Mon ruban LED indique CI pour clock et DI pour dat.

Hyperion

Vous devez dabord installer sur votre PC (nécessite d’installer JAVA). Ensuite,  Hypercron se connecteen SSH à votre Raspi, via l’onglet dédié.

l’installation d’Hyperion sur le Raspi se fait depuis cette rubrique, via le bouton Install/Upd Hyperion.

Pour la configuration, on indique le type du ruban LED et le nombre et sens de rotation de son ruban.

La rubrique Process sert à ajuster les couleurs des LED. Si on à trop de bleu si on affiche tout en blanc par exemple.
Cela peut ce faire via la rubrique SSH ou une application Android par exemple qui permettra de controler le ruban.

Comme le Raspi va « grabber » une source qui vient de l’USB, on doit décocher « Internal frame grabber »

A chaque modification de configuration, on doit faire :

  • Create hyperion config
  • stop
  • send config
  • start

Le ruban reboot et voila !

Le site d’Hyperion donne beaucoup d’infos sur l’installation et la configuration.

Le ruban LED

Perso, j’ai fixé le ruban LED sur des baguettes en bois que j’ai orientés avec un angle de 45°, histoire d’avoir une diffusion optimale.
Les fichiers 3D que j’ai créé pour cela son dispo sur mon Thingiverse.

Le résultat

source01

 

Catégorie : RASPBERRY PI | Commenter
mai 1

Domotique avec Google Home et Photon

Amélioration/simplification de mon 1er projet domotique.
Plus besoin de serveur Blynk, remplacé par le cloud de Particle.
Le Teensy est remplacé par Photon, qui contient une puce WiFi donc plus besoin de ESP-01 et donc de régulateur 3.3 volts.

J’ai modifié aussi le code qui permet maintenant d’envoyer deux mots clés via Google Home pour déclencher une action.

Le but étant de piloter les télécommandes infra-rouge (ampli 5.1, switch HDMI…) , la Freebox, les lampes de la maison (via des prises commandés en 433mhz) et un ruban LED multicolore via mon Google Home.
Tout le montage rentre dans un bocal translucide de chez Ikea. La consommation au repos est de 1.9 Watts.

Photon dans bocal IKEA

Pré-requis

Composants :

  • Particle Photon
  • XY-FST-433 (RX433)
  • SFH4346 (LED infra-rouge)
  • WS2812 (ruban LED)
  • Condensateur 1000 uF/25V
  • Transfo 5 Volts /2A
  • Éventuellement, un relais 220V/RX433

Le Principe

IFTTT reçoit les commandes du Google Home (trigger) et l’envoie une URL (WebHook) sur le cloud Particle.
Le micro-contrôleur Photon, relié en WiFi,  déclenche des actions infra-rouge et radio-fréquence, via le code Arduino.

Ex : On dit : Allume et un mot clé (tout, le guéridon, le lampadaire, la télé…), le code Arduino contient des IF qui réagissent aux mot clés indiqués et envoie les codes infra-rouge ou 433mhz.

Le Photon

La connexion du Photon au WiFi est simplissime :

  • Brancher en USB
  • installer l’appli Android,
  • connecter le smartphone au WiFi du Photon
  • indiquer le SSID/clé de son WiFi

Une fois fait, le Photon est accessible via le cloud Particle.

Le code Arduino

Pas besoin de passer par l’installation de Arduino, tous se passe en ligne via le cloud Particle. L’avantage est de pouvoir mettre à jour le code du Photon directement en WiFi !

Il faut juste intégrer les librairies :

  • IRtransmitter
  • RCSwitch
  • NEOpixel
  • rest_client

Juste à modifier IRTransmitter.ccp pour pouvoir envoyer des code infra-rouge à la suite.

}
digitalWrite(led_pin_, LOW);
delay(10); //temps minimum entre deux envoie de code infra rouge
}

On peut ajouter manuellement une library (petit « + »), les deux fichiers ***.cpp et ***.h qui la compose seront liés et ajoutés automatiquement au fichier ***.ino
ex : #include « IRTransmitter.h »
#include « IRTransmitter.cpp »
Copier/coller dedans le code de la librairy, précédement récupéré sur GitHub
(bizz, le code copier dans ***.cpp, se retrouve dans ***.h et vice versa)
L’avantage c’est que l’on pourra éditer les library et que, lors de l’export du projet, on aura dans le zip le fichier .ino et les library utilisées

// Webhook
#include "rest_client.h"
RestClient client = RestClient("hd1.freebox.fr");

// WS2812
#include "neopixel.h"
#define PIXEL_PIN D2 // pin de la broche Din du WS2812
#define PIXEL_COUNT 55 // nombre de LED
#define PIXEL_TYPE WS2812B
#define BRIGHTNESS 255 // lumière, de 0 à 255
int VitesseAllume = 20;
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

// InfraRouge
#include "IRTransmitter.h"
#define IR_PIN D6 // pin LED InfraRouge
#define LED_PIN D7 // LED interne à chaque envoie de code
IRTransmitter transmitter(IR_PIN, LED_PIN);

// RX433
#include "RCSwitch.h"
RCSwitch mySwitch = RCSwitch();


void setup() {//SETUP

IPAddress myIP = WiFi.localIP(); // publier l'adresse IP
Particle.publish("IP du Photon", String(myIP), PRIVATE);

pinMode(D7, OUTPUT); // LED interne

mySwitch.enableTransmit(D0);// PIN data du module RX433

strip.setBrightness(BRIGHTNESS);
strip.begin();
strip.show(); // démarrer LED éteintes

// enregistrement de la fonction dans le cloud Particle.
// Le 1er terme sera appelé dans IFTTT, le second contient le TextField de IFTTT
Particle.function("allume", MotAllume);
Particle.function("eteint", MotEteint);
Particle.function("AmpliAction", ActionAmpli);
Particle.function("AmpVolPlus", DBenPlus);
Particle.function("AmpVolMoins", DBenMoins);
Particle.function("voir", regarder);
Particle.function("BonneNuit", EteintTout);

}//fin setup

/*** CODES INFRAROUGE ***/
//Ampli 5.1
unsigned int  Ampli_OnOff[67] = {8550,4200, 600,1500, 600,500, 600,1500, 600,500, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,450, 650,1500, 600,1550, 600,450, 600,1550, 600,450, 600,500, 550,500, 600,1550, 600,1500, 650,1500, 600,450, 600,500, 600,450, 600,1550, 600,1500, 600,500, 600,450, 600,450, 600,1550, 600,1550, 600,1550, 600};  // NEC A55A38C7

unsigned int  Ampli_VolPlus[67] = {8500,4200, 600,1550, 600,500, 550,1550, 600,500, 550,500, 600,1550, 550,500, 600,1550, 550,500, 600,1550, 600,450, 600,1550, 600,1500, 600,500, 600,1500, 600,500, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,500, 550,500, 600,450, 600,1550, 600,450, 600,1550, 600,500, 550,1550, 600,1550, 600,1550, 550,1550, 700};  // NEC A55A50AF  

unsigned int  Ampli_VolMoins[67] = {8550,4200, 600,1550, 600,450, 600,1550, 600,450, 600,500, 600,1500, 650,450, 600,1500, 650,450, 600,1550, 550,500, 600,1550, 600,1500, 600,500, 600,1500, 650,450, 600,1500, 650,1500, 600,500, 550,1550, 600,500, 550,500, 600,450, 600,500, 600,450, 600,450, 650,1500, 600,450, 600,1550, 600,1550, 600,1550, 550,1550, 600};  // NEC A55AD02F

unsigned int  Ampli_Mute[67] = {8550,4200, 600,1500, 600,500, 600,1500, 600,500, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,1550, 600,450, 600,1550, 600,450, 600,500, 550,1550, 600,500, 550,500, 550,1600, 600,450, 600,450, 600,500, 550,1550, 600,500, 550,1600, 550,1550, 600,500, 550,1550, 600,1550, 600,1550, 600};  // NEC A55A48B7

unsigned int  Ampli_Loudness[67] = {8550,4200, 550,1550, 600,500, 600,1500, 600,500, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,1550, 600,450, 600,1550, 600,450, 600,1550, 600,1550, 550,1550, 600,1550, 600,1550, 600,450, 600,450, 600,1550, 600,500, 550,500, 600,450, 600,500, 550,500, 600,1550, 600,1500, 600,500, 600};  // NEC A55AF906

//Switch HDMI
unsigned int  SwitchHDMI1[67] = {9100,4450, 600,550, 600,600, 600,550, 600,550, 600,550, 600,550, 600,600, 600,550, 600,1650, 600,1650, 600,1650, 650,1600, 650,1600, 650,1650, 600,1650, 600,1650, 600,550, 650,550, 600,1650, 600,550, 600,550, 650,500, 650,550, 600,550, 600,1650, 650,1600, 650,500, 650,1650, 600,1650, 600,1650, 650,1600, 650,1600, 650};  // NEC FF20DF

unsigned int  SwitchHDMI2[67] = {9200,4400, 650,550, 600,550, 600,550, 600,600, 600,550, 600,550, 600,550, 600,550, 650,1600, 650,1600, 650,1650, 600,1650, 600,1650, 600,1650, 650,1600, 650,1600, 650,550, 600,550, 600,550, 600,1650, 600,600, 600,550, 600,550, 600,550, 600,1650, 600,1650, 600,1650, 600,550, 600,1650, 650,1600, 650,1600, 650,1600, 650};  // NEC FF10EF

unsigned int  SwitchHDMI3[67] = {9200,4400, 600,550, 650,500, 650,500, 650,500, 600,600, 550,600, 600,550, 650,500, 600,1650, 600,1650, 600,1650, 600,1650, 600,1650, 600,1650, 650,1600, 650,1600, 650,500, 650,1600, 650,500, 650,1600, 650,500, 650,550, 600,550, 600,550, 600,1650, 600,550, 600,1650, 600,550, 600,1650, 600,1650, 600,1650, 600,1650, 600};  // NEC FF50AF

void loop() {

}//fin loop

/*** Ampli 5.1 ***/
int ActionAmpli(String action){

  if(action == "mute"){// coupe/remet/mute l'ampli
  transmitter.Transmit(Ampli_Mute, sizeof(Ampli_Mute) / sizeof(Ampli_Mute[0]));  
  return 1;
  }
  if(action == "loudness"){
  transmitter.Transmit(Ampli_Loudness, sizeof(Ampli_Loudness) / sizeof(Ampli_Loudness[0]));  
  return 1;
  }
}//

int DBenPlus(String action){// monte l'ampli de **
int volume = action.toInt();

 if(volume >=0 || volume <=10){// pour empécher de mettre trop fort !
      
    for (int i=1; i <= volume; i++){
     transmitter.Transmit(Ampli_VolPlus, sizeof(Ampli_VolPlus) / sizeof(Ampli_VolPlus[0]));
     delay(100);
    }
    return volume;    
 }
}//

int DBenMoins(String action){// monte l'ampli de **
int volume = action.toInt();

    for (int i=1; i <= volume; i++){
     transmitter.Transmit(Ampli_VolMoins, sizeof(Ampli_VolMoins) / sizeof(Ampli_VolMoins[0]));
     delay(100);
    }
    return volume;    
}//

/*** REGARDER ***/
int regarder(String action){
String mot[2];
    mot[0]="";
    mot[1]="";

    int index = 0;
    for( int i = 0; i < action.length(); i++ ){
        
      if( index < 2 ){// on sépare les mots reçus
        char sep = action.charAt(i);
        mot[index] += sep;

      if( sep == ' ') index++;// si il y a un espace entre
      }
    }
//Switch HDMI
  if(mot[0] == "la" || mot[1] == "freebox"){
  transmitter.Transmit(SwitchHDMI1, sizeof(SwitchHDMI1) / sizeof(SwitchHDMI1[0]));  
  return 1;
  }
  if(mot[0] == "Netflix" or mot[0] == "le" || mot[1] == "Chromecast"){
  transmitter.Transmit(SwitchHDMI2, sizeof(SwitchHDMI2) / sizeof(SwitchHDMI2[0]));  
  return 1;
  }
  if(mot[0] == "Kodi" or mot[0] == "le" || mot[1] == "mediacenter"){
  transmitter.Transmit(SwitchHDMI3, sizeof(SwitchHDMI3) / sizeof(SwitchHDMI3[0]));  
  return 1;
  }

// Chaines Freebox 
if (action == "mosaïque" or action == "mosaîc" or action == "panel") {TelecomFreebox ("0","","");}
if (action == "TF 1") {TelecomFreebox ("1","","");}
if (action == "France 2") {TelecomFreebox ("2","","");}
if (action == "France 3") {TelecomFreebox ("3","","");}
if (action == "Canal +" or action=="Canal") {TelecomFreebox ("4","","");}
if (action == "France 5") {TelecomFreebox ("5","","");}
if (action == "M 6") {TelecomFreebox ("6","","");}
if (action == "Arte") {TelecomFreebox ("7","","");}
if (action == "C 8") {TelecomFreebox ("8","","");}
if (action == "W 9") {TelecomFreebox ("9","","");}
if (action == "TMC") {TelecomFreebox ("1","0","");}
if (action == "TFX") {TelecomFreebox ("1","1","");}
if (mot[0] == "NRJ" || mot[1] == "12") {TelecomFreebox ("1","2","");}
if (action == "LCP") {TelecomFreebox ("1","3","");}
if (action == "France 4") {TelecomFreebox ("1","4","");}
if (action == "BFM") {TelecomFreebox ("1","5","");}
if (action == "cnews") {TelecomFreebox ("1","6","");}
if (action == "cstar") {TelecomFreebox ("1","7","");}
if (mot[0] == "France" || mot[1] == "Ô") {TelecomFreebox ("1","9","");}
if (action == "6 ter") {TelecomFreebox ("2","2","");}
if (mot[0] == "Numéro" || mot[1] == "23") {TelecomFreebox ("2","3","");}
if (action == "RMC") {TelecomFreebox ("2","4","");}
if (mot[0] == "chérie" || mot[1] == "25") {TelecomFreebox ("2","5","");}
if (action == "LCI") {TelecomFreebox ("2","6","");}
if (mot[0] == "France" || mot[1] == "Info") {TelecomFreebox ("2","7","");}
if (mot[0] == "Paris" || mot[1] == "Première") {TelecomFreebox ("2","8","");}
if (action == "RTL 9") {TelecomFreebox ("2","9","");}
if (action == "Téva") {TelecomFreebox ("3","8","");}
if (mot[0] == "AB" || mot[1] == "1") {TelecomFreebox ("3","9","");}
if (action == "Paramount") {TelecomFreebox ("5","8","");}
if (mot[0] == "planète" || mot[1] == "+") {TelecomFreebox ("5","9","");}
if (mot[0] == "National" || mot[1] == "Geographic") {TelecomFreebox ("6","0","");}
if (mot[0] == "National" || mot[1] == "Wild") {TelecomFreebox ("6","1","");}
if (mot[0] == "M6" || mot[1] == "Music") {TelecomFreebox ("6","4","");}
if (mot[0] == "NRJ" || mot[1] == "hits") {TelecomFreebox ("6","5","");}
if (mot[0] == "MTV" || mot[1] == "hits") {TelecomFreebox ("6","6","");}
if (mot[0] == "trace" || mot[1] == "urban") {TelecomFreebox ("6","7","");}
if (action == "Vivolta") {TelecomFreebox ("6","9","");}
if (action == "TV5") {TelecomFreebox ("7","0","");}
if (mot[0] == "TV" || mot[1] == "Breizh") {TelecomFreebox ("7","1","");}
if (action == "comédie") {TelecomFreebox ("8","0","");}
if (mot[0] == "polar" || mot[1] == "+") {TelecomFreebox ("8","1","");}
if (mot[0] == "Warner" || mot[1] == "TV") {TelecomFreebox ("8","2","");}
if (mot[0] == "serie" || mot[1] == "club") {TelecomFreebox ("8","3","");}
if (action == "MTV") {TelecomFreebox ("8","4","");}
if (mot[0] == "elle" || mot[1] == "girl") {TelecomFreebox ("8","5","");}
if (mot[0] == "fashion" || mot[1] == "TV") {TelecomFreebox ("2","4","1");}
if (mot[0] == "planete" || mot[1] == "CI") {TelecomFreebox ("2","0","0");}
if (mot[0] == "planete" || mot[1] == "Aventure") {TelecomFreebox ("2","0","1");}
if (action == "ushuaîa") {TelecomFreebox ("2","0","4");}
if (action == "histoire") {TelecomFreebox ("2","0","5");}
if (mot[0] == "toutes" || mot[1] == "histoire") {TelecomFreebox ("2","0","6");}
if (mot[0] == "science" || mot[1] == "vie") {TelecomFreebox ("2","0","7");}

if (mot[0] == "un" || mot[1] == "DVD"){
    TelecomFreebox ("home","","");
    delay(2000);
    TelecomFreebox ("right","","");
    delay(1000);
    TelecomFreebox ("right","","");
    delay(1000);
    TelecomFreebox ("right","","");
    delay(1000);
    TelecomFreebox ("ok","","");
    }
}//

/*** ALLUME ***/
int MotAllume(String action){

String mot[2];
    mot[0]="";
    mot[1]="";

    int index = 0;
    for( int i = 0; i < action.length(); i++ ){
        
      if( index < 2 ){// on sépare les mots reçus
        char sep = action.charAt(i);
        mot[index] += sep;

      if( sep == ' ') index++;// si il y a un espace entre
      }
    }
    
// Toutes les lumières
 if(mot[0] == "tout"){
colorWipe(strip.Color(255, 0, 0), VitesseAllume); // lampe en rouge
mySwitch.send(16762196, 24);// boule
delay(5);
mySwitch.send(16765268, 24);// lampadaire
delay(5);
mySwitch.send(16766036, 24);// guéridon
delay(5);
mySwitch.send(16766228, 24);// étoile
  }
    
// Ruban LED
 if(mot[0] == "en" || mot[1] == "rouge"){
colorWipe(strip.Color(255, 0, 0), VitesseAllume); // lampe en rouge
  }
  
    if(mot[0] == "en" || mot[1] == "vert" || mot[1] == "verre"){
colorWipe(strip.Color(0, 255, 0), VitesseAllume); // lampe en vert
  }
  
    if(mot[0] == "en" || mot[1] == "bleu"){
colorWipe(strip.Color(0, 0, 255), VitesseAllume); // lampe en bleu
  }
  
    if(mot[0] == "en" || mot[1] == "blanc"){
colorWipe(strip.Color( 255, 255, 255), VitesseAllume); // lampe en blanc
  }
  
      if(mot[0] == "ciel"){
rainbow(27); // Arc en Ciel
  }
  
/*** modules 433 mhz ***/    
  if(mot[0] == "la" || mot[1] == "cuisine"){
mySwitch.send(1975778, 24);
  }
  
  if(mot[0] == "la" || mot[1] == "boule"){// boule
mySwitch.send(16762196, 24);
  }
  
  if(mot[0] == "le" || mot[1] == "lampadaire"){
mySwitch.send(16765268, 24);
  }
  
  if(mot[0] == "le" || mot[1] == "guéridon"){
mySwitch.send(16766036, 24);
  }
  
  if(mot[0] == "la" or mot[1] == "veilleuse"){// étoile
mySwitch.send(16766228, 24);
  }

  if(mot[0] == "le" || mot[1] == "5.1"){// ampli 5.1
  transmitter.Transmit(Ampli_OnOff, sizeof(Ampli_OnOff) / sizeof(Ampli_OnOff[0]));  
  }
  
if (mot[0] == "la" || mot[1] == "télé" or mot[1] == "Freebox") {
    transmitter.Transmit(Ampli_OnOff, sizeof(Ampli_OnOff) / sizeof(Ampli_OnOff[0]));//Ampli 5.1
    TelecomFreebox ("power","","");//Freebox sur TV
    delay(1500);
    TelecomFreebox ("ok","","");
    delay(2000);
    TelecomFreebox ("0","","");// mosaique
    delay(100);
    // pour réveiller le switch HDMI
    transmitter.Transmit(SwitchHDMI2, sizeof(SwitchHDMI2) / sizeof(SwitchHDMI2[0]));// HDMI 2
    delay(300);
    transmitter.Transmit(SwitchHDMI3, sizeof(SwitchHDMI3) / sizeof(SwitchHDMI3[0]));// HDMI 3
    delay(300);
    transmitter.Transmit(SwitchHDMI1, sizeof(SwitchHDMI1) / sizeof(SwitchHDMI1[0]));// Switch HDMI sur Freebox
    }

}//FinAllume

/*** ETEINT ***/
int  MotEteint(String action){

String mot[2];
    mot[0]="";
    mot[1]="";

    int index = 0;
    for( int i = 0; i < action.length(); i++ ){
        
      if( index < 2 ){// on sépare les mots reçus
        char sep = action.charAt(i);
        mot[index] += sep;

      if( sep == ' ') index++;// si il y a un espace entre
      }
    }

    if(mot[0] == "la" || mot[1] == "lampe"){// ruban LED
colorWipe(strip.Color( 0, 0, 0), 60); // rien
  }
  
 if(mot[0] == "tout"){// Toutes les lumières
mySwitch.send(16762193, 24);// boule
delay(5);
mySwitch.send(16765265, 24);// lampadaire
delay(5);
mySwitch.send(16766033, 24);// guéridon
delay(5);
mySwitch.send(16766225, 24);// étoile
colorWipe(strip.Color(0, 0, 0), VitesseAllume); // lampe
  }  
  
  if(mot[0] == "la" || mot[1] == "cuisine"){
  mySwitch.send(1975778, 24);
  }
  
    if(mot[0] == "la" || mot[1] == "boule"){
mySwitch.send(16762193, 24);
  }
  
  if(mot[0] == "le" || mot[1] == "lampadaire"){
mySwitch.send(16765265, 24);
  }
  
  if(mot[0] == "le" || mot[1] == "guéridon"){
mySwitch.send(16766033, 24);
  }
  
  if(mot[0] == "la" or mot[1] == "veilleuse"){// étoile
mySwitch.send(16766225, 24);
  }

  if(mot[0] == "le" || mot[1] == "5.1"){// ampli 5.1
  transmitter.Transmit(Ampli_OnOff, sizeof(Ampli_OnOff) / sizeof(Ampli_OnOff[0]));
  }

  if(mot[0] == "la" || mot[1] == "télé" or mot[1] == "Freebox"){
  transmitter.Transmit(Ampli_OnOff, sizeof(Ampli_OnOff) / sizeof(Ampli_OnOff[0]));// ampli 5.1
  TelecomFreebox ("power","","");// Freebox
  }
  
}//FinEteint

/*** ON VA SE COUCHER ***/
int  EteintTout(String appareil){

transmitter.Transmit(Ampli_OnOff, sizeof(Ampli_OnOff) / sizeof(Ampli_OnOff[0]));// ampli 5.1
TelecomFreebox ("power","","");// Freebox
mySwitch.send(16762193, 24);// boule
delay(5);
mySwitch.send(16765265, 24);// lampadaire
delay(5);
mySwitch.send(16766033, 24);// guéridon
delay(5);
mySwitch.send(16766225, 24);// étoile
colorWipe(strip.Color(0, 0, 0), VitesseAllume); // lampe

}//

/*** FONCTIONS RUBAN WS2812 ***/
void colorWipe(uint32_t c, uint8_t wait) {// changement de couleurs
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

void rainbow(uint8_t wait) {// arc en ciel
  uint16_t i, j;
  for(j=0; j<256; j++) {
    for(i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    delay(wait);
  }
}
uint32_t Wheel(byte WheelPos) {
  if(WheelPos < 85) {
   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  } else if(WheelPos < 170) {
   WheelPos -= 85;
   return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  } else {
   WheelPos -= 170;
   return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
}


/*** FONCTION TELECOMMANDE FREEBOX ***/
void TelecomFreebox(String touche1, String touche2, String touche3){
  int URL1 = client.get("/pub/remote_control?code=86700567&key="+touche1);
  Particle.publish("Touche Freebox 01", String(touche1), PRIVATE);
  delay(50);
  int URL2 = client.get("/pub/remote_control?code=86700567&key="+touche2);
  Particle.publish("Touche Freebox 02", String(touche2), PRIVATE);
  delay(50);
  int URL3 = client.get("/pub/remote_control?code=86700567&key="+touche3);
  Particle.publish("Touche Freebox 03", String(touche3), PRIVATE);
}//

L’électronique

Tout est basé sur le Photon, juste à connecté le module RX433, les 2 LED infra-rouge et le condo, permettant de protéger le ruban LED.

IFTTT

Il suffira d’avoir en Trigger Google Assistant et en Action Particle.

Le code permet d’avoir 2 mots en TextFiled (la télé par exemple) mais on peut le modifier facilement.

Montage en 3D

Le Photon est placé au dessus et je me suis permis de faire un semblant de design 😉

Les fichiers 3D

Catégorie : Electronique | Commenter
février 23

Domotique avec Google Home, Teensy et Blynk

Mon projet domotique 2017. Le but étant de piloter les télécommandes infra-rouge (Freebox, ampli 5.1, switch HDMI…), les lampes de la maison (via des prises commandés en 433mhz) et un ruban LED multicolors via mon Google Home (et aussi IFTTT et Blynk).
Tout le montage rentre dans un bocal translucide de chez Ikea.

Le tout consomme 1.7 Watts au repos et 6.5 Watts avec une couleur allumé.

 

Pré-requis

Composants :

  • Régulateur 3.3volts LD1117v33
  • Teensy 3.2
  • ESP01 (WiFi)
  • XY-FST-433 (RX433)
  • SFH4346 (LED infra-rouge)
  • WS2812 (ruban LED)
  • Condensateur 1000 uF/25V
  • Transfo 5 Volts /2A
  • Éventuellement, un relais 220V/RX433

Le Principe

IFTTT reçoit les commandes du Google Home (trigger) et l’envoie une URL (WebHook) sur le serveur Blynk.
Celui-ci est connecté au Teensy via le ESP01 et déclenche des actions via le code Arduino.

On dit : Allume et un mot clé (tout, un, deux, Freebox…), le code Arduino contient des IF qui réagissent aux mot clés indiqués et envoie les codes infra-rouge ou 433mhz.

Le code Arduino

/*URL pour webhook IFTTT (passé en GET)  
 * https://ipduserveurblynk:9443/tokenblynk/update/v2?value={{TextField}}
 * avec le navigateur
 * https://ipduserveurblynk:9443/tokenblynk/update/v0?value=MotClé 
 * 
 * A base de Teensy 3.2
 * 2017 - Par Pit Wyman
 */
 
#define ESP8266_BAUD vitesse
#include <SoftwareSerial.h>
#define HWSERIAL Serial1 //pin RX1=0, TX1=1 du TeensyLC, Teensy 3.2

//RX433
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
int PinRX433 = 10; //pin Arduino/Teensy du module RX433

//Blynk
#define BLYNK_PRINT Serial //pour afficher les infos de connexion Wifi et Blynk  
#include <BlynkSimpleShieldEsp8266.h>

//ESP10
#include <ESP8266_Lib.h>
SoftwareSerial EspSerial(0, 1); // TX, RX de ESP10
ESP8266 wifi(&EspSerial);

//InfraRouge
/*
2 LED IR en série et Pas de résistance (avec certaines alims, ça envoie pas assez de jus)
Arduino Uno/Nano = pin 3
Teensy LC = 16
Tensy 3 à 3.6 = pin 5
*/
#include <IRremote.h>
//irrecv.blink13(true);// allume la LED interne du Teensy lors de l'envoie
IRsend irsend; //LED IR

//Ruban LED WS2812
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#define WS2812Data 16 // Pin de la broche data du WS2812

// nombre de LED du WS2812
#define NbLED 55
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NbLED, WS2812Data, NEO_GRB + NEO_KHZ800);

int vitesse = 9600;
char auth[] = "***"; //token Blynk
char ssid[] = "****"; // Nom WiFi
char pass[] = "*****"; // Clé WiFi

#define VERSION "MaDomotique - Fin 2017"

void setup() {/*******************************************/
  Serial.begin(vitesse);//moniteur serie
  pixels.begin(); // NeoPixel library.
 //transmission RX433
  mySwitch.enableTransmit(PinRX433);
  // Optional set pulse length. default 320
  //mySwitch.setPulseLength(280); 
  // Optional set protocol (default is 1, will work for most outlets)
  //mySwitch.setProtocol(1); 
  // Optional set number of transmission repetitions. defaut 15
  //mySwitch.setRepeatTransmit(15);

  EspSerial.begin(ESP8266_BAUD);
  delay(50);
  Blynk.begin(auth, wifi, ssid, pass, "192.168.0.30"); //IP du serveur local Blynk
  
ws2812 (0,NbLED, 0,0,0);//éteint
ws2812 (0,NbLED, 255,255,255);//allume
delay(200);
ws2812 (0,NbLED, 0,0,0);//éteint
}

/******************** Allumer/éteindre lampes, Freebox ou Ampli 5.1 ***********************************/

BLYNK_WRITE(V0){// Allume ***
String ValeurV0 = param.asStr();
Serial.print("allume : ");
Serial.println(ValeurV0);

ws2812 (0,8, 255,0,0);//controle
ws2812 (0,8, 0,0,0);
   
Blynk.virtualWrite(0,ValeurV0);//envoie la valeur sur display de Blynk
 
      if (ValeurV0 == "tout" or ValeurV0 == "tous" or ValeurV0 == "tu"){
      mySwitch.send(16762196, 24); //lampe 1
      delay(100);
      mySwitch.send(16765268, 24); //lampe 2
      delay(100);
      mySwitch.send(16766036, 24); //lampe 3 
      delay(100);
      mySwitch.send(16766228, 24); //étoile papier
      delay(100);
      ws2812 (0,NbLED, 255,0,0); //WS2812 en rouge
      }

  if (ValeurV0 == "première" || ValeurV0 == "un" || ValeurV0 == "1" || ValeurV0 == "hein"){
  mySwitch.send(16762196, 24); //lampe 1
  }

      if (ValeurV0 == "deuxième" || ValeurV0 == "deux" || ValeurV0 == "2" || ValeurV0 == "de"){
      mySwitch.send(16765268, 24); //lampe 2
      }

  if (ValeurV0 == "troisième" || ValeurV0 == "trois" || ValeurV0 == "3"){
  mySwitch.send(16766036, 24); //lampe 3 
  }

  if (ValeurV0 == "veilleuse" or ValeurV0 == "étoile"){
  mySwitch.send(16766228, 24); //étoile papier
  }

  if (ValeurV0 == "cuisine") {
  mySwitch.send(1975778, 24); //cuisine
  }

      if (ValeurV0 == "Freebox" or ValeurV0 == "télé" or ValeurV0 == "tele"){

      irsend.sendNEC(0xA55A38C7, 32);// InfraRouge - Ampli 5.1 sur ON (allume la télé via prise intélligente)
          
      irsend.sendNEC(0xFF20DF, 32);// InfraRouge - switch HDMI sur Freebox
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);
      delay(100);
         
      CommandeFreebox("power");// allume la Freebox
      delay(2000);// attendre 2 sec
      CommandeFreebox ("ok");// valider (sur bouton télévision)
      }

if (ValeurV0 == "ampli" or ValeurV0 == "l'ampli"){// Ampli 5.1
      irsend.sendNEC(0xA55A38C7, 32);
}

if (ValeurV0 == "blanc"){// Ruban LED
      ws2812 (0,NbLED, 255,255,255);
}
if (ValeurV0 == "rouge"){// Ruban LED
      ws2812 (0,NbLED, 255,0,0);
} 
if (ValeurV0 == "vert"){// Ruban LED
      ws2812 (0,NbLED, 0,255,0);
} 
if (ValeurV0 == "bleu"){// Ruban LED
      ws2812 (0,NbLED, 0,0,255);
}
if (ValeurV0 == "jaune"){// Ruban LED
      ws2812 (0,NbLED, 255,255,0);
}
if (ValeurV0 == "orange"){// Ruban LED
      ws2812 (0,NbLED, 255,127,0);
}
if (ValeurV0 == "violet"){// Ruban LED
      ws2812 (0,NbLED, 127,0,255);
}

}//V0

BLYNK_WRITE(V1){// éteint ***
String ValeurV1 = param.asStr();
Serial.print("éteint : ");
Serial.println(ValeurV1);

ws2812 (0,8, 255,0,0);//controle
ws2812 (0,8, 0,0,0);
 
  if (ValeurV1 == "tout" or ValeurV1 == "tous" or ValeurV1 == "tu"){
  mySwitch.send(16762193, 24); //lampe 1
  delay(100);
  mySwitch.send(16765265, 24); //lampe 2
  delay(100);
  mySwitch.send(16766033, 24); //lampe 3 
  delay(100); 
  mySwitch.send(16766225, 24); //étoile papier
  delay(100);
  ws2812 (0,NbLED, 0,0,0); //WS2812
  }
  
      if (ValeurV1 == "première" || ValeurV1 == "un" || ValeurV1 == "1" || ValeurV1 == "hein"){
      mySwitch.send(16762193, 24); //lampe 1
      }

  if (ValeurV1 == "deuxième" || ValeurV1 == "deux" || ValeurV1 == "2" || ValeurV1 == "de"){
  mySwitch.send(16765265, 24); //lampe 2
  delay(100);
  }

      if (ValeurV1 == "troisième" || ValeurV1 == "trois" || ValeurV1 == "3"){
      mySwitch.send(16766033, 24); //lampe 3 
      delay(100);
      }

  if (ValeurV1 == "veilleuse" or ValeurV1 == "étoile"){
  mySwitch.send(16766225, 24); //étoile papier
  }

  if (ValeurV1 == "cuisine"){
  mySwitch.send(1975778, 24); //cuisine
  }
  
  if (ValeurV1 == "Freebox" or ValeurV1 == "télé"){
  CommandeFreebox ("power");// éteint la Freebox

  //la télé est éteinte via l'ampli HDMI
  //irsend.sendNEC(0x2FD48B7, 32);// InfraRouge - TV Toshiba sur OFF
  //delay(40);
  //irsend.sendNEC(0xFFFFFF, 32);
  delay(100);
  irsend.sendNEC(0xA55A38C7, 32);// InfraRouge - Ampli 5.1 sur OFF 
  }
  
      if (ValeurV1 == "ampli" or ValeurV1 == "l'ampli"){// Ampli 5.1
      irsend.sendNEC(0xA55A38C7, 32);
      }
      
if (ValeurV1 == "blanc" or ValeurV1 == "rouge" or ValeurV1 == "vert" or ValeurV1 == "bleu" or ValeurV1 == "jaune" or ValeurV1 == "orange" or ValeurV1 == "violet"){// Ruban LED
      ws2812 (0,NbLED, 0,0,0);
} 

}//V1

/****************************************** Switch HDMI  - InfraRouge *********************************/
BLYNK_WRITE(V2){// HDMI ***
String ValeurV2 = param.asStr();
Serial.print("HDMI  : ");
Serial.println(ValeurV2);

if (ValeurV2 == "Freebox"){
      irsend.sendNEC(0xFF20DF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32); 
  }//if

  if (ValeurV2 == "Netflix"){
      irsend.sendNEC(0xFF10EF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);
  }//if

  if (ValeurV2 == "Kodi" or ValeurV2 == "mediacenter" or ValeurV2 == "libreelec"){
      irsend.sendNEC(0xFF50AF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);  
  }//if

}//V2

/************************************* Ampli 5.1  - InfraRouge ************************************/
BLYNK_WRITE(V3){// monte/augmente l'ampli de ***
int ValeurV3 = param.asInt();
Serial.print("monte le volume de : ");
Serial.println(ValeurV3);

ws2812 (8,8+ValeurV3, 255,0,0);//controle
ws2812 (8,8+ValeurV3, 0,0,0);

  if (ValeurV3){
  
for (int i=0; i <= ValeurV3*2; i++){
Serial.println(ValeurV3);  
irsend.sendNEC(0xA55A50AF, 32);
delay(40);  
}//for
  }//if
  
}//V3

BLYNK_WRITE(V4){// baisse/diminue l'ampli de ***
int ValeurV4 = param.asInt();
Serial.print("baisse le volume de : ");
Serial.println(ValeurV4); 

ws2812 (8,8+ValeurV4, 255,0,0);//controle
ws2812 (8,8+ValeurV4, 0,0,0);

   if (ValeurV4){
  
for (int i=0; i <= ValeurV4*2; i++)
{
Serial.println(ValeurV4);  
irsend.sendNEC(0xA55AD02F, 32);
delay(40);
}//for
  }//if
  
}//V4

BLYNK_WRITE(V5){// coupe/remet l'ampli
int ValeurV5 = param.asInt();

if (ValeurV5 == 1){
Serial.println(ValeurV5);  
irsend.sendNEC(0xA55A48B7, 32);
  }//if
  
}//V5

/***************************************** Chaines Freebox - Webhook ************************/

BLYNK_WRITE(V6){// Freebox/regarder ***
String ValeurV6 = param.asStr();
Serial.print("regarder : ");
Serial.println(ValeurV6);

//définition des chaines
if (ValeurV6=="Mosaïque" or ValeurV6=="mosaïque" or ValeurV6=="panel") {CommandeFreebox("0");}
if (ValeurV6 == "TF 1") {CommandeFreebox("1");}
if (ValeurV6 == "France 2") {CommandeFreebox("2");}
if (ValeurV6== "France 3") {CommandeFreebox("3");}
if (ValeurV6 == "Canal +" or ValeurV6=="Canal") {CommandeFreebox("4");}
if (ValeurV6 == "France 5") {CommandeFreebox("5");}
if (ValeurV6 == "M 6") {CommandeFreebox("6");}
if (ValeurV6=="Arte") {CommandeFreebox("7");}
if (ValeurV6=="C 8") {CommandeFreebox("8");}
if (ValeurV6=="W 9") {CommandeFreebox("9");}
//a partir de 2 chiffres, ça ne marche plus ?!?


if (ValeurV6=="pause") {CommandeFreebox("play");}
if (ValeurV6=="direct") {
CommandeFreebox("green");
delay(2000);
CommandeFreebox("ok");
}

if (ValeurV6=="programme") {CommandeFreebox("epg");}
if (ValeurV6=="menu") {CommandeFreebox("green");}
if (ValeurV6=="maison") {CommandeFreebox("home");}
if (ValeurV6=="ok") {CommandeFreebox("ok");}
if (ValeurV6=="haut") {CommandeFreebox("up");}
if (ValeurV6=="bas") {CommandeFreebox("down");}
if (ValeurV6=="droite") {CommandeFreebox("right");}
if (ValeurV6=="gauche") {CommandeFreebox("left");}

if (ValeurV6=="dvd"){
CommandeFreebox("home");
delay(2000);
CommandeFreebox("right");
delay(1000);
CommandeFreebox("right");
delay(1000);
CommandeFreebox("right");
delay(1000);
CommandeFreebox("ok");
}

if (ValeurV6=="TV"){
CommandeFreebox("home");
delay(2500);
CommandeFreebox("ok");
}

/*************************************** Regarder Freebox Netflix ou Kodi ***************************************/

if (ValeurV6 == "Freebox" or ValeurV6 == "télé"){
      irsend.sendNEC(0xFF20DF, 32);// InfraRouge - switch HDMI sur Freebox
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);
      //la télé est allumé via l'ampli HDMI
      //delay(100);
      //irsend.sendNEC(0x2FD48B7, 32);// InfraRouge - TV Toshiba sur ON
      //delay(40);
      //irsend.sendNEC(0xFFFFFF, 32);
      delay(100);
      irsend.sendNEC(0xA55A38C7, 32);// InfraRouge - Ampli 5.1 sur ON     
  
      CommandeFreebox("power");// allume la Freebox
      delay(2000);// attendre 2 sec
      CommandeFreebox ("ok");// valider (sur bouton télévision)
      }

if (ValeurV6 == "Netflix"){
      //Ampli (qui allume la télé)
      irsend.sendNEC(0xFF10EF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);  
delay(100);
      //HDMI sur Netflix
      irsend.sendNEC(0xFF10EF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32); 
}
if (ValeurV6 == "Kodi"){
      //Ampli (qui allume la télé)
      irsend.sendNEC(0xFF10EF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);  
delay(100);
      //HDMI sur Kodi
      irsend.sendNEC(0xFF50AF, 32);
      delay(40);
      irsend.sendNEC(0xFFFFFF, 32);
}

}//V6

/********************************************* couper les lumières et la télé ***********************/

BLYNK_WRITE(V7){// on va se coucher
int ValeurV7 = param.asInt();

if (ValeurV7){
// lumières
mySwitch.send(16762193, 24); //lampe 1
  delay(100);
  mySwitch.send(16765265, 24); //lampe 2
  delay(100);
  mySwitch.send(16766033, 24); //lampe 3 
  delay(100); 
  mySwitch.send(16766225, 24); //étoile papier
  delay(100);
  ws2812 (0,NbLED, 0,0,0); //WS2812

CommandeFreebox ("power");// éteint la Freebox

irsend.sendNEC(0xA55A38C7, 32);// éteint l'ampli (qui éteint la télé)    
}
  
}//V7

/****************************** Ruban LED WS 2812 via l'appli Blynk *****************************/

BLYNK_WRITE(V8){ //zeRGBa de Blynk (http://docs.blynk.cc/#widgets-controllers-zergba)
  
  int r = param[0].asInt(); //rouge
  int v = param[1].asInt(); //vert
  int b = param[2].asInt(); //bleu

ws2812 (0,NbLED, r,v,b);//WS2812

}//V8


void CommandeFreebox(String MotCle){ /************************************* Fonction envoie des codes Freebox **************************************/
// WebHook Blynk avec : http://hd1.freebox.fr/pub/remote_control?code=86700567&key=/pin/
//&key=<touche>&long=true
//&key=<touche>&repeat=<n>

Blynk.virtualWrite(10, MotCle);
}

void ws2812 (int debut, int fin, int rouge, int vert, int bleu) /************** Fonction d'affichage des LED du ruban WS2812 *****************************/
{
    for(int i=debut;i<=fin;i++){
    // position de la LED (0=1er), couleurs RVB (de 0 à 255)
    pixels.setPixelColor(i, pixels.Color(rouge,vert,bleu)); 
    pixels.show(); // update couleurs
  }  
}//WS2812


void loop() { /**************************** LOOP *************************/
Blynk.run();      
}//loop


Ce code sera évidement adapté pour votre cas. Pour le miens, lorsque mon ampli 5.1 s’allume, il commande une multiprise « intelligente » qui allume la télé, le caisson basse et autre.
Le seul truc que je n’ai pas pu faire c’est changer les chaines de la Freebox qui ont 2 chiffres. Même en testant une URL dédié à ça, pas moyen.

L’électronique

Je suis partie d’un Teensy 3.2, un Arduino Uno n’est pas suffisant en terme de puissance.

Un ESP01 relié l’ensemble au WiFi, le module RX4333 envoie les codes en 433 mhz. 2 LED infra-rouge relié en série envoient les codes infra-rouge.
Le ruban LED (WS2812) est aussi relié au 5 volts.

L’ensemble est alimenté via un transfo 5 volts, un régulateur 3.3 volts alimente le ESP01. Un condensateur de 1000 uF/25V stabilise la tension (et pour protéger le ruban LED).

Le montage

Les composants électroniques sont fixés sur une plaque et reliés entrent eux par le dessous. Simple mais suffisant.
Le ruban LED s’enroule autour des montants.

J’ai fais une armature avec mon imprimante 3D. Tout est juste emboité, un trou est prévu à la base pour mettre un connecteur pour le transfo.
L’ensemble est coiffé par un bocal (à sucre je crois) de chez Ikea.

Fichier 3D

IFTTT et Blynk

J’utilise aussi le WebHook de IFTTT pour envoyer les mots clés qui seront reçu par Blynk et le WebHook de Blynk pour envoyer du code sur Teensy.

EX : Envoie le mot clé (TextField) sur l’IP du serveur Blynk/LeTokenBlynk, sur la VirtualPin V0

Dans le code Arduino :

BLYNK_WRITE(V0)
String ValeurV0 = param.asStr() (si c’est un mot)
String ValeurV0 = param.asInt() (si c’est un chiffre)

 

source 01 

Catégorie : Electronique | Commenter
février 18

Récupérer les codes 433 mhz et infra-rouge d’une télécommande

Le but est d’afficher les codes des télécommandes du style commande de lampe, porte de garage et autre fonctionnant sous 433 mhz (RX433) mais aussi ceux des télécommandes infra-rouge de télévision au autre.

On pourra donc ensuite, grâce à une autre montage, envoyer ces codes et piloter n’importe quoi !

Le montage

Simple, un Arduino Nano, une diode réceptrice infra-rouge et un récepteur 433 mhz.

Le code Arduino

//InfraRouge
#include <IRremote.h>
int recvPin = 11; //pin Arduino pour récepteur InfraRouge (TOSP4838)
IRrecv irrecv(recvPin);

//RX433
#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
decode_results results;

void  setup ( )
{
  Serial.begin(9600);
  irrecv.enableIRIn();
  irrecv.blink13(true);//allume la LED interne lors de l'envoie InfraRouge
  mySwitch.enableReceive(0);  // Récepteur RX433 (XY-MK-5V) sur pin 2 de Arduino Uno et Nano
}

// affichage des codes InfraRouge
void  ircode (decode_results *results)
{
  // Panasonic
  if (results->decode_type == PANASONIC) {
    Serial.print(results->address, HEX);
    Serial.print(":");
  }
  Serial.print(results->value, HEX);
}//void

// afficahge des codes encodés
void  encoding (decode_results *results)
{
  switch (results->decode_type) {
    default:
    case UNKNOWN:      Serial.print("Inconnu");       break ;
    case NEC:          Serial.print("NEC");           break ;
    case SONY:         Serial.print("SONY");          break ;
    case RC5:          Serial.print("RC5");           break ;
    case RC6:          Serial.print("RC6");           break ;
    case DISH:         Serial.print("DISH");          break ;
    case SHARP:        Serial.print("SHARP");         break ;
    case JVC:          Serial.print("JVC");           break ;
    case SANYO:        Serial.print("SANYO");         break ;
    case MITSUBISHI:   Serial.print("MITSUBISHI");    break ;
    case SAMSUNG:      Serial.print("SAMSUNG");       break ;
    case LG:           Serial.print("LG");            break ;
    case WHYNTER:      Serial.print("WHYNTER");       break ;
    case AIWA_RC_T501: Serial.print("AIWA_RC_T501");  break ;
    case PANASONIC:    Serial.print("PANASONIC");     break ;
    case DENON:        Serial.print("Denon");         break ;
  }
}

// dump les résultats
void  dumpInfo (decode_results *results)
{
  // Check if the buffer overflowed
  if (results->overflow) {
    Serial.println("IR code too long. Edit IRremoteInt.h and increase RAWBUF");
    return;
  }

  // Show Encoding standard
  Serial.print("Encodage  : ");
  encoding(results);
  Serial.println("");

  // Show Code & length
  Serial.print("Code      : ");
  ircode(results);
  Serial.print(" (");
  Serial.print(results->bits, DEC);
  Serial.println(" bits)");
}

//structure
void  dumpRaw (decode_results *results)
{
  // Print Raw data
  Serial.print("Timing[");
  Serial.print(results->rawlen-1, DEC);
  Serial.println("]: ");

  for (int i = 1;  i < results->rawlen;  i++) {
    unsigned long  x = results->rawbuf[i] * USECPERTICK;
    if (!(i & 1)) {  // even
      Serial.print("-");
      if (x < 1000)  Serial.print(" ") ;
      if (x < 100)   Serial.print(" ") ;
      Serial.print(x, DEC);
    } else {  // odd
      Serial.print("     ");
      Serial.print("+");
      if (x < 1000)  Serial.print(" ") ;
      if (x < 100)   Serial.print(" ") ;
      Serial.print(x, DEC);
      if (i < results->rawlen-1) Serial.print(", "); //',' not needed for last one
    }
    if (!(i % 8))  Serial.println("");
  }
  Serial.println("");                    // Newline
}

//+=============================================================================
// Dump out the decode_results structure.
//
void  dumpCode (decode_results *results)
{
  // Start declaration
  Serial.print("unsigned int  ");          // variable type
  Serial.print("rawData[");                // array name
  Serial.print(results->rawlen - 1, DEC);  // array size
  Serial.print("] = {");                   // Start declaration

  // Dump data
  for (int i = 1;  i < results->rawlen;  i++) {
    Serial.print(results->rawbuf[i] * USECPERTICK, DEC);
    if ( i < results->rawlen-1 ) Serial.print(","); // ',' not needed on last one
    if (!(i & 1))  Serial.print(" ");
  }

  // End declaration
  Serial.print("};");  // 

  // Comment
  Serial.print("  // ");
  encoding(results);
  Serial.print(" ");
  ircode(results);

  // Newline
  Serial.println("");

  // Now dump "known" codes
  if (results->decode_type != UNKNOWN) {

    // Some protocols have an address
    if (results->decode_type == PANASONIC) {
      Serial.print("unsigned int  addr = 0x");
      Serial.print(results->address, HEX);
      Serial.println(";");
    }

    // All protocols have data
    Serial.print("unsigned int  data = 0x");
    Serial.print(results->value, HEX);
    Serial.println(";");
  }
}

void  loop ( )
/************************************************** InfraRouge ******************************************/
{
  decode_results  results;        // Somewhere to store the results

  if (irrecv.decode(&results)) {  // Grab an IR code
    dumpInfo(&results);           // Output the results
    dumpRaw(&results);            // Output the results in RAW format
    dumpCode(&results);           // Output the results as source code
    Serial.println("");           // Blank line between entries
    irrecv.resume();              // Prepare for the next value
  }
 /**************************************************** RX433 ********************************************/
 if (mySwitch.available()) 
  {  
    int value = mySwitch.getReceivedValue();
    Serial.println("RX433");
    
    if (value == 0) {
      Serial.print("Codage inconnu");
    } else 
    {
      Serial.print("Reçu ");
      Serial.print( mySwitch.getReceivedValue() );
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocole: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }
    mySwitch.resetAvailable();
  }//RX433
  
}//loop

Codes infra-rouge

Il y a plusieurs protocoles :

Pour  Sony et  RC5/6, chque transmission doit être répétés 3 fois !
ATTENTION :
la librairie IRremote.h ne semble pas pouvoir envoyer des codes codés sur plus de 32bits.
Les RC6, 36 doivent donc êtres envoyer en raw, qui prennent plus de taille mémoire.
L’envoie des codes se fera avec la librairie IRremote.h
Exemple : (0x devant le code) et le nombre de bits
irsend.sendNEC(0xA55A38C7, 32);

Codes RX433

L’envoie se fera avec la librairie RCSwitch.h
Exemple
mySwitch.send(1975778, 24);
Catégorie : Teensy/Arduino | Commenter
février 18

Le Teensy en WiFi avec ESP01

Faire communiquer le Teensy en WiFi est simple et pas chère avec ESP01.
Il faut juste au préalable le configurer et terme de vitesse, mode serveur/client et bien sur nom et clé WiFi, via une liaison série.

le Teensy est alimenté en 5 Volts mais le esp01 à besoin de 3.3 Volts. Cependant, même si le Teensy dispose d’une sortie 3.3 volts, elle est limité à 100 mA, insuffisant pour le ESP01. On doit donc utiliser un régulateur 3.3 Volts.

 

ATTENTION : bien couper le strap situé sous le Teensy car il sera alimenté via la pin Vin et pas via la prise USB

Le code Arduino

Permettant envoyer/recevoir des commande AT, et donc de programmer le ESP01

/*
0 (RX) Arduino ou Teensy sur TX ESP01
1 (TX) Arduino ou Teensy sur RX ESP01

(attention un copier/coller dans le moniteur serie ajoute un espace à la fin des commandes !)

la commande  AT renvoie OK et la LED bleu de EPS01 s'allume brievement
(Si pas de retour, changer la vitesse à 115200)

vitesse de la liaison
AT+CIOBAUD=9600

ResetESP10
AT+RST

Configurer en mode client et serveur
AT+CWMODE=3

Afficher les réseaux WiFi
AT+CWLAP

Connecter au WiFi
AT+CWJAP="nom_ssid","clé_wifi"

Afficher son adresse IP (la 1er est le serveur et la 2e le client)
AT+CIFSR (serveur = 192.168.4.1 - client=192.168.0.32)

AT+GMR
Afficher la version du firmware

 */
int vitesse = 9600; // Use baud rate 115200 during firmware update
void setup() {

    // du moniteur serie vers Arduino/Teensy
    Serial.begin(vitesse);

    // Arduino/Teensy vers ESP01
    Serial1.begin(vitesse);

}

void loop() {

    // ESP01 vers serie
    if ( Serial1.available() ) {
        Serial.write( Serial1.read() );
    }

    // Send bytes from computer back to ESP8266
    if ( Serial.available() ) {
        Serial1.write( Serial.read() );
    }

}

Et donc, en rajoutant du code, on peut facilement contrôler le Teensy via WiFi !

//série

#define ESP8266_BAUD 9600

#include <SoftwareSerial.h>

#define HWSERIAL Serial1 //pin RX1=0, TX1=1 du TeensyLC, Teensy 3.2


//ESP10

#include <ESP8266_Lib.h>

SoftwareSerial EspSerial(0, 1);

ESP8266 wifi(&EspSerial);

Catégorie : Teensy/Arduino | Commenter
janvier 6

Serveur Blynk local

Blynk est un service génial permettant de contrôler les entrées/sorties de beaucoup de matériels (Arduino, raspberryPi, Teensy…) via une appli smartphone ou du code arduino.
Blynk peut aussi utiliser les capteurs du smartphones pour son projet.
La création d’un compte octroi un cloud permettant la liaison via Internet mais du coup, une latence qui peut être gênante parfois.

Heureusement, on peut facilement installer son propre serveur Blynk, en Java, sur un raspberry Pi (une version 2 avec Raspbian Lite dans mon exemple).
L’avantage aussi est de s’affranchir de la limite « d’energy balance » du projet Blynk car sur son propre serveur, on peut monter cette valeur.

Installer Java

sudo apt-get update
sudo apt-get install oracle-java8-jdk

Faire : java -version pour afficher le numéro de version

Télécharger et installer Blynk

Allez chercher l’adresse sur le site : https://github.com/blynkkk/blynk-server/
(ex: wget « https://github.com/blynkkk/blynk-server/releases/download/v0.28.9/server-0.28.9-java8.jar »)

Démarrer Blynk
(modifier le numéro de java selon)
java -jar server-0.28.9-java8.jar -dataFolder /home/pi/Blynk

Un Ctrl+C ferme le serveur, pour redémarrer faire
java -jar server-0.28.9-java8.jar -dataFolder /home/pi/Blynk

Allez sur : https://ip_du_raspi:9443/admin

Utiliser au départ admin@blynk.cc et admin pour rentrer dans l’interface, ajouter ensuite un utilisateur avec login et password et supprimer ensuite le compte admin.

Mettre à jour le server

Tuer le processus, via son numéro PID

ps -aux | grep java
sudo kill ***

Télécharger et installer la nouvelle version

Penser à modifier le crontab

Source

 

Blynk au démarrage du Raspi

Editer le crontab
sudo crontab -e (sudo si le dossier Blynk est root:root, sinon crontab -e)
ajouter
@reboot java -jar /home/pi/server-0.28.9-java8.jar -dataFolder /home/pi/Blynk &

Pare-feux

Au besoin, ajouter des règles de redirection à sa box :

Blynk server has 3 ports open for different security levels.
8441 – SSL/TLS connection for hardware
8442 – plain TCP connection for hardware (no security)
9443 – Webhook SSL
8080 – Webhook

Modification des ports en début 2018
443 – mutual authentication (mutual SSL) connection for Mobile Apps

 

A partir de la, il suffit de créer un projet dans l’appli Blynk et de choisir « custom » pour le serveur, avec l’adresse IP de son Raspberry ou l’adresse IP externe de sa box, si l’on souhaite un accès via une connexion 4G.

L’appli envoie le token du projet par mail mais on peut le récupérer via la rubrique « users » du serveur Blynk.

Configuration

On peut aussi créer et personnaliser un fichier server.properties selon des besoins particuliers mais ce n’est pas indispensable.
En cas de réinstallation du serveur, il suffira de sauvegarder  ces fichiers.

sudo nano server.properties (dans le même dossier que le *.jar)
https://github.com/blynkkk/blynk-server/blob/master/server/core/src/main/resources/server.properties

remplacer
#server.host=test.blynk.cc
par
server.host=192.168.0.30

si une appli utilise le port 8080 (apache…) ou peut le changer
http.port=8181

en cas de blocage via webhook
webhooks.frequency.user.quota.limit=-1 to server properties.

Erreur de flow (trop de requètes)
If sending hundreds of requests is what you need for your product you may increase flood limit on local server and within Blynk library.
For local server you need to change user.message.quota.limit property within server.properties file :
#100 Req/sec rate limit per user.
user.message.quota.limit=100

sudo nano mail.properties
On peut recevoir le token via Gmail… créer un fichier mail.properties dans le même dossier que je ***.jar
sudo nano mail.properties
ATTENTION : ne fonctionne pas si la « validation en 2 étapes » est activé sur le compte Google
ajouter dedans
mail.smtp.auth=true
mail.smtp.starttls.enable=true
mail.smtp.host=smtp.gmail.com
mail.smtp.port=587
mail.smtp.username=YOUR_EMAIL_HERE
mail.smtp.password=YOUR_EMAIL_PASS_HERE

Webhook

Une des fonctions les plus puissante de Blynk est l’utilisation de webhook, des URL qui permettent de déclencher des actions sur Blynk.
Par exemple, via IFTTT : https://son_ip_publique:9443/le_token_du_projet/update/d10?value=1

enverra la valeur 1 sur la pin virtuel numéro 10 de Blynk.

 

 

 

 

Catégorie : Non classé | Commenter
novembre 19

Les applications de gestion de mot de passe

Toutes ces applications ont le même principe, regrouper ses mots de passe dans un coffre-fort numérique (un fichier crypté), protégé par un mot de passe maître.
L’ensemble sera synchronisé via Internet entre navigateur Web et smartphone.

C’est l’application qui se charge de générer un mot de passe long, compliqué et différent pour chaque compte. Vous n’avez qu’à vous rappeler du mot de passe maître.

Les ténors

LastPass et DashLane mais je préfère m’en écarter car elles sont, en partie, payantes et sur des serveurs très connus, donc soumises à de potentielles attaques.

Bitwarden

Open-source, interface sur le Web (en anglais),  extension Chrome en français avec beaucoup d’options.

Sur la page de connexion d’un site web (login et mot de passe à créer), l’application peut générer un mot de passe complexe et remplit une entrée avec le login choisi, le mot de passe et l’adresse Web de la page de connexion.

De retour sur cette page (l’adresse doit être identique à celle mémorisée dans Bitwarden), un simple clic sur l’icone Bitwarden remplira automatiquement les champs.

  

On a l’application gratuite, à l’apparence identique et toujours en Français sur  Android.

La syncro se fait via un serveur sécurisé (même les gestionnaires du serveur ne peuvent lire les mots de passe) chez Microsoft Azure.

… »bitwarden traite et stocke toutes les données de manière sécurisée dans le cloud Microsoft Azure à l’aide de services gérés par l’équipe de Microsoft.
bitwarden ne gère pas directement l’infrastructure ou la sécurité du serveur. Toutes les données sont sauvegardées plusieurs fois, à l’aide des services fournis par Microsoft Azure… »

Bitwarden indique que l’on peut l’installer sur son propre serveur Linux, mais ce n’est pas évident pour le commun des mortels.

Point positif, pas d’installation à faire sur l’ordinateur, tout se fait en ligne ou via les applications Chrome et Android.

Point négatif, la page web du service en anglais.

Endpass

Belle interface, en français et une extension Chrome. Installable sur PC et Mac avec une version classique ou portable (c’est-à-dire à installer par exemple sur une clé USB ou Dropbox/GoogleDrive/OneDrive…). Endpass sera donc accessible sur différents ordinateurs ou smartphones.

La syncro des mots de passe peut se faire via différents services Internet (dropbox, Google Drive…)

La consommation en mémoire est un peut élevée (comparé à Keepass par exemple).

Points positifs, la qualité de l’interface et des catégories (dont les cartes bancaires et autres), l’ajout possible de champs et l’auto-remplissage dans le navigateur.

Point négatif, l’application Android (en français) gratuite est limitée à 20 entrées, la version payante coûte presque 10€.

Keepass

Logiciel open-source, en version installable ou portable, en anglais mais on peut installer facilement une traduction française.


Beaucoup de réglages et de possibilités… dont l’auto-remplissage via un raccourci clavier même pour les logiciels installés sur le PC (autre que le navigateur).

 

Points positifs :

  • open-source
  • version portable (à installer dans Dropbox, Google Drive, OneDrive… par exemple)
  • la personnalisation du remplissage des champs (ex: login1, tab, login2, tab password, enter)
  • l’auto-remplissage via un raccourci clavier (même pour un programme installé sur le PC).
  • la reconnaissance de l’adresse Web par un mot (ex: *dropbox* reconnait toutes les pages du site Dropbox)
  • l’application Android  gratuite.
  • beaucoup d’options et de plugins disponibles

Point négatif :

  •  l’interface, un peu « old school » et les nombreux réglages peuvent rebuter les moins « geeks ».

Zenpass

15 identifiants maxi avec l’offre gratuite, ensuite il faut payer pour chaque mot de passe supplémentaire.
Les serveurs de ZenyPass sont hébergés par la société Digital Ocean, et sont situés à Francfort, Allemagne.

Point positif: 

  • Open-source,
    Le paiement se fait en une seule fois, sans abonnement.

Points négatifs :

  • Pas d’auto-remplissage automatique, il faut d’abord passez par la page Zenpass pour ensuite allez sur le site
  • Pas d’extension navigateur
  • Pas d’application smartphone

 

Comparatifs en 2016

Comparatifs en 2017

Catégorie : LOGICIELS | Commenter
octobre 5

Un monitoring simple pour le raspberry

Il est bien d’avoir accès aux infos de son raspi parfois SANS passer par l’installation d’un système de monitoring par le Web, qui nécessite un server apache et PHP.

Pour avoir ces infos via la console, EZmonitoring suffit.

Installation

A modifier selon la version et cours

wget --content-disposition http://www.ezservermonitor.com/esm-sh/downloads/version/2.2
unzip ezservermonitor-sh_v2.2.zip
chmod u+x eZServerMonitor.sh

Une fois fait, la commande

/eZServerMonitor.sh --all

Permet d’avoir toutes les infos.

Catégorie : RASPBERRY PI | Commenter
octobre 1

Resilio sur disque-dur Freebox

Resilio (ex BitTorrentSyncro) est un système permettant de synchroniser des dossiers entre divers appareils tel que Raspberry, NAS, PC…
Le pitch içi étant de synchroniser les dossiers  présents sur un serveur Linux avec ceux présents sur le disque-dur interne d’une Freebox revolution, via un raspberry Pi (version 1 dans mon cas) connecté en réseaux sur la Freebox.

Resilio Synchro

Installer d’abord une version Lite de Raspbian et la configurer (date, langue…).
Pour infos, le faite de placer un fichier appelé ssh (sans extension) à la racine de la carte permet d’avoir accès au Raspi directement.

Installer ensuite Resilio, la version varie selon que l’on utilise un Raspi 1 ou un Raspi 3.
Pensez à faire un apt-get update et upgrade avant.

Pour mettre Resilio au démarrage

sudo systemctl enable resilio-sync
sudo nano /usr/lib/systemd/user/resilio-sync.service
changer "WantedBy=multi-user.target" par "WantedBy=default.target"
sudo systemctl --user start resilio-sync

Ensuite, se connecter sur <ip-du-raspi>:8080/gui/

La belle interface de Resilio devrait apparaitre. Indiquer ensuite la clé, fourni par le Resilio source, et choisir le dossier de le Freebox qui sera syncronisé.

Montage du disque-dur Freebox

 

Créer un dossier dans le dossier « media » (dédié au disque externe) du raspi.

sudo mkdir /media/freebox
sudo mkdir /media/freebox/Rtorrent/

leurs donner des droits d’accès total

sudo chmod -R 777 /media/freebox/

Créer le montage

Edité le fichier de montage de disque

sudo nano /etc/fstab
//mafreebox.freebox.fr/Disque\040dur\Rtorrent /media/freebox/Rtorrent cifs _netdev,rw,nofail,x-systemd.automount,x-systemd.device-timeout=10,guest,iocharset=utf8,uid=1000,gid=1000,sec=none,file_mode=0777,dir_mode=077

uid et gid 1000 est l’utilisateur et groupe du Raspberry (afficher avec la commande id).

Si mafreebox.freebox.fr renvoie une erreur lors du montage, on peut remplacer par 192.168.0.254 ou par freebox-server.local.

La 1er partie indique que le dossier Rtorrent situé sur le disque-dur de la Freebox. Le 2e partie indique de le dossier Rtorrent, inclus dans freebox, lui même inclus dans media sera syncronisé.

Monter le disque au démarrage du Raspi

Créer un fichier

sudo nano /etc/freebox.credentials

Ecrire dedans

username=
password=

Monter le disque dur, une fois pour toute

sudo mount -a

La commande df permet de voir si le disque-dur est bien monté.

Voila, dans mon cas, tout ce qui est téléchargé sur mon Rtorrent est synchronisé avec ma Freebox…. un bonheur !

source 1

source 2

Catégorie : RASPBERRY PI | Commenter
septembre 23

Ambilight avec OpenElec et WS2801

J’ai déjà fait un post sur Ambilight MAIS avec un Raspi un Arduino et un WS2812. Cette version est plus simple et utilise un Raspberry Pi 3 (avec OpenElec) et un ruban LED WS2801.

Pour le placement des LED sur la télé, voir ce post.

Branchement

Le Raspi et le ruban LED est alimenté via une petite alim ATX 5V/6A,

Le WS2801 contient 32 LED par mètre et consomme 1.8A par mètre (50mA/LED), avec toutes les LED en blanc (source)

bien que ma mesure, avec 89 LED allumé en blanc et le rapi ne consomme que 1 A.
Théoriquement on devrait avoir 0.05 X 89 = 4.45 A. J’ai testé avec une autre alim, c’est idem…. j’ai pas de réponse la dessus.

  • +5V sur le Raspi et le fil rouge du WS2801
  • GND sur le Raspi et le fil noir/rouge du WS2801
  • CI du WS2801 sur SPI_clock du Raspi
  • DI du WS2811 sur CPI_mosi du Raspi

Logiciel

Installer l’image d’Openelec pour raspberry.

Une fois fait, installer Hyperion. Même si on peut l’installer en ligne de commande, le plus simple est de passer par le logiciel Hypercon (en Java) à installer sur Windows.

Il permet d’installer Hyperion sur le raspi (via une connexion SSH) et surtout de paramétrer les LED et autres.

Dans la rubrique hardware :

  • type = WS2801
  • Output = /dev/spidev0.0
  • baudrate = 1000 000

Le reste dépend de votre configuration et choix.

Dans le rubrique Grabber :

  • internal frame garbber = enabled
  • External/Kodi checker = enabled
  • SSH/system = Openelec /LE

Dans la rubrique SSH :

Indiquer l’adresse IP de son Raspi, le username Openelec (root), le password (openelec) puis faire « connect ».

Faire « stop hyperion »

Cliquer sur « Create Hyperion Configuration » avant d’envoyer cette configuration, via « Send config ».

Faire « start hyperion » pour actualiser la config.

En cas de problème

Vérifier que les ports SPI du Raspi sont activés via le fichier config.tx présent sur la carte SD du raspi.

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

 

 

Catégorie : RASPBERRY PI | Commenter