La reconnaissance vocale n'étant pas fiable, j'ai cherché un autre moyen de piloter mon module.
Je me suis tourné vers un encodeur/switch.
Ma commande aliexpress
Je vous invite à regarder une page google pour en savoir plus sur les encodeurs.
Recherche google
En gros on récupère un signal de cette forme aux bornes de codeur.
Suivant le décalage De A ou B on connais le sens et la vitesse.
Afin de voir dans un menu le résultat de la rotation du codeur, j'ai ajouter un écran LCD 2×16 en I2C.
Et pour le fun, une led RGB !
Je me suis créer une petit maquette avec le fruit de mes réflexions sur l'émission IR et le capteur de lumière.
Tout n'est pas de moi !
J'ai pris des exemples à droite et gauche puis assemblé le tout.
Les sources sont cités au début.
Le menu n'a que 5 choix, mais on peu en ajouter plus et même créer des sous menus.
Il n'y a pas la gestion RF et récepteur IF comprise. Pour l'instant je suis sur une maquette.
/* Logiciel des fonctions de la platine
* exemple lcd de la lib liquidcrystal_i2c
* encodeur sur http://bildr.org/2012/08/rotary-encoder-arduino/
* Encodeur utilise EnableInterrupt
* DHT11 http://total-informatique.com/utiliser-le-dht11-avec-un-ecran-lcd/
* RGB http://www.mbeckler.org/microcontrollers/rgb_led/
* Menu https://skyduino.wordpress.com/2014/07/06/arduino-lcd-faire-un-menu-sous-forme-de-liste/
*
* Synoptique :
* On affiche un message de bienvenue
* Affiche température et humidité
* Si bouton tourne ou push
* Affiche menu
* Gestion menu
*/
#include <avr/pgmspace.h> // library for keeping variables in Flash RAM
#include "Wire.h"
#include "LiquidCrystal_I2C.h"
#include "DHT.h" // Librairie pour le capteur DHT
#include <IRremote.h>
#include <EnableInterrupt.h>
// ### Menu ###
prog_char const mainMenu1[] PROGMEM = "1.Television ";
prog_char const mainMenu2[] PROGMEM = "2.XBMC ";
prog_char const mainMenu3[] PROGMEM = "3.Lum centre ";
prog_char const mainMenu4[] PROGMEM = "4.Lum bandeau";
prog_char const mainMenu5[] PROGMEM = "5.Luminosite";
const char* const mainMenu[] PROGMEM = {
mainMenu1, mainMenu2, mainMenu3, mainMenu4, mainMenu5};
// Data télécommande
#define cmd_code 0xffffffff // remote code pour transmettre.
#define Tv_onoff 0x20df10ef // Codes des télécommandes
#define Tv_volP 0x20df40bf
#define Tv_volM 0x20dfc03f
#define Ampli_on 0x7e817e81
#define Ampli_off 0x7e81fe01
#define Ampli3 0x5eA1609e
#define Ampli2 0x5eA1c03e
#define Ampli_volP 0x5eA158a7
#define Ampli_volM 0x5eA1d827 // Codes des télécommandes
// ### Definition DHT ###
#define DHTPIN 6 //Pin auquel est connecté le capteur DHT
#define DHTTYPE DHT11 //Si vous utiliser le DHT 11
//#define DHTTYPE DHT22 //Si vous utiliser le DHT 22 (AM2302)
//#define DHTTYPE DHT21 //Si vous utiliser le DHT 21 (AM2301)
// ### Definition RGB ###
#define slen 7 // 7 characters, e.g. '#ff6666'
/* Définition IR */
#define REMOTE_BIT 3532
#define tempsIR 100 // Temps entre 2 commandes IR
// ### Definition senseur lumière ###
#define LUM_SENSOR_PIN A0 // lumière sensor connected to this analog pin
// Var pour DHT
float fltHumidity; //Pourcentage d'humidité mesuré
float fltTemperature; //Température mesurée en Celsius
float hum; // ancienne val humidité
float temp; // ancienne val température
// Var pour RGB
int redPin = 10; // Red LED, connected to digital pin 9
int greenPin = 9; // Green LED, connected to digital pin 10
int bluePin = 12; // Blue LED, connected to digital pin 11
// ### Definition Encoder ###
//these pins can not be changed 2/3 are special pins
#define encoderPin1 7
#define encoderPin2 8
#define encoderSwitchPin 4 //push button switch
volatile int lastEncoded = 0;
volatile long encoderValue = 0;
//long lastencoderValue = 0;
long ancienencoderValue = 0;
// ==== Variables Générales ====
const int intTimePause = 5000; //Par défaut on actualise les valeures toutes les 5 secondes
long position = -999;
char serInStr[slen]; // array to hold the incoming serial string bytes
boolean TV = false;
boolean sortm = false;
unsigned long TimeOut;
char buffer[16]; // make sure this is large enough for the largest string it must hold
//char prompt = "Choisissez !";
//IR LED must be connected to Arduino PWM pin 3.
IRsend irsend; // innitialise l' IR object
LiquidCrystal_I2C lcd(0x27,16,2); // set the LCD address to 0x27 for a 16 chars and 2 line display
DHT dht(DHTPIN, DHTTYPE); //On initialise le capteur DHT
boolean bp=false;
int r, v, b;
void BPtest() {
bp=true; // Renvoie bp vrai si bouton pressé
}
void updateEncoder() {
int MSB = digitalRead(encoderPin1); //MSB = most significant bit
int LSB = digitalRead(encoderPin2); //LSB = least significant bit
int encoded = (MSB << 1) |LSB; //converting the 2 pin value to single number
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderValue ++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderValue --;
lastEncoded = encoded; //store this value for next time
// Renvoie la valeur encoderValue contenant la position.
}
// Attach the interrupt in setup()
void setup() {
Serial.begin(115200);
lcd.init(); // initialize the lcd
pinMode(encoderPin1, INPUT_PULLUP); // Défini les pattes de l'encodeur
pinMode(encoderPin2, INPUT_PULLUP);
pinMode(encoderSwitchPin, INPUT_PULLUP);
enableInterrupt(encoderPin1, updateEncoder, CHANGE);
enableInterrupt(encoderPin2, updateEncoder, CHANGE);
enableInterrupt(encoderSwitchPin, BPtest, CHANGE);
pinMode(redPin, OUTPUT); // sets the pins LED RGB as output
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
ancienencoderValue=encoderValue=0;
bp=false;
// Message de bienvenue sur le LCD.
lcd.backlight();
lcd.print("Salut le monde!");
lcd.setCursor(0, 1);
lcd.print("Tourne le bouton");
delay(1500);
lcd.clear();
}
// Affiche une couleur de led
void led_rgb(int teinte) {
HSVtoRGB(&r, &v, &b, teinte, 255, 255);
analogWrite(redPin, r );
analogWrite(greenPin, v );
analogWrite(bluePin, b );
} //Fin du void
void loop() {
//Affiche la temp/humidité si pas menu
tmphum(); // Affiche temp et humidité
//Test, gestion menu
if (ancienencoderValue != encoderValue) { // Si le bouton tourne
Serial.println("tourne");
affmenu3();
}
// Affiche une led rouge prete
led_rgb(0);
} //FIN DE LOOP
// *** Affiche le choix du menu suivant la position de l'encoder
// Change aussi la couleur de la led ***
void affmenu3() {
Serial.print("Entree dans le choix"); //Serial.println(bp);
/* Variable pour le menu */
int nbItems = 5; // Défini le nb d'irem dans le menu
byte selectedMenuItem = 1; // Choix sélectionné
byte shouldExitMenu = false; // Devient true quand l'utilisateur veut quitter le menu
unsigned long TempMax;
boolean boucle = false; // Test de boucle pour aff
long color; // Stock la couleur
int ValC[ ]= {40, 80, 120, 160, 200};
// Affiche une premiere valeur
lcd.clear();
lcd.print("Choisissez !");
strcpy_P(buffer, (char*)pgm_read_word(&(mainMenu[selectedMenuItem-1])));
lcd.setCursor(0, 1);
lcd.print(buffer);
TempMax=millis();
while ((!bp) && (millis() < TempMax+20000)) { // tant que bp off et tempsMAx <
/* change la led rgd */
led_rgb(ValC[selectedMenuItem+1]);
/* Gére le sens du codeur */
long encoder = encoderValue - ancienencoderValue;
Serial.println(selectedMenuItem);
//Serial.print("Encoder :"); Serial.println(encoder);
if (encoder != 0) {
if (encoder > 0) { // on inc
/* S'il existe un choix précédent */
if(selectedMenuItem > 1) {
selectedMenuItem--;
}
} else { // on dec
/* S'il existe un choix suivant */
if(selectedMenuItem < nbItems) {
/* Passe au choix suivant */
selectedMenuItem++;
} else {
selectedMenuItem=nbItems;
}
}
// Affiche le nouveau menu
lcd.setCursor(0, 1);
lcd.print(" "); // Aff ligne vide
strcpy_P(buffer, (char*)pgm_read_word(&(mainMenu[selectedMenuItem-1])));
lcd.setCursor(0, 1);
lcd.print(buffer);
Serial.print("Menu :");Serial.println(selectedMenuItem);
}
ancienencoderValue=encoderValue;
}
/* Bouton appuyé */
//Serial.print("bp appuyé :"); Serial.println(bp);
if(bp) {
displayChoice(selectedMenuItem);
}
bp=false;
led_rgb(0);
} // Fin du void
void tmphum() { // Lit le capteur et affiche les résultats.
fltHumidity = dht.readHumidity(); //On lit le pourcentage d'humidité
fltTemperature = dht.readTemperature(); //On lit la température en degrés Celsuis
if (isnan(fltTemperature) || isnan(fltHumidity)) //Si les valeures retournées ne sont pas des nombres :
{
lcd.setCursor(0, 1); //Positionnement du curseur
lcd.print(DHTTYPE); //On affiche le type de capteur
lcd.setCursor(5, 1);
lcd.print(" illisible"); //On affiche l'erreur
}
else
{
if ((hum != fltHumidity) || (temp != fltTemperature)) lcd.clear();
//Serial.print("Lecture temp/hum"); Serial.println(fltTemperature);
//mise en forme et affichage des informations sur l'écran LCD
//lcd.setdelay(intTimePause); //On actualise les informations toutes les x millisecondes.Cursor(0, 0); //Positionnement du curseur
if (hum != fltHumidity) {
lcd.setCursor(0, 0);
lcd.print(" "); // Aff ligne videlcd.print(
}
lcd.setCursor(0, 0);
lcd.print("Degres : ");
lcd.setCursor(9, 0);
lcd.print(fltTemperature); //Affichage de la température
lcd.setCursor(13, 0);
lcd.print((char)223); //Affiche le caractère ° (degrés)
lcd.setCursor(14, 0);
lcd.print("C"); //En degrés Celsuis
if (temp != fltTemperature) {
lcd.setCursor(0, 1);
lcd.print(" "); // Aff ligne videlcd.print(
}
lcd.setCursor(0, 1);
lcd.print("Humidite : ");
lcd.setCursor(11, 1);
lcd.print(fltHumidity); //Affichage de l'humidité
lcd.setCursor(15, 1);
lcd.print("%");
}
//delay(intTimePause); //On actualise les informations toutes les x millisecondes.
temp = fltTemperature;
hum = fltHumidity;
}
/** Affiche le choix de l'utilisateur */
void displayChoice(byte selectedMenuItem) {
bp=false;
/* Affiche le choix de l'utilisateur */
lcd.clear();
lcd.print(F("Z'avez choisi :"));
lcd.setCursor(0, 1);
strcpy_P(buffer, (char*)pgm_read_word(&(mainMenu[selectedMenuItem])));
lcd.print(buffer);
delay(500);
/* Selection de l'ordre */
switch(selectedMenuItem) {
case 0 : //television
lcd.clear();
lcd.print(F("Television"));
if (!TV) { // Tv pas allumé
Serial.write("ordre tv on");Serial.println(selectedMenuItem);
irsend.sendNEC(Ampli3, REMOTE_BIT);
// irsend.sendNEC(cmd_code, REMOTE_BIT);
// delay(tempsIR);
irsend.sendNEC(0x20df10ef, 3532);
// irsend.sendNEC(cmd_code, REMOTE_BIT);
// delay(tempsIR);
TV=true;
}
else {
Serial.write("ordre tv off");
irsend.sendNEC(Ampli_off, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
irsend.sendNEC(Tv_onoff, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
TV=false;
}
break;
case 1 : //XBMC
lcd.clear();
lcd.print(F("XBMC"));
if (!TV) { // xbmc pas allumé
Serial.write("ordre xbmc on");
irsend.sendNEC(Ampli2, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
irsend.sendNEC(Tv_onoff, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
TV=true;
}
else {
Serial.write("ordre xbmc off");
irsend.sendNEC(Ampli_off, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
irsend.sendNEC(Tv_onoff, REMOTE_BIT);
irsend.sendNEC(cmd_code, REMOTE_BIT);
delay(tempsIR);
TV=false;
}
break;
case 2 : //Lumière table
lcd.clear();
lcd.print(F("Lum Table"));
break;
case 3 : //Lumière bandeau
lcd.clear();
lcd.print(F("Lum bandeau"));
break;
case 4 : //Luminosité
lumin();
break;
delay(2000);
}
bp=false;
Serial.println("Fin d'ordre");
} //Fin displayChoice
void lumin() { //Affiche la luminosité meusurée
long tempsMax;
lcd.clear();
lcd.print(F("Luminosite"));
//Serial.print("bp > :"); Serial.println(bp);
//delay(50);
while (!bp) {
tempsMax = millis();
//Serial.print(digitalRead(encoderSwitchPin)); Serial.print(encoderValue); Serial.println(ancienencoderValue);
lcd.setCursor(0, 1);
lcd.print(" "); // Aff ligne videlcd.print(
lcd.setCursor(0, 1); //Positionnement du curseur
lcd.print(analogRead(LUM_SENSOR_PIN));
//delay(200);
while (millis() < tempsMax+500) {
}
}
bp=false;
} //Fin lumin
// *** Convertie une lumiére TSV (teinte, saturation, valeur) [HSVen anglais] en RGB (hackable N°6)
void HSVtoRGB(int *r, int *g, int *b, int h, int s, int v) {
int c;
long l, m, n;
// saturation zéro, pas de couleur
if (s == 0) {
*r = *g = *b = v;
return;
}
// chroma
c = ((h % 60) * 255) / 60;
h /= 60;
// intermédiaire
l = (v * (256 - s)) / 256;
m = (v * (256 - (s * c) / 256)) / 256;
n = (v * (256 - (s * (256 - c)) / 256)) / 256;
// choix dominante
switch (h) {
case 0:
*r = v; *g = n; *b = l;
break;
case 1:
*r = m; *g = v; *b = l;
break;
case 2:
*r = l; *g = v; *b = n;
break;
case 3:
*r = l; *g = m; *b = v;
break;
case 4:
*r = n; *g = l; *b = v;
break;
default:
*r = v; *g = l; *b = m;
break;
}
} // Fin HSVtoRGB