Bonsoir, après avoir étudié ,en fonction de mes compétences, deux autres méthodes purement électronique en vain j'ai récupéré le kit que j'avais offert à mon fils il y a un an et voici ce que j'ai réussis à faire en quelques jours.
Mon installation hifi est composée d'un filtre actif, compresseur, équaliseur et de plusieurs amplis et comme source un PC musique. J'en avais assez d'allumer le PC musique, ensuite les filtres & co et les amplis. Je voulais n'avoir que le PC musique à allumer et que le reste se fasse tout seul.
J'utilise une sortie USB pour alimenter l'Arduino et le +5 de l'USB pour savoir si le PC est allumé ou pas.
Une fois démarré un relais alimente l'alim 9V de l'Arduino et à l'extinction ce même relais coupe tout.
Elles n'apparaissent pas sur le schéma mais j'ai rajouté une résistance de rappel à la masse de 10k sur chaque pin.
Voici le code
int RelAlim=2;
int RelAmp=4;
int RelEq=6;
int PCusb=8;
void setup(){
pinMode(RelAlim, OUTPUT);
pinMode(RelAmp, OUTPUT);
pinMode(RelEq, OUTPUT);
pinMode(PCusb, INPUT);
digitalWrite(RelAlim, HIGH); //Alimentation du circuit via le transfo
}
void loop(){
if (digitalRead(PCusb)==HIGH){ //PC Musique Allumé
digitalWrite(RelAlim, HIGH); //Maintient relais Alim ON
delay(500); //Tempo pour ne pas surcharger l'alim
digitalWrite(RelEq, HIGH); //Allumage relais Eq
delay(5000); //Tempo avant d'allumer les amplis
digitalWrite(RelAmp, HIGH); //Allumage relais Ampli
}
if (digitalRead(PCusb)==LOW){ //PC Musique éteind
digitalWrite(RelAmp, LOW); //Coupure relais Ampli
delay(5000); //Tempo attente que l'ampli soit éteind
digitalWrite(RelEq, LOW); //Coupure relais Eq
delay(500); //Tempo pour ne pas surcharger l'alim
digitalWrite(RelAlim, LOW); //Coupure relais Alim. On coupe le circuit
}
}
C'est mon premier code alors dites moi ce que vous en pensez et ce que je peux apporter comme amélioration.
Bonsoir mimikrakra
Pour ce faire, j'ai une multiprise "automatique" avec une prise maître où est connecté le PC, quand le PC consomme, ça allume les autres prises.
Je crois que ça s'appelle une smart power strip.
Salut, je connais juste de nom ce genre de prises. Je n'ai pas cherché de ce coté car je voulais un système avec zéro conso au repo et surtout avec la possibilité de différer l'allumage des éléments.
En plus ça me donne l'occasion de mettre un pied dans la programmation.
Bonjour, en relisant mon programme je me suis rendu compte que la boucle passait son temps à allumer les relais et à chaque passage il y a la tempo "delay" donc je l'ai réécris en prenant en compte l'état des sorties.
J'ai une version avec "if" et une autre avec "while". Les deux sont supposées fonctionner mais "while" dans l'esprit irait mieux, je pense.
Pendant que le micropoc traite ma boucle "while" est-ce qu'il peut traiter autre chose ou est-ce qu'il est bloqué dans la boucle tant qu'elle est active? je ferai le test ce soir ou ce weekend.
Voici les deux versions, dites moi ce que vous en pensez.
Merci ^^
int RelAlim=2;
int RelAmp=4;
int RelEq=6;
int PCusb=8;
void setup(){
pinMode(RelAlim, OUTPUT);
pinMode(RelAmp, OUTPUT);
pinMode(RelEq, OUTPUT);
pinMode(PCusb, INPUT);
digitalWrite(RelAlim, HIGH); //Alimentation du circuit via le transfo
delay(500);
digitalWrite(RelAmp, LOW); //Relais ampli OFF
digitalWrite(RelEq, LOW); //Relais Eq OFF
}
void loop(){
if (digitalRead(PCusb)==HIGH){ //PC Musique Allumé
if (digitalRead(RelAlim)==LOW){ //Si relais Alim OFF
digitalWrite(RelAlim, HIGH); //Allumage relais Alim
delay(500); //Tempo pour ne pas surcharger l'alim
}
if (digitalRead(RelEq)==LOW){ //Si relais Eq OFF
digitalWrite(RelEq, HIGH); //Allumage relais Eq
delay(5000); //Tempo avant d'allumer les amplis
}
if (digitalRead(RelAmp)==LOW){ //Si relais Ampli OFF
digitalWrite(RelAmp, HIGH); //Allumage relais Ampli
}
}
if (digitalRead(PCusb)==LOW){ //PC Musique éteind
if (digitalRead(RelAmp)==HIGH) {
digitalWrite(RelAmp, LOW); //Coupure relais Ampli
delay(5000); //Tempo attente que l'ampli soit éteind
}
if (digitalRead(RelEq)==HIGH){
digitalWrite(RelEq, LOW); //Coupure relais Eq
// delay(500); //Tempo pour ne pas surcharger l'alim
}
if (digitalRead(RelAlim)==HIGH) {
digitalWrite(RelAlim, LOW); //Coupure relais Alim. On coupe le circuit
}
}
}
int RelAlim=2;
int RelAmp=4;
int RelEq=6;
int PCusb=8;
void setup(){
pinMode(RelAlim, OUTPUT);
pinMode(RelAmp, OUTPUT);
pinMode(RelEq, OUTPUT);
pinMode(PCusb, INPUT);
digitalWrite(RelAlim, HIGH); //Alimentation du circuit via le transfo
delay(500); //Attente 500ms
digitalWrite(RelAmp, LOW); //Relais ampli OFF
digitalWrite(RelEq, LOW); //Relais Eq OFF
}
void loop(){
while (digitalRead(PCusb)==HIGH) { //Tant que le PC est allume alors...
if (digitalRead(RelAlim)==LOW){ //Si relais Alim OFF
digitalWrite(RelAlim, HIGH); //Allumage relais Alim
delay(500); //Tempo pour ne pas surcharger l'alim
}
if (digitalRead(RelEq)==LOW){ //Si relais Eq OFF
digitalWrite(RelEq, HIGH); //Allumage relais Eq
delay(5000); //Tempo avant d'allumer les amplis
}
if (digitalRead(RelAmp)==LOW){ //Si relais Ampli OFF
digitalWrite(RelAmp, HIGH); //Allumage relais Ampli
}
}
while (digitalRead(PCusb)==LOW) { //Tant que le PC est éteint
if (digitalRead(RelAmp)==HIGH) { //Si relais ampli ON
digitalWrite(RelAmp, LOW); //Coupure relais Ampli
delay(5000); //Tempo attente que l'ampli soit éteind
}
if (digitalRead(RelEq)==HIGH){ //Si relais Eq ON
digitalWrite(RelEq, LOW); //Coupure relais Eq
}
if (digitalRead(RelAlim)==HIGH) { //Si realais Alim ON
digitalWrite(RelAlim, LOW); //Coupure relais Alim. On coupe le circuit
}
}
}
Les relais sont alimentés en 5V par une sortie de l'Arduino. Les relais consomment-ils vraiment moins de 20mA? En général, on ne peut pas alimenter un relais directement par Arduino.
Ahhhh je ne m'étais pas posé la question.
Ce sont des relais Finder 40.52-05 que j'avais acheté au début du projet avant de passer à l'Arduino.
Sur la doc la bobine est donnée pour 130mA donc c'est loin des 20mA. En tout ca ça fonctionnait bien lors de mes essais ...mais pour combien de temps ?
Je regarde sur amazon les cartes 8 relais qui sont prévues pour être pilotées directement par les sorties de l'Arduino et quand c'est indiqué certaines demandent 70mA par canal. Ce n'est pas parce que c'est en vente qu'il faut l'acheter, je sais ^^.
Il me faut des relais capables de supporter 250V/10A car j'ai des amplis derrière.
Ces relais consomment 70mA par canal, ce qui est différent. 70mA est le courant de bobine.
Ils demandent en général quelques mA sur la commande, pas plus.
Au début mon projet était prévu avec des montages RC pour gérer la tempo des relais. En théorie ça fonctionne très bien mais en pratique, non. Sur un forum d'électronique on m'a parlé de super condensateur etc. donc j'ai lâché l'affaire. J'avais déjà commandé les relais avec leur support pour faire mes essais.
Maintenant avec l'Arduino je peux faire un montage propre et avec le module 8 relais l'ensemble est plus compacte. Ce sont des relais 1RT et je veux couper le neutre et la phase donc 6 relais.
Les deux codes sont quasi équivalents dans la mesure ou tu ne fais rien 'autre. On peut faire des tas de test ou rester bloqué, cela n'a pas une grande importance.
L'avantage de la machine à états qui va bloquer les différentes étapes est que l'on ne va pas passer de l'allumage à l'extinction rapidement si il y a un faux contact sur la prise USB. Voir ce que cela donne avec tes deux versions.
Une tension fugitive sur l'USB va provoquer l'allumage de RelAlim, de RelEq pendant 5s.
Une perte de tension très brève sur l'USB (on bouge le câble) Va tout éteindre et rallumer.
C'est un fonctionnement possible, mais est-ce bien cela que tu désires?
Merci pour tes remarques.
C'est vrai que d'activer une sortie qui est déjà active ne sert pas à grand chose. Mon but était de rajouter ensuite le delay.
Le delay est bien mais il met tout le programme en pause donc j'ai un peu cherché et travailler avec millis() c'est beaucoup mieux.
Voici encore une version du programme. Je fais peut être trop contrôles et de tests de variables ?
int RelAlim=2;
int RelAmp=4;
int RelEq=6;
int PCusb=8;
long Temps;
long TempsPC;
int ChgtPCusb;
void setup(){
pinMode(RelAlim, OUTPUT);
pinMode(RelAmp, OUTPUT);
pinMode(RelEq, OUTPUT);
pinMode(PCusb, INPUT);
digitalWrite(RelAlim, HIGH); //Alimentation du circuit via le transfo
digitalWrite(RelAmp, LOW); //Relais ampli OFF
digitalWrite(RelEq, LOW); //Relais Eq OFF
Temps=millis(); //enregistre l'heure - Début du chrono
TempsPC=millis();
ChgtPCusb=digitalRead(PCusb); //Initialisation de la variable de changement d'état de l'USB
}
void loop(){
if (ChgtPCusb != digitalRead(PCusb)) { //Si l'état de l'USB et différent
TempsPC=millis(); //Enregistre l'heure - Début du chrono
ChgtPCusb=PCusb; //Initialisation de la variable de changement d'état de l'USB
}
if ((digitalRead(PCusb)==HIGH) & ((millis()-TempsPC) > 1000)) { //Si PC Musique Allumé et tempo > à 1000ms
if ((digitalRead(RelAlim)==LOW) & digitalRead(RelEq)==LOW & digitalRead(RelAmp)==LOW) { //Si relais alim OFF et relais EQ OFF et Relais ampli OFF
digitalWrite(RelAlim, HIGH); //Allumage relais alim
}
if (digitalRead(RelAlim)==HIGH & digitalRead(RelEq)==LOW & digitalRead(RelAmp)==LOW) { //Si relais alim ON et relais EQ OFF et relais ampli OFF
digitalWrite(RelEq, HIGH); //Allumage relais Eq
Temps=millis(); //Enregistre l'heure
}
if (digitalRead(RelAlim)==HIGH & digitalRead(RelEq)==HIGH & digitalRead(RelAmp)==LOW & ((millis()-Temps)>5000)) { //Si relais alim ON et relais EQ ON et relais ampli OFF
digitalWrite(RelAmp, HIGH); //Allumage relais ampli
Temps=millis(); //Enregistre l'heure
}
}
if ((digitalRead(PCusb)==LOW) & ((millis()-TempsPC) > 1000)) { //Si PC Musique éteind et tempo > à 1000ms
if (digitalRead(RelAmp)==HIGH & (digitalRead(RelEq)==HIGH) & (digitalRead(RelAlim)==HIGH)) { //Si relais ampli ON et relais EQ ON et relais alim ON
digitalWrite(RelAmp, LOW); //Coupure relais ampli
Temps=millis(); //Enregistre l'heure
}
if (digitalRead(RelAmp)==LOW & (digitalRead(RelEq)==HIGH) & (digitalRead(RelAlim)==HIGH) & ((millis-Temps) > 5000)) { //Si relais ampli OFF et relais EQ ON et relais alim ON
digitalWrite(RelEq, LOW); //Coupure relais Eq
}
if (digitalRead(RelAmp)==LOW & (digitalRead(RelEq)==LOW) & (digitalRead(RelAlim)==HIGH)) { //Si relais ampli OFF et relais EQ OFF et relais alim ON
digitalWrite(RelAlim, LOW); //Coupure relais Alim. On coupe le circuit
}
}
}
Apres quelques erreurs d'écritures de certaines variables ça fonctionne ^^
Votre avis sur le code...
int RelAlima=2;
int RelAlimb=4;
int RelAmpa=6;
int RelAmpb=8;
int RelEqa=10;
int RelEqb=12;
int PCusb=13;
long Temps;
long TempsPC;
int ChgtPCusb;
void setup(){
pinMode(RelAlima, OUTPUT);
pinMode(RelAlimb, OUTPUT);
pinMode(RelAmpa, OUTPUT);
pinMode(RelAmpb, OUTPUT);
pinMode(RelEqa, OUTPUT);
pinMode(RelEqb, OUTPUT);
pinMode(PCusb, INPUT_PULLUP);
digitalWrite(RelAlima, HIGH); //Alimentation du circuit via le transfo
digitalWrite(RelAlimb, HIGH); //Alimentation du circuit via le transfo
digitalWrite(RelAmpa, LOW); //Relais ampli OFF
digitalWrite(RelAmpb, LOW); //Relais ampli OFF
digitalWrite(RelEqa, LOW); //Relais Eq OFF
digitalWrite(RelEqb, LOW); //Relais Eq OFF
Temps=millis(); //enregistre l'heure - Début du chrono
TempsPC=millis(); //enregistre l'heure - Début du chrono
ChgtPCusb=digitalRead(PCusb); //Initialisation de la variable de changement d'état de l'USB
}
void loop(){
if (digitalRead(ChgtPCusb) != digitalRead(PCusb)) { //Si l'état de l'USB et différent
TempsPC=millis(); //Enregistre l'heure - Début du chrono
ChgtPCusb=PCusb; //Initialisation de la variable de changement d'état de l'USB
}
if ((digitalRead(PCusb)==HIGH) & ((millis()-TempsPC) > 1000)) { //Si PC Musique Allumé et tempo > à 1000ms
if ((digitalRead(RelAlima)==LOW) & digitalRead(RelEqa)==LOW & digitalRead(RelAmpa)==LOW) { //Si relais alim OFF et relais EQ OFF et Relais ampli OFF
digitalWrite(RelAlima, HIGH); //Allumage relais alim
digitalWrite(RelAlimb, HIGH); //Allumage relais alim
}
if (digitalRead(RelAlima)==HIGH & digitalRead(RelEqa)==LOW & digitalRead(RelAmpa)==LOW) { //Si relais alim ON et relais EQ OFF et relais ampli OFF
digitalWrite(RelEqa, HIGH); //Allumage relais Eq
digitalWrite(RelEqb, HIGH); //Allumage relais Eq
Temps=millis(); //Enregistre l'heure
}
if (digitalRead(RelAlima)==HIGH & digitalRead(RelEqa)==HIGH & digitalRead(RelAmpa)==LOW & ((millis()-Temps)>5000)) { //Si relais alim ON et relais EQ ON et relais ampli OFF
digitalWrite(RelAmpa, HIGH); //Allumage relais ampli
digitalWrite(RelAmpb, HIGH); //Allumage relais ampli
Temps=millis(); //Enregistre l'heure
}
}
if ((digitalRead(PCusb)==LOW) & ((millis()-TempsPC) > 1000)) { //Si PC Musique éteind et tempo > à 1000ms
if (digitalRead(RelAmpa)==HIGH & (digitalRead(RelEqa)==HIGH) & (digitalRead(RelAlima)==HIGH)) { //Si relais ampli ON et relais EQ ON et relais alim ON
digitalWrite(RelAmpa, LOW); //Coupure relais ampli
digitalWrite(RelAmpb, LOW); //Coupure relais ampli
Temps=millis(); //Enregistre l'heure
}
if (digitalRead(RelAmpa)==LOW & (digitalRead(RelEqa)==HIGH) & (digitalRead(RelAlima)==HIGH) & ((millis()-Temps) > 5000)) { //Si relais ampli OFF et relais EQ ON et relais alim ON
digitalWrite(RelEqa, LOW); //Coupure relais Eq
digitalWrite(RelEqb, LOW); //Coupure relais Eq
}
if (digitalRead(RelAmpa)==LOW & (digitalRead(RelEqa)==LOW) & (digitalRead(RelAlima)==HIGH)) { //Si relais ampli OFF et relais EQ OFF et relais alim ON
digitalWrite(RelAlima, LOW); //Coupure relais Alim. On coupe le circuit
digitalWrite(RelAlimb, LOW); //Coupure relais Alim. On coupe le circuit
}
}
}
Cela représente quoi ChgtPCusb et PCusb? Le numéro des entrées, un état? Il y a un mélange! Que doivent elle contenir?
La première ligne dit que PCusb est un numéro de pin (constante), et que ChgtPCusb vaut HIGH ou LOW. Mais dans ce cas, on ne peut pas faire digitalRead(ChgtPCusb).
Sinon quelques remarques de moindre imoprtance, qui ne nuisent en rien au fonctionnement.
Je suis assez allergique à ce genre de déclarations que l'on voit 99% du temps. Ce nombre est utilisé dans le digitalReadWrite qui demandent un uint8_t. Pourquoi demander un int (2 octets) plutôt qu'un uint8_t (1 octet). De plus c'est une constante, autant la définir comme telle. Cela fait: const uint8_t RelAlima=2;
D'accord, de toutes façon le résultat est exactement le même, le compilateur corrige.
Usuellement la convention des nom en C++ serait de mettre les constantes en majuscules (LOW, HIGH, mais pourquoi pas aussi PC_USB, REL_ALIMA...), les variables en minuscules, avec un majuscule pour séparer les mots (chgtPCusb, temps...) C'est surtout pour celui qui lit le code sans l'avoir écrit.
C'est bien par contre de mettre des commentaires. C'est une bonne habitude à prendre.
ChgtPCusb contient la valeur précédente de PCusb qui est l'état du signal USB.
Au démarrage c'est le PC Musique qui alimente la carte Arduino via l'USB et je repique le +5 sur la pin 13 (PCusb) pour savoir si le PC est allumé ou pas. C'est pour ça qu'il y l'alim 9V (RelAlim) pour maintenir l'Arduino en vie à la coupure de l'USB.
Avec ChgtPCusb je peux calculer depuis combien de temps PCusb est actif (une remarque qui m'a été faite pour éviter le bagotement)
Pourquoi on ne peut pas faire ça? Ca fonctionne bien
Merci pour les remarques de moindre importance mais importantes tout de même. Je vais faire attention à tout ça.