Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

telecommande:ext1 [2019/08/13 12:16] (Version actuelle)
Ligne 1: Ligne 1:
 +====== Test avec un encoder/​switch ======
  
 +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.
 +
 +[[http://​www.aliexpress.com/​snapshot/​6536924073.html?​orderId=66197489434089|Ma commande aliexpress]]
 +
 +Je vous invite à regarder une page google pour en savoir plus sur les encodeurs.\\
 +[[https://​www.google.fr/​search?​q=arduino+encoder&​biw=1920&​bih=894&​tbm=isch&​tbo=u&​source=univ&​sa=X&​ei=9lx0VcTvHMzsUsjugdgL&​sqi=2&​ved=0CCwQsAQ|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.\\
 +{{wiki:​rotaryencoderwaveform.gif?​300 |}}  \\ 
 +
 +
 +
 +Afin de voir dans un menu le résultat de la rotation du codeur, j'ai ajouter un écran LCD 2x16 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.
 +
 +====== Schémas ======
 +Sous eagle comme d'hab.
 +
 +
 +====== Programmation ======
 +Comme je voulais laisser la place pour un émetteur/​récepteur RF433MHz et un récepteur IF.\\
 +J'ai été obligé de laisser les pattes : 2,3,10 et 11 disponibles.\\
 +J'​avais donc un problème pour le codeur et le switch afin de récupérer une action rapidement.\\
 +J'ai découvert que quasi toutes les pattes de l'​arduino pouvait générer une interruption,​ du coup plus de soucis.\\
 +J'ai commencé avec la librairie attachinterrupt :\\
 +[[http://​www.arduino.cc/​en/​Reference/​AttachInterrupt]] \\
 +Puis utilisé EnableInterrupt qui est plus récent et mis à jour :\\
 +[[https://​github.com/​GreyGnome/​EnableInterrupt]]
 +
 +====== Quelques mots sur le code ======
 +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.
 +
 +<code c++>
 +/* 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
 +
 +
 +</​code>​
 +
 +
 +======= Quelques mots sur la finalisation du projet =======
 +
 +J'ai pensé mettre ce module dans un cylindre avec 1 bague tournante et l'​afficheur en haut derrière un plexi fume.\\
 +Les diodes IF seraient à la base tournées dans tout les sens.\\
 +On peu prévoir un alim par induction sur un socle.\\
 +Le codeur demandera un peu de mécanique pour que la bague l’entraîne mais avec le possibilité d'​appuyer pour déclencher le switch.\\
 +
 +
 +======= BILAN =======
 +Un encodeur c'est pas mal à condition d'​utiliser les interruptions.\\
 +Sinon on loupe des crans, mais malgré les int., on ne peu pas tourner trop vite.\\
 +Sous mon code j'ai des pas de 4 à chaque cran, construction du codeur ? Erreur de prog ?\\
 +Je ne sais pas, mais il faut y penser dans le code.
telecommande/ext1.txt · Dernière modification: 2019/08/13 12:16 (modification externe)
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0