Bonjour,
Je cherche un moyen de commander plusieurs relais simultanément, avec mon Raspberry.
Actuellement, j'utilise la commande gpio, pour contrôler les broches du GPIO
Voici, en bash, mon premier essai de chenillard :
Une boucle qui enclenche et déclenche, successivement, les douze premiers relais d'une carte de seize.
Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
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 gpio -g mode 26 out gpio -g mode 19 out gpio -g mode 13 out gpio -g mode 6 out gpio -g mode 5 out gpio -g mode 21 out gpio -g mode 20 out gpio -g mode 16 out gpio -g mode 12 out gpio -g mode 25 out gpio -g mode 24 out gpio -g mode 23 out sleep 5 while true; do # Enclenche gpio -g write 26 1 sleep 0.2 gpio -g write 19 1 sleep 0.2 gpio -g write 13 1 sleep 0.2 gpio -g write 6 1 sleep 0.2 gpio -g write 5 1 sleep 0.2 gpio -g write 21 1 sleep 0.2 gpio -g write 20 1 sleep 0.2 gpio -g write 16 1 sleep 0.2 gpio -g write 12 1 sleep 0.2 gpio -g write 25 1 sleep 0.2 gpio -g write 24 1 sleep 0.2 gpio -g write 23 1 sleep 0.2 # Déclenche gpio -g write 26 0 sleep 0.2 gpio -g write 19 0 sleep 0.2 gpio -g write 13 0 sleep 0.2 gpio -g write 6 0 sleep 0.2 gpio -g write 5 0 sleep 0.2 gpio -g write 21 0 sleep 0.2 gpio -g write 20 0 sleep 0.2 gpio -g write 16 0 sleep 0.2 gpio -g write 12 0 sleep 0.2 gpio -g write 25 0 sleep 0.2 gpio -g write 24 0 sleep 0.2 gpio -g write 23 0 sleep 0.2 done
A raison d'un relais manoeuvré toutes les 200 millisecondes.
Ensuite, j'ai rédigé un script PHP, destiné à être appelé par une requête Ajax.
Code php : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 <?php $lesBroches = array(26, 19, 13, 6, 5, 21, 20, 16, 12, 25, 24, 23); if(isset($_POST['relais']) && $_POST['relais'] >= 0 && $_POST['relais'] < count($lesBroches) && isset($_POST['etat'])) { $leRelais = min(max(0, $_POST['relais']), count($lesBroches)); $lEtat = min(max(0, $_POST['etat']), 1); $commande = 'gpio -g mode '.$lesBroches[$leRelais].' out;sleep 100 ms;gpio -g write '.$lesBroches[$leRelais].' '.$lEtat; system($commande); //echo($commande); } ?>
Le tableau $lesBroches est une table de correspondance, entre le relais (indice du tableau) et le n° de son fil de contrôle, partant du GPIO vers la carte.
Ce script PHP est invoqué par une requête Ajax :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 var xhrGpio = new XMLHttpRequest(); ... function enclencher(pRelais, pEtat, pDelai) { var attente = parseInt(Math.random() * pDelai); caseGpio.style.backgroundColor = 'transparent'; caseGpio.innerHTML = ' '; setTimeout ( function(pRelais, pEtat) { xhrGpio.open('POST', 'ajax/ajaxGpio.php'); xhrGpio.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xhrGpio.send('relais=' + pRelais + '&etat=' + pEtat); }, attente, pRelais, pEtat ); }
Cette fonction JavaScript reçoit :
* Le numéro [0..11] du relais à manoeuvrer.
* L'état [0/1] à donner au relais : 0=OFF, 1=ON
* Le temps d'attente avant la manoeuvre.
Le schéma final de mon application est le suivant :
Un logiciel en JavaSCript, dont je vous épargne le détail (boutons, événements), sans pertinence ici, invoque la fonction enclencher(pRelais, pEtat, pDelai),
qui, à son tour, invoque la requête Ajax, située sur la même machine (équipée d'un serveur LAMP), via l'adresse localhost.
Ladite requête Ajax invoque une commande système gpio, qui manoeuvre les relais.
Et c'est là l'objet de ma question.
Car j'ai remarqué qu'en invoquant la commande gpio simultanément, sur deux relais ou plus, un seul d'entre eux était manoeuvré.
J'ai donc légèrement différé la manoeuvre, en instaurant un temps d'attente aléatoire, passé en troisième paramètre, d'une fonction qui n'en comptait, au départ, que deux.
Ainsi, je peux appeler ma fonction "enclencher" deux fois simultanément.
En croisant les doigts, pour que la fonction Math.random() ne génère pas deux valeurs aléatoires trop proches l'une de l'autre.
J'aimerais pouvoir enclencher, ou déclencher, tous mes douze (ou, plus tard, seize) relais simultanément, en une seule requête Ajax.
L'idéal serait que je passe, à ma fonction, non pas le numéro et l'état du relais à manoeuvrer, mais un tableau de nbRelais cases, contenant chacune l'état que le relais correspondant doit prendre.
Rédiger une telle fonction ne me pose aucun problème, mais que doit-elle invoquer ensuite, si la commande gpio a des ratés ?
Actuellement, j'ai trouvé une solution sale :
Créer une boucle de répétition, pour réveiller les relais qui ont raté leur commutation au premier ordre :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 relaisDog = function(pRelais) { // Watchdog d'enclenchement de secours if(pRelais < lesEtats.length) { enclencher(pRelais, parseInt(lesEtats[pRelais]), 500); setTimeout(relaisDog, 300, pRelais + 1); } else { setTimeout(relaisDog, 500, 0); } } ; // Premier appel de lancement setTimeout(relaisDog, 1000, 0);
Comme un chien de garde, qui fait son boulot en arrière-plan, relaisDog répète inlassablement l'état on/off à chaque relais.
Finalement, après un ou deux tours, tout le monde a compris, tous les relais sont bien commutés.
De l'extérieur, ça donne l'impression d'un programme indiscipliné : Chacun commute quand il veut.
Mais qui finit par obéir, avec du retard.
J'aimerais n'entendre qu'un seul déclic. Comme une troupe qui marche au pas.
Fiable à 100%, et sans relaisDog, dont je souhaite me débarrasser.
Existe t'il d'autres commandes que gpio, pour maneuvrer l'état des pins d'un Raspberry ?
Merci pour votre réponse.
Christian.
Partager