Tout d'abord, je tiens à préciser que je ne suis pas expert en programmation !
J'ai déjà fait de nombreux montages qui fonctionnent mais là, je bloque sur quelque chose qui doit être simple mais ça fait deux jours !
je m'explique :
Pour commander mes volets sans changer les commandes locales ( interrupteurs montée/arrêt/descente),
Je souhaite récupérer l'état des entrées ( en Pullup ), répeter cela pour 6 montées et 6 descentes pour pouvoir enclencher mes variables depuis une autre commande sans utiliser (delay) pour ne pas bloquer le programme.
Le cycle devrait être :
SI ( inter montée == LOW) {
MET LA VARIABLE MONTEE_ V1 à 1;
pendant X temps;
puis MET LA VARIABLE MONTEE_V1 à 0;
}
SINON{
MET LA VARIABLE MONTEE V1 à 0
}
SI (VARIABLE MONTEE V1 == 1){
digitalWrite(relais1, LOW);
}
SINON{
digitalWrite(relais1, HIGH);
}
Quel est le problème ? Les faire monter tous ensemble ? Pour cela il te faut un code non bloquant. Là ce que tu fais c'est que tu attends la fin de la montée de l'un pour passer au suivant. Il faut les tester tous mais surtout tester l'arrivée en haut pour les arrêter
Je verrais quelque chose comme ça
Si inter montée LOW
Pour chaque volet
Si pas fin de course : relais HIGH
Sinon relais LOW
Voilà ce que j'ai reussi à pondre, le relais s'enclenche si l'inter est passant, il se coupe lorsque l'inter est ouvert, mais il ne se coupe pas après le temps donné par la tempo si l'inter reste passant ....
HELP ME !!!
unsigned long startTime = 0;
int etat = 0;
int inter = 46;
int relais = 42;
void setup() {
Serial.begin(9600);
pinMode(inter, INPUT_PULLUP);
pinMode(relais, OUTPUT);
}
void loop() {
// Lecture inter
int btn = digitalRead(inter);
// Si inter enclenché
if ( btn == LOW ) {
// On allume le relais
digitalWrite(relais, LOW);
// Et on change d'état en numérotant le temps actuel
etat = 0;
startTime = millis();
}
// Si on est dans l'état 1,
// Cela signifie que l'inter est enclenché
// Et donc que l'on doit vérifier le temps pour éteindre le relais
if ( etat == 1 ) {
}
// Si il s'est écoulé 3 secondes
if ( millis() - startTime >= 3000 ) {
// Alors on éteint le relais
digitalWrite(relais, HIGH);
// Et on revient à l'état initial
etat = 0;
}
//Si inter declenché
else if ( btn == HIGH) {
// Alors on éteint le relais
digitalWrite(relais, HIGH);
}
}
Vous avez 6 volets roulants électriques (Volet1 à Volet6), chacun avec sa commande manuelle 3 positions (Monter, Descendre, Stop)
Vous appuyez sur une commande d'un des volets (Monter, Descendre, Stop) - disons sur le VoletX
--> que voulez vous qu'il se passe pour le VoletX et pour les 5 autres ?
--> comment pilotez vous les autres volets ?
--> mettez nous un petit schéma électrique...
Je crois comprendre qu'il s'agit plutôt d'une commande centralisée.
Par contre sans contact de fin de course, tu risques de forcer sur les moteurs pendant des durées importantes. Il faudrait une sécurité, comme un capteur de courant au niveau des moteurs ? Je pense qu'il existe des exemples sur internet, il faut chercher un peu...
Par contre sans contact de fin de course, tu risques de forcer sur les moteurs pendant des durées importantes.
Non, les capteurs agissent directement sur le moteur, ils sont montés en série avec chaque commande montée / descente.
Tu peux laisser l'interrupteur montée ou descente dans la même position sans problème pendant la nuit. C'est même fait pour cela. Quand tu fermes les volets, tu bascule l'interrupteur et tu peux t'en aller. Ce n'est pas le peine de rester devant pour remettre l'interrupteur dans la position médiane à la fin.
Alors, pas d’inquiétude, les moteurs sont équipés de fin de courses donc pas de risque de forçage.
Si j'avais des boutons poussoir, ça fonctionnerai déjà mais ce sont des interrupteurs qui ne sont pas forcements remis à zéro après manipulation, et à 50€ la commande, je compte pas tout changer !
C'est juste dans le principe, en fait je que je recherche c'est transformer les inter en poussoirs, on récupère l'état et après on l'oubli jusqu'à un nouveau changement d'état.
bonjour ,a tous
j' ai un volet qui me semble être du même type .
normalement la ligne 220 volts 2 fils arrive au boitier d' interrupteur puis 3 fils 220 repartent du boitier inter vers le moteur .
1 fil 220 v d' arrivé au boitier repart au moteur ,il n'est pas coupé
l 'autre fil arrive sur un interrupteur a bascule deux fils en repartent (A,B) .
on a donc:
1 phase ou neutre direct moteur.
1 phase ou neutre direct moteur qui par le biais de l 'inter va être redistribué :
sur A ,ou, sur B ,ou,en l' air (position stop ).
question : pourquoi s' inquiéter d'un instruction bloquante type délai quant on veut faire
une temporisation pour la montée. ou la descente
réponse : pendant le délai a n'importe quel moment avant la fin du délai veut qu 'une action occasionne une réaction.
question : quelle action ??
ATTENsion reponse roulement de tembour ,proooooooooooooom:
OUVRIR OU FERMER LES VOLETS PAS COMPLETEMENT(pour mater la ou le v...)
Tout à fait !
Pouvoir stopper le volet à tout moment !
Ou.....
Pouvoir le contrôler à distance via une application type « Blynk » en action des sorties virtuelles en parallèle des acquisitions des entrées physiques.
Ça me dit toujours pas comment transformer mes inter en poussoir dans mon code !
J'ai lu les messages en diagonale mais j'ai l'impression que ton problème est typiquement ce qui se résoud avec une machine à états. Lis le tuto de J-M-L sur le sujet, dans la section tutos
conformément a la charte qui dit qu' ici on donne pas le code tout fait , je m' excuse :
pas pour créer chez vous un sentiment de frustration ou autre mais parce que tout
simplement j' en suis pas capable...
commençons par le premier problème évoqué
vous êtes bloqué par un instruction bloquante de délai
un délai c' est quoi ? : c' est une variable coincée dans dans une boucle qui s' incrémente de 1 ,
compare sa propre valeur a une valeur x et que temps que cette valeur x n'est pas atteinte ,
le pointeur programme continue a boucler sans rejoindre la boucle (loop ) principale.
pourquoi un délai de l'instruction délai () est il PRÉCIS ?
justement parce qu'il n'y aucune autre instruction que vous pouvez (y) insérer , susceptible de le ralentir donc d' altérer sa précision.
solution : il faux résonner en nombre de cycle de boucle pas en délai
====dans les grandes ligne======
créer un variablecourse=0
créer une valeurcoursemaxi=1000 000//valeur a debuger a l'ecran du pc
etc......
dans la loop de void loop
si j'appuis sur d1//volet complétement fermé au depart du premier allumage
ALORS la pin ou est connecté mon relais se met a 1
variable course= variable course+1 // fameuse boucle temporelle
serialprint variable course// sa va afficher a l' ecrant la course maxi au moment ou vous
// arrêterai votre volet
si j' appui sur stop OU si variablecourse=valeurcousemaxi// faux bûcher un peu les
//opérateurs logiques
alors la pin qui commande le relais repasse a zéro .
=======================
ps j'ai pas remis la variable course a zéro comme cela on sait a peut prêt ou se trouve le volet
sauf si coupure coupure EDF....
un capteur a effet hall sur la ligne 220 peut y remédier ( suggestion de LESEPT)
on peut décrémenter la variable course quand le volets descend , s'il descend a la même vitesse qu'il monte ...
la valeur qu 'affiche l'idée de l'arduino quant vous stoppez le volet en même Temp que le frein de course du moteur 220 v est a réinscrire dans le programme a la place de 1000 000
.
Si je t'ai bien compris, il faudrait un truc du genre :
#define INTER 46
#define relais 42
void setup() {
Serial.begin(9600);
pinMode(INTER, INPUT_PULLUP);
pinMode(relais, OUTPUT);
}
void loop() {
digitalWrite(relais, HIGH);
int etat = digitalRead(INTER);
int course =0;
if (etat == LOW) {
digitalWrite(relais, LOW);
for ( course = 0; course <= 2000; course++) {
Serial.println(course);
}
if ((course == 2000) || (etat == HIGH)){
digitalWrite(relais, HIGH);
}
}
}
après test ça fonctionne lorsque je donne une impulsion sur l'interrupteur mais si celui-ci reste passant, la boucle FOR incrémente jusqu'à 2000 et recommence au début à l'infini....
@PBZOOM
Non... il ne faut pas gérer le temps avec un compteur qui s'incrémente car la rapidité d'incrémentation va dépendre de ce que vous faites entre 2 tours donc même si vous calez le nombre d'itérations (disons 1000000) pour que ça marche dans un cas, dès que vous avez une nouvelle idée et rajoutez du code il faudra changer refaire le boulot. C'est pénible et pas précis... il faut utiliser millis() ou micros() pour cela qui est géré par interruptions et bcp plus précis et surtout indépendant de ce que vous faites.
il vous faut une petite machine à états et utiliser millis() car vous n'avez pas besoin de la précision de micros().
Donc concrètement vous devez détecter un changement (attention aux bounces) de votre interrupteur pour décider des opérations. Je reviens vers ma question d'origine, on a besoin de mieux comprendre cet interrupteur pour vous aider... est-ce un 2 positions (O / I) ou trois positions (I / 0 / II) ?
et un petit schéma nous détaillant comment vous vous connectez (où sont les moteurs, alims, Arduino etc) serait utile aussi
par exemple si c'est un bouton 2 états, en écrivant une fonction qui détecte une bascule du bouton (événement "click") vous pourriez avoir une machine à état du genre
Tout d'abord, je vous remercie pour votre implication dans ma galère !
J'ai passé pas mal de temps à lire votre tuto mais je n'y ai pas trouvé de solution à mon problème.
Les commandes de volets sont des interrupteurs à 3 positions (montée/arrêt/descente).
Les sorties de l'arduino MEGA2560 commanderont 12 relais ( 1 Montée et 1 descente pour chaque volet)
je n'ai pas eu le temps de faire un schéma mais grosso modo ce que je cherche à faire c'est :
if (CMDmontéeV1 == LOW){
//mettre la variable montéeV1 à 1;
//tempo ( très faible sans utiliser de delay);
//puis mettre la variable montéeV1 à 0;
}
else if(CMDdescenteV1 ==LOW){
//mettre la variable descentV1 à 1;
//tempo ( très faible sans utiliser de delay);
//puis mettre la variable descenteV1 à 0;
}
else if ((CMDmontéeV1==HIGH)&&(CMDdescenteV1==HIGH)){
//mettre la variable ArretV1 à 1;
}
Et cela pour chaque commande de volet
En fait, convertir les interrupteur en boutons poussoirs....
J'espère que je suis assez clair dans mes explications !
et merci encore
Désolé, je pensais que le pseudo code était plus explicite à la manière d'un grafcet !
Je n'ai pas besoin de savoir si le volet est ouvert ou fermé, si par exemple je demande une fermeture et que le volet l'est déjà, le relais fermeture devrait s'actionner X temps, cela n'a pas d'incidence puisque le fin de course bas du moteur l'empêchera de fonctionner.
si on passe de 0 à 1 le volet monte pendant X temps si il arrive à son fin de course mécanique il s'arrêtera même si X temps n'est écoulé.
si on passe de 1 à 0 le volet s'arrête immédiatement
si on passe de 0 à 2 le volet descent pendant X temps si il arrive à son fin de course mécanique il s'arrêtera même si X temps n'est écoulé.
si on passe de 2 à 0 le volet s'arrête immédiatement
Cela ne depend pas de la position du volet.
C'est simplement ( ou pas ) pour pouvoir les commander à distance tout en conservant les commandes locales.
Quand j'ai fais mon tableau électrique, j'y avais ramené tous les retours de commandes et tous les départs vers les volets en vu d'y greffer l'arduino et la carte relais.
Maintenant récupérer le changement d'état, lui donner une forme d'impulsion momentanée sans que ce bout de code fasse 4000 lignes, c'est là ma question première !
J'ai vraiment l'impression que je cherche trop compliqué, ou alors ça l'est réellement !