J’avais essayé il y a déjà longtemps les émetteurs et le récepteurs RF433 des sites chinois avec l’Arduino , et j’avais été enthousiasmé par la facilité de cloner les télécommandes bon marché eu utilisant la libraire RC-Switch…
par exemple :
http://anothermaker.xyz/iot/domotique-arduino-nano-raspberry-pi-partie1-rf433mhz-4995
Mais j’ai été très vite déçu, en effet de nombreuses télécommandes n’étaient pas identifiées pas ce moyen…( j’apprends ce jour que cette bibliothèque à évolué avec 29 protocoles supplémentaires…., dont les DiO…, super…on continue quand même)
J’ai donc entrepris de me passer de cette Library pourtant excellente…
Pour cela j’ai revu le sniffer433 en utilisant la numérisation rapide….
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
#define DATA A0 #define NbEchantillons 1250 // Defines for setting A2D register bits #define a2dBitClr(bit) (_SFR_BYTE(ADCSRA) &= ~_BV(bit)) #define a2dBitSet(bit) (_SFR_BYTE(ADCSRA) |= _BV(bit)) const int maxCompteur = NbEchantillons; //500 pour le grapheur.... byte code[NbEchantillons]; volatile int compteur = 0; const byte ledPin = 13; byte action = 1, nbemission = 0; unsigned long debut = 0, fin = 0; // Set A2D register clock division factor, enabling faster sampling void a2dSetup(int factor){ //de 2 à 7....4 environ 16µs, 5 environ 30µs, 6 environ 60 µs, 7-->110µs (par mesure....){ if (factor & 1) a2dBitSet(ADPS0); else a2dBitClr(ADPS0); if (factor & 2) a2dBitSet(ADPS1); else a2dBitClr(ADPS1); if (factor & 4) a2dBitSet(ADPS2); else a2dBitClr(ADPS2); } void setup() { Serial.begin(256000); pinMode(DATA, INPUT); digitalWrite(ledPin, LOW); a2dSetup(4); //de 2 à 7....4 environ 16µs, 5 environ 30µs, 6 environ 57 µs, 7-->110µs (par mesure....) } void loop() { compteur = 0; debut = micros(); while (compteur < maxCompteur) code[compteur++] = analogRead(DATA); fin = micros(); digitalWrite(ledPin, HIGH); for (int i = 0; i < maxCompteur; i++) { Serial.print(code[i]); Serial.print(","); } Serial.print("Fin-duree:" + String(fin - debut) + ","); digitalWrite(ledPin, LOW); while ((!digitalRead(6)) and (!digitalRead(8))); delay(20); } |
il envoie les données capturées à un moniteur graphique écrit avec Delphi, celui de l’arduino étant limité à 500 données…
Pour le bouton on d’une télécommande, le signal est le suivant:
On y voit des barres fines et des barres plus épaisses séparées par des blancs, on suggère rapidement des 0 et des 1, soit « 0001010100010101010101110 »
En fait la dernière barre fine est le début du signal….suivi d’un grand blanc ce qui constitue l’entête de synchronisation
On peut obtenir davantage de détails en jouant sue le paramètre ‘factor’ de la procédure a2dSetup (configuration du convertisseur analogique numérique) avec un paramètre à 4 on obtient une donnée toutes les 16 µs…(environ…)
Le moniteur graphique permet de mesurer les périodes…
Ici en moyenne une mesure toutes les 9,54µs (factor mis à 3), 8 périodes (bits) 1086 mesures soit un bit 9,54*1086/8=1295 µs et donc un pulse (état H ou b) à 323,75 µs
L’analyse complète donne:
1-Entete de 32 ‘pulses’: Hbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
2-Bit 0: 4 pulses Hbbb
3-Bit 1: 4 pulses HHHb
4-durée d’un état (pulse): 323 µs
On peut ainsi simuler la télécommande physique par un programme:
Telecommande On/Off
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
///Telecommande bureau. const byte ledPin = 13; const String btnMarche = "000101010001010101010111"; const String btnArret = "000101010001010101010100"; #define dureePulse 350 //325 marche aussi.... unsigned long debut; void EnvoyerBit(int H, int L) {//entete:1-31, 0:1-3, 1:3-1 debut = micros(); digitalWrite (10, HIGH); while ((micros() - debut) < (dureePulse * H)); digitalWrite(10, LOW); while ((micros() - debut) < ( dureePulse * (L + H))); } void EnvoyerCode(String btn) { for (int j = 1; j < 10; j++) { EnvoyerBit(1, 31);// Synchro 1-31: 1 pulse H, 31 pulse L for (int i = 0; i < btn.length(); i++) { if (btn[i] == '1') EnvoyerBit(3, 1);//Envoyer 1: 3 pulse H, 1 pulse L else EnvoyerBit( 1, 3); //Envoyer 0: 1 pulse H, 3 pulse L } } } void setup() { pinMode (10, OUTPUT); pinMode(ledPin, OUTPUT); delay(500); } void loop() { digitalWrite(ledPin, HIGH); EnvoyerCode(btnMarche); delay(5000); digitalWrite(ledPin, LOW); EnvoyerCode(btnArret); delay(5000); } |
PS: pour les télécommande DiO, une solution est ici:
http://charleslabs.fr/fr/project-Contrôle+de+prises+DiO+avec+Arduino
marche très bien
Finalement j’utilise RC-Switch avec tous ses protocoles….
Version Simplifiée avec esp32
les timers de l’esp32 permettent une version plus claire
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
//**************** sniffer avec timers esp32 ********************* hw_timer_t * timerMesures = NULL; hw_timer_t * timerLed = NULL; int led = 2; int touche = 17; int RX433 = 33; volatile byte state = LOW; #define nbmesures 4000 volatile int mesures[nbmesures]; volatile int i = 0; boolean debug = true; portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; long debut; int interMesures = 52; void IRAM_ATTR onTimerMesures() { portENTER_CRITICAL_ISR(&timerMux); mesures[i] = digitalRead(RX433); i++; if (i > nbmesures) { i = 0; timerAlarmDisable(timerMesures); } portEXIT_CRITICAL_ISR(&timerMux); } void IRAM_ATTR onTimerLed() { state = !state; digitalWrite(led, state); } void setup() { Serial.begin(115200); pinMode(led, OUTPUT); pinMode(touche, INPUT); pinMode(RX433, INPUT); /* Use 1 & 2 timers of 4 */ /* 1 tick take 1/(80MHZ/80) = 1us so we set divider 80 and count up */ timerMesures = timerBegin(0, 80, true); timerLed = timerBegin(1, 80, true); /* Attach onTimer function to our timer */ timerAttachInterrupt(timerMesures, &onTimerMesures, true); timerAttachInterrupt(timerLed, &onTimerLed, true); /* Set alarm to call onTimer function every second 1 tick is 1us => 1 second is 1000000us */ /* Repeat the alarm (third parameter) */ timerAlarmWrite(timerMesures, interMesures, true);//une mesure toutes les interMesure µs timerAlarmWrite(timerLed, 1000000, true); /* Start an alarm */ timerAlarmEnable(timerMesures); timerAlarmEnable(timerLed); if (debug) Serial.println("start timer"); } void loop() { if (i >= nbmesures) { Serial.print("Durée des mesures: " + String(millis() - debut)); Serial.println(" attendu :" + String(nbmesures * interMesures / 1000)); if (debug) Serial.println(); int cas = 2; int nbcas = 1; cas = mesures[0]; if (debug) Serial.println("**************** les mesures avec comptage ***********************************"); for (int j = 1; j < nbmesures; j++) { if (mesures[j] == cas) { nbcas++; } else { if (debug) Serial.println(" (" + String(cas) + ":" + String(nbcas) + ") "); cas = mesures[j]; nbcas = 1; } Serial.print(mesures[j]); if ((nbcas % 100) == 0) Serial.println(); } if (debug) Serial.println(" (" + String(cas) + ":" + String(nbcas) + ") "); // fin des mesures ******************************************** // for (int u = 0; u < nbmesures; u++) mesures[u] = 0; if (debug) Serial.println("Touche en attente... ");//pour lancer une nouvelle série de mesures while (digitalRead(touche) == HIGH) { delay(100); } if (debug) Serial.println(); i = 0; debut = millis(); timerAlarmEnable(timerMesures); } } |
resultat sans signal
Durée des mesures: 208 attendu :208
**************** les mesures avec comptage ***********************************
(0:1)
11 (1:2)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:3997)
Touche en attente…
résultats avec signal (après élimination des données superflues ou redontantes…)
Durée des mesures: 208 attendu :208
**************** les mesures avec comptage ***********************************
111 (1:3)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:197)
111111 (1:6)
00000000000000000000 (0:20)
111111 (1:6)
0000000000000000000 (0:19)
111111 (1:6)
00000000000000000000 (0:20)
111111111111111111 (1:18)
00000000 (0:8)
11111 (1:5)
00000000000000000000 (0:20)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
000000000000000000000 (0:21)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
00000000000000000000 (0:20)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
000000000000000000000 (0:21)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
00000000000000000000 (0:20)
11111 (1:5)
000000000000000000000 (0:21)
11111 (1:5)
00000000000000000000 (0:20)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
000000000000000000000 (0:21)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
00000000000000000000 (0:20)
111111111111111111 (1:18)
000000000 (0:9)
1111 (1:4)
000000000000000000000 (0:21)
111111111111111111 (1:18)
000000000 (0:9)
11111111111111111 (1:17)
000000000 (0:9)
11111111111111111 (1:17)
000000000 (0:9)
1111 (1:4)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:197)
entre deux blocs de 197 O, on voit apparaitre une alternance de 0 et 1:
-un 1 :
111111111111111111 (1:18)
00000000 (0:8)
-un 0:
11111 (1:5)
00000000000000000000 (0:20)
On retrouve le codage sur 4 états HHHb pour un 1 et Hbbb pour un 0, la durée de chaque état étant de 5 à 8 intervalles de mesures de 52 µs soit 260-416 µs soit en moyenne 338 µs ( entre 25*52/4 et 27*52/4)
En comptant les nombres d’échantillons de chaque état, on on obtient la signature du signal, par exemple:
11111111111111111111111111 (1:26)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:1019)
111111111111111111111111111111111 (1:33)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:99)
11111111111111111111111111111111 (1:32)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:99)
11111111111111111111111111111111 (1:32)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:100)
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:98)
0000000000000000000000000000000000000 (0:37)
111111111111111111111111111111 (1:30)
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:102)
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:98)
0000000000000000000000000000000000000 (0:37)
111111111111111111111111111111 (1:30)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:97)
00000000000000000000000000000000000000 (0:38)
11111111111111111111111111111 (1:29)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:97)
000000000000000000000000000000000000000 (0:39)
11111111111111111111111111111 (1:29)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:98)
000000000000000000000000000000000000000 (0:39)
1111111111111111111111111111 (1:28)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:104)
111111111111111111111111111111 (1:30)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
11111111111111111111111111111 (1:29)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:97)
000000000000000000000000000000000000000 (0:39)
11111111111111111111111111111 (1:29)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:97)
0000000000000000000000000000000000000000 (0:40)
1111111111111111111111111111 (1:28)
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:103)
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:98)
000000000000000000000000000000000000000 (0:39)
1111111111111111111111111111 (1:28)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:104)
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:97)
000000000000000000000000000000000000000 (0:39)
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:96)
0000000000000000000000000000000000000000 (0:40)
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 (1:96)
000000000000000000000000000000000000000 (0:39)
1111111111111111111111111111 (1:28)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 (0:1019)
26,1019,33,99,32,99,32,100,98,37,30,102,98,37,30,103,97,38,29,103,97,39,29,103,98,39,28,104,30,103,29,103,97,39,29,103,97,40,28,103,98,39,28,104,97,39,96,40,96,39,28,1019,
Cette dernière ligne sera donnée au player avec la durée entre deux échantillons, par exemple
1 |
int veilleuseOff[] = {236, 28, 124, 28, 124, 104, 48, 28, 124, 104, 48, 28,<br />124, 104, 48, 28, 124, 28, 124, 28,124, 104, 47, 29, 123, 105, 46, 30, 122,<br />107, 45, 31, 121, 30, 121, 107, 46, 106, 46,106, 46, 106, 46, 106, 47, 29,<br />122, 30, 123, 30};<br /><br />void player() {<br />int imax = 50;//nombre de données<br />for (int v = 0; v < 5; v++) {<br /> boolean niveau = LOW;<br /> for (int i = 0; i < imax; i++) {<br /> digitalWrite(rfTransmitPin, niveau);<br /> delayMicroseconds(veilleuseOff[i] * 10);//10 durée entre 2 échantillons<br /> niveau = !niveau;<br /> }<br /> }<br /> }<br /><br />. |