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
juillet 4

La création d’un circuit imprimé

Divers logiciels, gratuits ou payants, existent pour créer des circuits imprimés. Je vais préférer les gratuits et les simples d’accès, dans mon cas Fritzing.

Fritzing

Ce logiciel gratuit (en beta donc à voir ensuite) permet de créer un circuit imprimer à partir d’un schéma théorique ou via la liaison de composant virtuel disposé sur une platine d’essais du style breadboard.

La prise en main est relativement simple, de nombreux composants sont déjas présent dans la bibiliothèque, de plus il existe une large communauté d’utilisateurs et de nombreux tuto dessus.

Par contre, le logiciel donne peu d’infos et d’options pour la création et surtout l’exportation du circuit, en vu de sa fabrication. Même si bouton « faire fabriquer » envoie sur le site de la société, pour ma part, ça ne fonctionne pas.

Importation de composants

Fritzing permet d’incorporer de nombreux composants, dessinés par des amateurs ou fournis par des vendeurs de composants.
Justement, un des leaders, adafruit, à toute une librairie que l’on peut incorporer dans Fritzing, il suffit de télécharger un zip sur Github et de suivre ce tuto.

Création du circuit

Le plus simple est de cabler les éléments ensemble sur la vue « platine »

fritzing-platine01

et ensuite, ont les places sur une des 2 faces du CI.
Bine faire attention au sens des composants, en effet, Fritzing parle de « dessus, dessous » avec le bouton en bas de son interface et de « supérieur, inférieur » dans le menu propriétés du CI, dans la colonne de droite. Mais tout dépend de comment on veux placer ces composants évidement.

fritzing-dessus fritzing-PCB02

Les tracés du dessus sont en jaune et ceux du dessous en orange. On aurait préféré des couleurs moins proches ou la possibilité de masquer les couches mais bon, c’est du gratuit.

Exportation

Fritzing permet d’exporter en PDF, plusieurs en faite mais e plus important pour un circuit en double-face est :

  • etch_copper_top, pour le dessus du circuit
  • etch_copper_bottom_mirror, pour le dessous du circuit

Ces 2 PDF, une fois imprimés et coller dos à dos (coté blanc de la feuille), permettent d’avoir un aperçu en taille réel du future circuit imprimé.

ATTENTION : pour ma part, l’exportation en PDF n’écrase pas les anciens, en cas de modif donc, pensez à effacer les PDF déjà créés.

Les fichiers contenant le mot « skil » affiche le coutour des composants et du CI.
Les fichiers contenant le mot « mask » affiche les trous du CI.
Les fichiers contenant le mot « paste_mask » affiche le plan de masse (à vérifier).

L’exportation en SVG génères des fichiers images vertorielles, pouvant être édités en autre avec Inscape.

L’exportation en Gerber génère un lot de fichiers contenant divers informations sur les composants utilisés (le circuit, les connexions, les pastilles…)

Vérification du circuit

Le logiciel (portable)  GerbV est très simple et permet d’avoir un aperçu du circuit et de masquer certaines pistes.

GerbV

Fabrication

Fritzing permet directement depuis sont interface d’allez sur son site, de créer un compte et de leur uploader le fichier natif de Fritzing. Il s’occupe ensuite de  la fabrication et l’envoie postale du CI. Les prix ne sont pas trop élevés.

On peut aussi passer par une autre société, il suffira d’envoyer par mail, selon ce que demande la société, un PDF contenant les 2 faces du CI, un ZIP des fichiers Gerber et parfois un fichier DRILL (pouvant être créé avec GerbV) pour le perçage.

gerbV - export DRIL

 

Pour ma part, dans la région j’ai trouvé la société Cilec, réactive et pas trop chère.

 

Catégorie : Electronique | Commenter