Utiliser une télécommande IR avec un noeud MyS.

Forum dédie aux capteurs et gateway mysensors.org
Fredok
Messages : 90
Inscription : 12 août 2016, 15:04

Utiliser une télécommande IR avec un noeud MyS.

Message par Fredok »

Bonjour à vous, voici un petit tuto pour transformer une vieille télécommande IR pour qu’elle devienne une télécommande/clavier pour DZ. J’ai utilisé un nœud Mysensors existant qui contenait une sonde de température, un capteur d’ouverture du Velux et de luminosité)

1) Matériel :
Un nœud Mysensors existant ou en faire un nouveau (arduino uno/pro/nano …et bien sur NRF24L01 ou autre solution)
De quoi communiquer avec cet arduino
Un capteur IR type TL1838 (0,35€ sur Al…ss ou 5€ les 50 ou encore un TL1838 monté sur un câble avec sortie Jack pour déporter le capteur IR)
Une vieille télécommande IR (avec protocole NEC très courant) j’utilise celle çi :
telecKeyes.jpg
telecKeyes.jpg (36.92 Kio) Consulté 4620 fois
Pour info :
CH- 0xFFA25D
CH 0xFF629D
CH+ 0xFFE21D
PREV 0xFF22DD
NEXT 0xFF02FD
PLAY/PAUSE 0xFFC23D
VOL- 0xFFE01F
VOL+ 0xFFA857
EQ 0xFF906F
0 0xFF6897
100+ 0xFF9867
200+ 0xFFB04F
1 0xFF30CF
2 0xFF18E7
3 0xFF7A85
4 0xFF10EF
5 0xFF38C7
6 0xFF5AA5
7 0xFF42BD
8 0xFF4AB5
9 0xFF52AD

Une Led RGB [optionnel mais utile] (genre KEYES KY-009 0,33€)

1.5) Déterminer les code IR de la télécommande

J’utilise sur un arduino de test le programme d’exemple livré avec la librairie IRremote.h

Code : Tout sélectionner

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */

#include <IRremote.h>

int RECV_PIN = 11;

IRrecv irrecv(RECV_PIN);

decode_results results;

void setup()
{
  Serial.begin(9600);
  // In case the interrupt driver crashes on setup, give a clue
  // to the user what's going on.
  Serial.println("Enabling IRin");
  irrecv.enableIRIn(); // Start the receiver
  Serial.println("Enabled IRin");
}

void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, HEX);
    irrecv.resume(); // Receive the next value
  }
  delay(100);
}
Il suffit de recopier le code et la touche correspondante qui apparait sur le moniteur série.

2) Montage
Le capteur IR possède 3 pins (Vcc=5V, Gnd et le signal S sur la pin 2)
La led RGB sur (Gnd et les pins PWM 3,5,6)
Les broches utilisées peuvent être modifiées, par contre pour la led RGB on doit prendre des pins pwm.
montage.jpg
montage.jpg (47.78 Kio) Consulté 4620 fois
3) Le programme Mysensors (v2 et +)
Attention, il contient aussi le code pour envoyer la température, la luminosité et l’état du velux donc à adapter.

Code : Tout sélectionner

#define MY_REPEATER_FEATURE
#define MY_DEBUG
#define MY_RADIO_NRF24
#include <Arduino.h>
#include <SPI.h>
#include <MySensors.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <Bounce2.h>
#include <IRremote.h>
//child
#define CHILD_ID_VELUX 1
#define CHILD_ID_LIGHTLEVEL 2
#define CHILD_ID_IRTEXT 3
#define CHILD_ID_TEMP 4
//PIN
#define PIN_IRREC 2
#define PIN_LIGHTLEVEL A0
#define PIN_DS18 7
#define PIN_LEDBLUE 3 //PWM
#define PIN_LEDGREEN 5 //PWM
#define PIN_LEDRED 6 // PWM
#define PIN_VELUX 8


//instance
Bounce debounceVelux = Bounce();
OneWire oneWire(PIN_DS18);
DallasTemperature sensors(&oneWire);
IRrecv irrecv(PIN_IRREC);
decode_results results;

//Msg
MyMessage msgVelux(CHILD_ID_VELUX,V_TRIPPED);
MyMessage msgLightLevel(CHILD_ID_LIGHTLEVEL,V_LIGHT_LEVEL);
MyMessage msgIrText(CHILD_ID_IRTEXT,V_TEXT);
MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP);

