Bonne soir,
Je suis en train de refaire ma télécommande pour porte garage avec IR.
Mon problème est la possibilité de modifier des codes déjà enregistré sur EEPROM.
Je peux ajouter jusqu'à 24*2 codes.
Pour l'instant, si j'arrive à 24 codes et je veux remplacer un code par un autre, la seule chose que je peux faire est de refaire la programmation complète des codes.
Il y à une solution simple (sans faire une usine à gaz) pour résoudre cet inconvénient?
Voici mon code (je ne l'ai pas testé, juste compilé).
/*
TeleIRPortes: Telecommande pour portes automatisé à IR
Savor 2019
*/
#include <IRremote.h>
#include <EEPROM.h>
#include "EEPROMAnything.h"
#define RECV_PIN 11
#define PIN_PORTE_A 2
#define PIN_PORTE_B 3
#define PIN_SET 4
#define PIN_ERASE 5
#define MAX_CODES 24 //pour plus de codes, il faut reorganiser la EEPROM
IRrecv irrecv(RECV_PIN);
decode_results results;
long lCodesPorteA[MAX_CODES];
long lCodesPorteB[MAX_CODES];
byte iNrCodes;
int iDelayAntiClonage = 2000;
void setup()
{
Serial.begin(9600);
Serial.println("TelecIRPortes V 0.0.1 17/12/19"); //Merci al1fch! t'as eu un karma pour ça!
irrecv.enableIRIn(); // Start the receiver
Serial.println("Enabled IRin");
EEPROM_readAnything(200, iNrCodes);
if (iNrCodes < 24)
{
Serial.print("Codes enregistrés: ");
Serial.println(iNrCodes);
} else
Serial.print("Codes enregistrés: 24! Memoire pleine!!!");
for (int a = 0; a < iNrCodes; a++)
{
if (EEPROM.read(a * 4) != 0)
{
EEPROM_readAnything(a * 4, lCodesPorteA[a]);
EEPROM_readAnything(100 + (a * 4), lCodesPorteB[a]);
Serial.print("Code A[");
Serial.print(a);
Serial.print("]: ");
Serial.println(lCodesPorteA[a]);
Serial.print("Code B[");
Serial.print(a);
Serial.print("]: ");
Serial.println(lCodesPorteB[a]);
}
}
pinMode(PIN_PORTE_A, OUTPUT);
pinMode(PIN_PORTE_B, OUTPUT);
pinMode(PIN_SET, INPUT_PULLUP);
pinMode(PIN_ERASE, INPUT_PULLUP);
}
void loop() {
if (digitalRead(PIN_SET) == LOW) Setting();
boolean bCodeReconu = false; //Precaution Anti-Clonage
if (irrecv.decode(&results)) {
for (int a = 0; a < iNrCodes; a++)
{
if (results.value == lCodesPorteA[a])
{
digitalWrite(PIN_PORTE_A, HIGH);
Serial.println("Ouverture/Fermeture Porte A");
delay(300);
digitalWrite(PIN_PORTE_A, LOW);
bCodeReconu = true;
iDelayAntiClonage = 2000;
}
if (results.value == lCodesPorteB[a])
{
digitalWrite(PIN_PORTE_B, HIGH);
Serial.println("Ouverture/Fermeture Porte B");
delay(300);
digitalWrite(PIN_PORTE_B, LOW);
bCodeReconu = true;
iDelayAntiClonage = 2000;
}
}
if (!bCodeReconu) delay(iDelayAntiClonage = + 1000); //Petite precaution!
irrecv.resume(); // Receive the next value
}
//delay(100);
}
void Setting() {
while (digitalRead(PIN_SET) == LOW)
{
if (digitalRead(PIN_ERASE) == LOW)
{
EEPROM.put(200, 0); //Mets à 0 iNrCodes
Serial.println("Memoire EEPROM effacé. Vous pouvez relacher le bouton SET");
iNrCodes = 0;
while (digitalRead(PIN_SET) == LOW);//Attens le relachement du bouton SET
return;
}
if (iNrCodes = 24)
{
Serial.println("Memoire Pleine! Vous pouvez relacher le bouton SET");
while (digitalRead(PIN_SET) == LOW);//Attens le relachement du bouton SET
return;
}
for (int a = iNrCodes; a < 25; a++)
{
while (!irrecv.decode(&results))
{
if (digitalRead(PIN_SET == HIGH)) return;
}
EEPROM_writeAnything(a * 4, lCodesPorteA[a]);
Serial.print("Code Porte A[");
Serial.print(a);
Serial.print("] ");
Serial.print(lCodesPorteA[a]);
Serial.println("enregistré");
while (!irrecv.decode(&results))
{
if (digitalRead(PIN_SET == HIGH)) return;
}
EEPROM_writeAnything(100 + (a * 4), lCodesPorteB[a]);
Serial.print("Code Porte B[");
Serial.print(a);
Serial.print("] ");
Serial.print(lCodesPorteB[a]);
Serial.println("enregistré");
EEPROM_writeAnything(200, ++iNrCodes);
}
}
}
Si je comprends bien, tu as deux portes avec des codes IR différents et une seule télécommande, dans laquelle tu veux stocker deux jeux de 24 codes : correct ? Ton problème est (par exemple) de changer le code numéro 12 de la télécommande numéro 2 sans avoir à recharger le reste des codes : toujours bon ?
Dans ce cas, il te faut un moyen de savoir (dans le programme) de quel numéro de code il s'agit, et ensuite écrire dans l'EEPROM la nouvelle valeur. Ça ne doit pas être sorcier.
Au passage, tu peux certainement mettre un break dans les blocs if (results.value == lCodesPorte*[a]) pour sortir du for lorsqu'un code est reconnu afin d'éviter de comparer aux autres codes en mémoire pour rien.
juste une remarque : dommage d'avoir défini MAX_CODES=24 au début du programme mais de ne pas l'utiliser ensuite, et d'avoir la valeur 24 écrite en dur dans le code
En fait, (en regardant TRES vite fait) j'ai l'impression que tu t'es beaucoup compliqué la vie pour tes enregistrements/relectures
pourquoi balayer tout le tableau avec des boucles for ? Le plus simple est d'utiliser eeprom.put et eeprom.get pour les manips, pas besoin de rajouter une librairie pour ça.
Par exemple quand tu veux lire tes codes dans le setup, tu fais simplement :
Rien ne sert de lire/écrire le tableau uniquement jusqu'au dernier code, c'est bien plus simple de lire/écrire le tableau complet dans tous les cas, de toute manière eeprom.put vérifie avant d'écrire que la valeur est bien différente de manière à ne pas user l'eeprom prématurément.
Maintenant pour ce qui est de remplacer un code précis dans le tableau, soit tu connais ce code et le code à remplacer, dans ce cas il suffit de rechercher dans le tableau, et une fois l'index trouvé, le remplacer puis appeler la fonction de sauvegarde, soit tu ne connais pas le code mais tu connais son index -> encore plus simple pas besoin de chercher, soit tu ne connais ni l'un ni l'autre et là... il n'y a pas de solution
Au passage, tu peux certainement mettre un break dans les blocs if (results.value == lCodesPorte*[a]) pour sortir du for lorsqu'un code est reconnu afin d'éviter de comparer aux autres codes en mémoire pour rien.
C'est vrai!
Dans ce cas, il te faut un moyen de savoir (dans le programme) de quel numéro de code il s'agit, et ensuite écrire dans l'EEPROM la nouvelle valeur. Ça ne doit pas être sorcier.
soit tu ne connais ni l'un ni l'autre et là... il n'y a pas de solution
J’espérais dans une solution miracle!
juste une remarque : dommage d'avoir défini MAX_CODES=24 au début du programme mais de ne pas l'utiliser ensuite, et d'avoir la valeur 24 écrite en dur dans le code
oui avec eeprom.get(adresse, donnée) tu va lire une donnée de la taille correspondant au type de "donnée" à l'adresse demandée.
donc si tu fais :
eeprom.get(0, lCodesPorteA);
tu vas lire depuis l'adresse 0 une quantité de données correspondant à lCodesPorteA qui est un tableau de 24 long
donc tu va lire les 24 elements du tableau d'un coup.
Ensuite avec : eeprom.get(sizeof(lCodesPorteA), lCodesPorteB); tu va faire la même chose mais à partir de l'adresse correspondant à la fin du tableau précédant en mémoire.
J'aurais très bien pu mettre la valeur en dur dans le code (d'ailleurs tu avais mis 100, mais avec 100 tu perds une case, puisque 100 ce serait la taille employée par 25 long(de 4octets), pas 24, il reste donc 4 octets inutilisées en eeprom entre tes deux tableaux, avec ton code actuel) mais l'intéret d'utiliser sizeof() c'est que si tu change d'architecture ça fonctionne à coup sûr, alors que le nombre d'octets pour représenter un long peut varier d'un processeur à un autre.
savoriano:
...
Cette fois, compilé et testé, car dans le code posté dans le dernier post il y avait beaucoup de problèmes.Je voulais avoir la possibilité de mettre 2 récepteurs mais apparemment ce n'est pas possible. Est possible d'en mettre 2 en parallèle?
Bonsoir Savoriano
Tu souhaite faire quoi exactement ?
avoir 2 recepteurs IR connectés sur le meme pin ou avoir 2 recepteurs chacun sur un pin différent ?
je voudrais pouvoir commander mes portes de extérieur mais aussi de l’intérieur, donc avec 2 récepteurs.
J'ai essayé de mettre 2 récepteurs dans 2 pins différents (vous pouvez voir dans le code les lignes mises en commentaire comme j'avais procédé) mais ça ne marchait pas comme je voulais! J'avais l'impression que même si je créai 2 instances pour les 2 récepteurs, les données n’était séparé. J'ai déduit que avec cette librairie pouvait gérer un seul récepteur.
Seulement après avoir tout monté je me suis demandé si n’était pas possible mettre 2 récepteurs dans un seul pin.
savoriano:
je voudrais pouvoir commander mes portes de extérieur mais aussi de l’intérieur, donc avec 2 récepteurs.
J'ai essayé de mettre 2 récepteurs dans 2 pins différents (vous pouvez voir dans le code les lignes mises en commentaire comme j'avais procédé) mais ça ne marchait pas comme je voulais! J'avais l'impression que même si je créai 2 instances pour les 2 récepteurs, les données n’était séparé. J'ai déduit que avec cette librairie pouvait gérer un seul récepteur.
Seulement après avoir tout monté je me suis demandé si n’était pas possible mettre 2 récepteurs dans un seul pin.
OK
C'est quoi comme ref ton/tes recepteurs/démodulateurs IR ?
En général , les recepteurs/démodulateurs IR (genre TSOP) , non sollicités ( = pas en phase de reception de signal IR) delivrent il me semble un niveau haut sur leur pin data , c'est facile à verifier : test du niveau de sortie du recepteur IR au repos.
Sous reserves de verifs plus approfondies , il doit etre possible de facilement en mettre en //
En gardant à l'esprit que si les 2 recepteurs sont sollicités en même temps , le décodage IR sera en echec
En général , les recepteurs/démodulateurs IR (genre TSOP) , non sollicités ( = pas en phase de reception de signal IR) delivrent il me semble un niveau haut sur leur pin data , c'est facile à verifier : test du niveau de sortie du recepteur IR au repos.
Je vais tester ça.
P.S. oui le niveau sur le pin OUT est haut.
Demain je vais essayer de les mettre dans le même pin de l'arduino
En gardant à l'esprit que si les 2 recepteurs sont sollicités en même temps , le décodage IR sera en echec