Après qu'Andreas Wolter ait ajouté deux émetteurs-récepteurs nRF24L01 à mon "Santa Detector" afin de recevoir les signaux des capteurs dans une autre pièce, les deux modules étaient sur ma table, prêts pour un nouveau projet. N'avais-je pas envie depuis longtemps de commuter différents circuits d'éclairage sur mon réseau ferroviaire miniature avec des relais? Le microcontrôleur avec le récepteur radio et les relais cachés quelque part sous la plaque, l'émetteur à portée de main à côté des pupitres de commande.
Dans la première option, j'utilise des interrupteurs, dans la deuxième option des boutons ou un pavé tactile capacitif pour activer et désactiver les relais.
Matériel utilisé
Nombre | Matériel |
---|---|
1 | Microcontrôleur avec ATmega 328 |
1 | Relais quadruple ou octuple |
2 | NRF24L01 avec module sans fil de 2,4 GHz pour ESP8266 (facultatif) Adaptateur NRF24L01) |
1 | Nano V3.0 CH340 |
1 | "Clavier souris" (dip-switch) ou 4-8 interrupteurs |
alternativement | 4 - 8 touches |
alternativement | TTP229 Module de capteur capacitif tactile numérique 16 canaux |
MB 102 Breadboard Kit |
Considérations préliminaires concernant la transmission du signal
Pour une transmission sûre des données, il est judicieux de choisir un code unique pour les états de commutation souhaités. Au code de base de 4000 choisi arbitrairement, j'ajoute à chaque fois la puissance de deux du relais souhaité. Comme toujours lors de la programmation, le comptage commence à 0 et se termine à 3 pour quatre relais ou à 7 pour huit relais.
Exemple : les relais 0, 2 et 7 doivent être commutés, donc 4000 + 2 puissance 0 + 2 puissance 2 + 2 puissance 7 donne un code de 4000 + 1 + 4 + 128 = 4133. Si le deuxième relais est ensuite désactivé, le code passe à 4129. Un petit tableau sur la valeur des relais (= puissance de 2) :
n |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
2 élevé n |
1 |
2 |
4 |
8 |
16 |
32 |
64 |
128 |
Cependant, dans notre circuit, nous utilisons une logique négative, c'est-à-dire qu'en raison des résistances pull-up internes (voir ci-dessous), l'état désactivé est 1, à l'activation, nous relions la broche à GND et l'état devient 0. Dans ce cas, nous soustrayons la valeur respective de 4015 (pour quatre interrupteurs, sinon 4255), donc le code 4015 signifie : tous les 4 interrupteurs éteints, le code 4000 signifie tous les interrupteurs allumés.
Pour l'évaluation du code sur le récepteur, on commence par soustraire les 4000 choisis arbitrairement ; la valeur restante se situe entre 0 (tout ON) et 15 (quatre OFF) ou 255 (huit OFF). Dans mon relais quadruple, la logique négative m'aide, car les différents relais sont activés lorsque l'entrée correspondante est reliée à GND. Faites attention au type de relais que vous voulez utiliser et à l'état dans lequel il s'active. J'aborde à nouveau le thème de la "logique négative" plus loin.
Pour la suite, une petite boucle for avec la fonction bitRead() est utile.
au début du sketch :
int bitArray[4]; // resp. 8 for 8 relays
dans la fonction loop() :
for (i = 0; i < 4; i++) {
bitArray[i] = bitRead(var, i); //Variable var steht für den korrigierten Code
A la fin, le bitArray[i] contient l'état de commutation 0 ou 1 pour chaque relais.
Intégration des émetteurs-récepteurs dans les deux sketches
Tout d'abord, les bibliothèques de programmes nécessaires sont intégrées au début du sketch :
/* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
RF24 radio(9, 10); // CE, CSN, MOSI=11, MISO=12, SCK=13
const byte address[6] = "Code8"; // frei wählbare Adresse der Transceiver
L'initialisation se fait ensuite dans la fonction void setup() :
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening(); // beim Sender
respectivement
radio.startListening(); // beim Empfänger
Dans le sketch de l'émetteur, je définis une fonction sendcode :
void sendcode() {
radio.write(&code, sizeof(code));
delay(100); // little delay for next button press
}
Chez le récepteur, la fonction void loop() commence par
if (radio.available()) {
radio.read(&code, sizeof(code));
La partie la plus facile est en principe l'interrogation des interrupteurs : déterminer les numéros des broches, les définir comme entrées dans le setup et interroger les états dans la boucle (loop). Pour éviter les résistances inutiles, j'opte pour les résistances pull-up intégrées ; cela signifie une logique négative (voir ci-dessus), la broche est commutée vers GND. Et en raison du grand nombre d'interrupteurs, j'opte pour des tableaux avec les numéros de broches et les états de commutation.
Le circuit pour l'émetteur avec quatre interrupteurs
Au lieu de 4 ou 8 interrupteurs individuels, j'utilise un "piano à souris". Qu'est-ce que c'est, demandent les plus jeunes. Ce sont huit interrupteurs miniatures alignés. Largement utilisés sur les cartes mères d'ordinateurs des années 1990 pour définir la configuration respective du PC.
Image et schéma électrique
Le sketch pour l'émetteur avec quatre interrupteurs (Download):
/*
* Arduino Wireless Communication
* Transmitter Code for 4 Relais
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
RF24 radio(9, 10); // CE, CSN
const byte address[6] = "Code8";
int code=4000;
int inputPins[4]={2,3,4,5};
void setup() {
Serial.begin(9600);
for (int i=0; i <= 3; i++){
pinMode(inputPins[i],INPUT_PULLUP);
}
radio.begin();
radio.openWritingPipe(address);
radio.setPALevel(RF24_PA_MIN);
radio.stopListening();
} // end setup
void sendcode() {
radio.write(&code, sizeof(code));
delay(100); // little delay for next button press
} // end sendcode
void loop() {
code = 4000;
int n = 1;
for (int i=0; i <= 3; i++){
int digRead = digitalRead(inputPins[i]);
Serial.print(" i = ");
Serial.print(i);
Serial.print(" digRead = ");
Serial.println(digRead);
code = code + n * digRead;
n = n*2;
}
Serial.print(" Code = ");
Serial.println(code);
sendcode();
} // end loop
Le circuit pour le récepteur avec quatre relais
Image et schéma de câblage
Le sketch pour le récepteur avec quatre relais (Download):
/*
* Arduino Wireless Communication
* Receiver Code for 4 Relais
*
* Library: TMRh20/RF24, https://github.com/tmrh20/RF24/
*/
RF24 radio(9, 10); // CE, CSN, MOSI=11, MISO=12, SCK=13
const byte address[6] = "Code8";
int code = 4000;
int outputPins[4]={2,3,4,5}; // resp. 8 for 8 relays
int bitArray[4]; // resp. 8 for 8 relays
int var = 0;
void setup() {
Serial.begin(9600);
for (int i=0; i <= 3; i++){
pinMode(outputPins[i],OUTPUT);
}
radio.begin();
radio.openReadingPipe(0, address);
radio.setPALevel(RF24_PA_MIN);
radio.startListening();
} //end void setup
void loop() {
if (radio.available()) {
radio.read(&code, sizeof(code));
Serial.println(code);
if (code>=4000 &&code<4256) {
Serial.print("Code ist ");
Serial.println(code-4000);
var = code-4000;
Serial.println(var,BIN);
int i = 0;
for (i = 0; i < 4; i++) {
bitArray[i] = bitRead(var, i);
Serial.print("Schalter ");
Serial.print(i+1);
Serial.print(" ist ");
Serial.println(bitArray[i]);
digitalWrite(outputPins[i],bitArray[i]);
}
}
}
} //end void loop
Et maintenant, le tout à nouveau avec des boutons ou le pavé tactile capacitif :
Tout le monde n'a pas un tel clavier de souris ou des interrupteurs. Mais les boutons sont présents chez tous les makers et les électroniciens amateurs. Si nous utilisons des boutons, nous devons toutefois adapter les sketches afin d'activer ou de désactiver un relais à chaque fois que nous appuyons sur un bouton. (Qui voudrait maintenir le bouton-poussoir enfoncé tout le temps ?)
Nous avons besoin de trois variables pour chaque bouton-poussoir (chaque relais à l'extrémité de la liaison radio) :
- le statut que nous voulons envoyer
- l'état précédent
- l'état actuel de notre bouton-poussoir
Pour tous les signaux d'entrée, nous utilisons à nouveau des tableaux :
int StatusPins[4]={0,0,0,0};
int lastStatusPins[4]={0,0,0,0};
int buttonStatus[4]={0,0,0,0};
Dans la void loop(), nous interrogeons successivement tous les boutons-poussoirs dans une boucle for et les comparons avec l'état précédent. S'ils ne sont pas égaux et que le bouton est à nouveau LOW, l'état envoyé est inversé. Enfin, la variable de l'état précédent est mise à jour.
for (i=0; i <= 3; i++){
buttonStatus[i] = digitalRead(inputPins[i]);
}
delay(100); // avoid bouncing
for (i=0; i <= 3; i++){
if (buttonStatus[i] != lastStatusPins[i]) {
if (buttonStatus[i] == LOW) {
StatusPins[i] = !StatusPins[i];
}
lastStatusPins[i] = buttonStatus[i];
}
Voici le sketch à télécharger.
Si vous n'aimez pas le fait que tous les relais soient activés lors de la première mise sous tension (nous nous en souvenons - "logique négative"), vous pouvez apporter une petite modification dans le sketch du récepteur :
On change la ligne 35 en
var = 15 - (code-4000); // bei 8 Relais 255 – ( )
Cela s'applique à nouveau à mon relais quadruple, dont les entrées doivent être "groundées" pour être activées.
"Touch" au lieu de "Push" :
Il existe un type de palpeur qui est presque indestructible sur le plan mécanique et électrique : Les capteurs tactiles qui fonctionnent selon le principe de la modification de la capacité.
Pour la suite, j'utilise le module de capteur capacitif numérique tactile à 16 canaux TTP229, qui marche de deux manières différentes : 1. il y a huit sorties qui passent chacune en HIGH lorsque l'on touche les boutons 1 à 8. 2. et il y a une sortie série avec deux lignes SCL et SDO.
Remarques concernant le point 1 : nous devons tenir compte de la "logique positive" (active HIGH) dans le circuit et le sketch (voir ci-dessous). Et nous pouvons définitivement utiliser un maximum de huit pavés tactiles.
Remarques concernant le point 2 : Malgré la similitude des noms, les deux lignes ne sont pas une interface I2C. C'est pourquoi la bibliothèque TTP229 d'Alexander Kiryanenko, affichée dans le gestionnaire de bibliothèques d'Arduino IDE, ne peut pas être utilisée. Il existe une bibliothèque appropriée sur la page du produit, sous Téléchargements.
Remarques générales : Plusieurs options sont réglables avec des cavaliers sur d'autres contacts - non pourvus de broches. Les valeurs par défaut pour "single touch" et la limitation aux huit premiers pavés tactiles sont correctes pour notre projet. L'alimentation en tension n'est pas critique pour tous les microcontrôleurs, aussi bien 3,3 volts que 5V sont possibles. Plus de détails ci-dessous.
Si, comme moi, vous ne voulez commuter que quatre relais au maximum, je vous recommande d'utiliser les sorties numériques OUT1 à OUT4, c'est-à-dire 2 lignes pour l'alimentation et quatre lignes vers les entrées numériques du microcontrôleur, pas de cavaliers ni de bibliothèque de programmes.
En plus de la connexion avec OUT1 à OUT4, nous devons connecter ce que l'on appelle des résistances pulldown entre les entrées et GND afin d'avoir toujours un état défini. Lorsque l'on touche le pavé tactile correspondant, l'entrée est HIGH, puis LOW lorsqu'on la relâche.
Dans le sketch pour les boutons-poussoirs, seules deux lignes doivent être modifiées :
A la ligne 21, le pinMode est défini comme suit à la place de INPUT_PULLUP :
pinMode(inputPins[i],INPUT);
Et la ligne 43 demande si l'entrée est commutée HIGH :
if (buttonStatus[i] == HIGH) {
Personnellement, je trouve que la "logique positive" est plus facile à comprendre. Malheureusement, les Arduino ne connaissent comme pinMode que OUTPUT, INPUT et INPUT_PULLUP (avec des résistances PULLUP internes). C'est pourquoi des résistances pulldown externes sont nécessaires pour cela, comme décrit ci-dessus. Mais il existe aussi le microcontrôleur ESP32 qui comprend le pinMode INPUT_PULLDOWN (donc qui a des résistances pulldown internes).
Le fabricant du module a toutefois également intégré la possibilité d'une logique négative, c'est-à-dire que les OUT1 à OUT8 reçoivent un potentiel GND en cas de contact. Mais pour cela, nous devons prendre le fer à souder et souder les barrettes de broches supplémentaires (non fournies). Tant que nous y sommes : voici la description des principales options :
TP0 |
0 |
8 broches de sortie - sortie CMOS active LOW |
Cavalier placé |
TP0 |
1 |
8 broches de sortie - Sortie CMOS active HIGH |
Default |
TP2 |
0 |
Mode 16 canaux (16 touches d'entrée) |
Cavalier positionné, uniquement 2-wire |
TP2 |
1 |
Mode 8 canaux (8 touches d'entrée) |
Défaut, 2-wire ou OUT |
TP3 et TP4 |
0, 0 |
Toutes les touches multiples |
Les deux cavaliers sont activés |
TP3 et TP4 |
1, 1 |
Toutes les touches uniques |
Default |
Donc : si on veut avoir la logique négative (active LOW) sur les broches numériques OUT, il faut mettre le cavalier sur TP0, mais pas de cavalier sur TP2. Les modifications de la configuration nécessitent un redémarrage du module.
Même si j'ai testé plusieurs options : Les valeurs par défaut (toutes les connexions ouvertes, pas besoin de souder) conviennent bien à notre projet de quatre ou huit relais.
Maintenant, cela devient encore plus difficile. Mais cela en vaut la peine ! Seulement deux lignes de données (plus l'alimentation) pour huit ou même seize pavés tactiles. Comme décrit ci-dessus, il ne s'agit pas d'une interface I2C. Nous pouvons donc utiliser des broches numériques normales pour SCL et SDO. Mais la lecture des données nécessite une bibliothèque spécifique.
Pour ce faire, nous téléchargeons les librairies Arduino depuis la page produit du TTP229 16-Channel Digital Touch Sensor Module dans la colonne "Important Downloads & Links".
Le fichier TTP229.zip avec le contenu suivant est nécessaire :
Ce fichier zip est déplacé dans le sous-dossier \Arduino\libraries et ensuite intégré dans le menu Sketch/Bibliothèque inclure/.ZIP bibliothèque ajouter...Ainsi, deux exemples de sketches sont également disponibles : Calculator et KeyToSerial. Le premier sketch montre le "multi-keys mode", c'est-à-dire la possibilité d'appuyer sur plusieurs pavés tactiles en même temps, le deuxième sketch montre le "single-key mode", c'est-à-dire un seul pavé tactile à la fois. Les deux sketches utilisent la connexion 2-wire, c'est-à-dire SCL et SDO.
Revenons à notre projet de radiocommande de quatre ou huit relais, nous relions maintenant SCL à la broche D2 et SDO à la broche D3 (au choix).
Dans mon sketch (Download), j'ai choisi la branche switch - case parce que j'avais obtenu des résultats absurdes avec la fonction exponentielle pow() en raison des différents types de données et des erreurs d'arrondi. Seul piège : les pavés numériques sont désignés de 1 à 8, mais les valeurs sont comprises entre 2 puissance 0 et 2 puissance 7, c'est-à-dire toujours un de moins que le chiffre indiqué sur le pavé numérique. Le sketch du côté du récepteur reste inchangé, sauf si vous souhaitez commuter huit relais.
Et voilà, c'est tout. En fait, ce n'est pas difficile si nous n'avions pas dû nous battre avec la logique négative (active LOW) ou les résistances pulldown. Amusez-vous bien à les reproduire.
1 commentaire
TOMMERAY
Merci, du matériel proposé avec explications en français et le sketch qui va avec. Un pas en avant, c’est parfait.