//Variables
#define SENDFREQUENCY 300000
#define REMOTETIME 60000
bool lastVelux=false;
unsigned long lastTime=millis();
bool firstTime=true;
int lastLum=0;
int lastTemp=-1;
String msgSend="";
struct CodeIR {  long codeL;  char codeMsg; };
#define NB_CODEIR 17
CodeIR codeIR[NB_CODEIR]={
  {0xFF629D,'+'},
  {0xFF02FD,'o'},
  {0xFFA857,'-'},
  {0xFFC23D,'>'},
  {0xFF22DD,'<'},
  {0xFF6897,'1'},
  {0xFF9867,'2'},
  {0xFFB04F,'3'},
  {0xFF30CF,'4'},
  {0xFF18E7,'5'},
  {0xFF7A85,'6'},
  {0xFF10EF,'7'},
  {0xFF38C7,'8'},
  {0xFF5AA5,'9'},
  {0xFF4AB5,'0'},
  {0xFF42BD,'*'},
  {0xFF52AD,'#'}};

void presentation() {
  sensors.begin();
  sensors.setCheckForConversion(false);
  sendSketchInfo("Multicapteur Bureau 1","1.0");
  present(CHILD_ID_VELUX,S_DOOR);
  present(CHILD_ID_LIGHTLEVEL,S_LIGHT_LEVEL);
  present(CHILD_ID_IRTEXT,S_INFO,"INFO TELEC",true);
  present(CHILD_ID_TEMP,S_TEMP);
}

void controlLED(int cRed,int cGreen,int cBlue) {
  analogWrite(PIN_LEDRED, cRed);
  analogWrite(PIN_LEDGREEN,cGreen);
  analogWrite(PIN_LEDBLUE,cBlue);
}

 String decodeIR(long IRvalue) {
  String resultat="";
  for(unsigned int i=0;i<NB_CODEIR;i++) {
      //Serial.print("codeL=");Serial.println(codeIR[i].codeL,HEX);
      if(IRvalue==codeIR[i].codeL) {
        //Serial.println("------------------trouver");
        resultat=codeIR[i].codeMsg;
        break;
      }
    }
  return resultat;
  }

String decodeMultipleIR(void) {
  //l'appel de * commence et fin pour #
  unsigned long lastTimeRemote=millis();
  bool goBack=false;
  controlLED(255,255,0);
  String msgResult="";

  while(true) {
    unsigned long now=millis();
    goBack=now-lastTimeRemote>REMOTETIME;
    if(goBack) {
      msgResult="";
      break;
    }
    bool irState=irrecv.decode(&results);
    if(irState) {
      long valeurIR=results.value;
      String msgIR=decodeIR(valeurIR);
      if(msgIR=="o"){
          controlLED(255,0,0);
          delay(500);
          controlLED(0,0,0);
          Serial.print("msg par IR=");Serial.println(msgResult);
          break;
        }
      if(msgIR=="#") { //cancel
        controlLED(255,100,0);
        delay(1000);
        controlLED(0,0,0);
        msgResult="";
        break;
      }
      if(!(msgIR==""||msgIR=="*"||msgIR=="o"||msgIR=="#")) {
        controlLED(0,0,0);
        delay(100);
        controlLED(25,50,100);
        msgResult+=msgIR;
        if(msgResult.length()>49) {break;}
      }
      irrecv.resume();
      delay(100);
    }
  }
  controlLED(55,0,100);
  delay(200);
  controlLED(0,0,0);
  //Serial.print("Je suis sortie ");Serial.println(msgResult);
  return msgResult;
}

void setup() {
    //pinMode(PIN_VELUX, INPUT);
    pinMode(PIN_IRREC, INPUT);
    pinMode(PIN_VELUX, INPUT_PULLUP);
    debounceVelux.attach(PIN_VELUX);
    debounceVelux.interval(2000);
    irrecv.enableIRIn();
    pinMode(PIN_LEDBLUE,OUTPUT);
    pinMode(PIN_LEDGREEN,OUTPUT);
    pinMode(PIN_LEDRED,OUTPUT);
}

void loop() {
    debounceVelux.update();
    bool velux=debounceVelux.read();
    if (velux^lastVelux) {
      Serial.println("Velux.....");
      send(msgVelux.set(velux==HIGH?1:0));
      lastVelux=velux;
    }

    unsigned long now=millis();
    bool sendTime=now-lastTime>SENDFREQUENCY;
    if(sendTime||firstTime) {
      firstTime=false;
      lastTime=now;
      int lum = map( analogRead(PIN_LIGHTLEVEL),0,1023,0,100);
      if(lum!=lastLum) {
        lastLum=lum;
          send(msgLightLevel.set(lum));
      }

      sensors.requestTemperatures();
      float temperature=sensors.getTempCByIndex(0);
      Serial.print("Temp=");Serial.println(temperature);
      if(temperature!=lastTemp && temperature != -127.00) {
        lastTemp=temperature;
        send(msgTemp.set(temperature,1));
      }
    }
    bool irState=irrecv.decode(&results);
    if(irState) {
      long valeurIR=results.value;
      String msgIR=decodeIR(valeurIR);
      if(msgIR=="*"){
          msgSend=decodeMultipleIR();
          if(msgSend!="") {
            char msgSendChar[50];
            msgSend.toCharArray(msgSendChar, msgSend.length()+1);
            Serial.print("---------Envoi de :");Serial.println(msgSendChar);
            send(msgIrText.set(msgSendChar));
          }
        }
        irrecv.resume();
        delay(100);
    }
  } 
4) Utilisation
On appui sur ‘*’ , la led s’allume
On tape son code, la led change de couleur
On appuie sur ‘Ok’ pour valider ou ‘#’ pour annuler.
Le nœud émet après validation le code tapé, DZ le reçoit comme un Text device.
Sans validation ou cancel, après 1min le programme revient dans le loop, la led s’éteint et rien n’est envoyé.

5) Exemple script lua d’utilisation
Type : device

Code : Tout sélectionner

if(devicechanged['Bureau1_Telecommande'] then
    local codeIR=otherdevices_svalues['Bureau1_Telecommande']
    print('Code IR='..codeIR)
    if(codeIR=='00') then fait ceci end
    if (codeIR=='01') then fait cela end
    if (codeIR=='10') then fait ça end
end 
6) Avantages / inconvénients
Con :
• C’est un peu moins pratique qu’une télécommande qui envoi on/off ou une seule pression suffit.
Pro :
• 1 seule télécommande (pas cher) permet d’envoyer une grande quantité de codes.
• 1 seul text device dans dans DZ.

7) Photos
p1.jpg
p1.jpg (129.44 Kio) Consulté 4620 fois
p2.jpg
p2.jpg (115.42 Kio) Consulté 4620 fois
Opi
RFXCOM
RFLINK 433 & 315
Mysensors
Wifi & Mqtt
EspEasy - Tasmota
Zigate+
hbachetti

Re: Utiliser une télécommande IR avec un noeud MyS.

Message par hbachetti »

Salut.
Réalisation sympa.
J'utilise en ce moment quelques touches inutiles de la télécommande de mon ampli audio pour transmettre des ordres à DOMOTICZ.
Un ARDUINO NANO équipé d'un tsop4838 reçoit les codes et les envoie par la ligne série à un petit script python tournant sur la RASPBERRY.
Ce script envoie ensuite les ordres à DOMOTICZ en JSON.
Ce qui me paraît bizarre, c'est que les codes de la télécommande changent, une touche à la fois, assez régulièrement. Quelques fois par an, je suis donc obligé de modifier mon code. Je trouve ça plutôt étrange.

J'ai en projet une télécommande à base d'ARDUINO PRO MINI alimentée par batterie. Cette fois-ci il s'agit d'un vrai nœud MYSENSORS, avec 8 boutons poussoirs.
Une télécommande en 2.4 GHz en somme. Mode veille pour l'ARDUINO et le NRF24L01, réveil par interruption.
Je compte utiliser un expander MCP23008 pour gérer les touches et réveiller l'ARDUINO.

La principale difficulté a été de trouver des boutons poussoirs à grosses touches pour pouvoir y coller des étiquettes imprimées sur film transparent ...

@+ pour de nouveaux partages
Fredok
Messages : 90
Inscription : 12 août 2016, 15:04

Re: Utiliser une télécommande IR avec un noeud MyS.

Message par Fredok »

Bonjour, j'avais aussi penser inclure un key pad 4x4 a un nœud MYS pour faire un boitier de commandes mais cela faisait 8 pins à utiliser et sur le nœud il n'y avait pas le compte alors j'ai choisit l'IR.
J'aimerais bien voir ton projet finalisé
Opi
RFXCOM
RFLINK 433 & 315
Mysensors
Wifi & Mqtt
EspEasy - Tasmota
Zigate+
hbachetti

Re: Utiliser une télécommande IR avec un noeud MyS.

Message par hbachetti »

J'ai fait mes premiers essais ce weekend.
La librairie MCP23008 AdaFruit a une grosse lacune. Elle ne permet pas de configurer les interruptions de l'expander.
Je vais être obligé de la ré-écrire.

A part çà la fonction Sleep() MYSENSORS ne sort pas lorsqu'une interruption arrive.
J'ai utilisé à la place smartSleep(), qui fonctionne, mais est assez pauvrement documentée. Je ne sais pas quel niveau d'endormissement elle est supposée provoquer.
Une mesure de consommation me le dira.

@+ pour la suite ...
Répondre