Je suis complètement nouveau en programmation Arduino mais après quelques semaines de recherches, j'ai réussi à écrire un bout de code pour l'éclairage d'une maquette de vaisseau spatial. Cependant je n'arrive pas trouver comment écrire correctement celui-ci pour que les deux LEDs verte et rouge n'interfèrent pas avec les autres lorsqu'on les active en appuyant sur les boutons. Est-ce que quelqu'un pourrait m'expliquer comment faire pour que les LEDs commandées par des boutons soient complètement indépendantes des autres ? Merci d'avance. Voici mon code:
#include <Adafruit_NeoPixel.h>
#define PIN 9
#define NUM_LEDS 2
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);
#define BT 4
#define BTN 2
#define Vert 6
#define Rouge 10
#define Blanc 11
#define Orange 12
#define Bleu 13
int Bleu_State = LOW;
int Orange_State = LOW;
int brightness = 0;
unsigned long prevTime_T1 = millis ();
unsigned long prevTime_T4 = millis ();
long interval_T1 = 1500;
long interval_T4 = 500;
void setup() {
Serial.begin(9600);
pinMode(PIN, OUTPUT);
pinMode(Blanc, OUTPUT);
pinMode(Rouge, OUTPUT);
pinMode(Bleu, OUTPUT);
pinMode(Vert, OUTPUT);
pinMode(Orange, OUTPUT);
pinMode(BTN, INPUT);
pinMode(BT, INPUT_PULLUP);
digitalWrite(Blanc, HIGH);
}
void loop() {
unsigned long currentTime = millis();
// Task 1: LED Orange clignote rapidement
if (currentTime - prevTime_T4 > 500) {
Orange_State = !Orange_State;
digitalWrite(Orange, Orange_State);
prevTime_T4 = currentTime;
}
// Task 2: LED bleu clignote lentement
if (currentTime - prevTime_T1 > 1500) {
Bleu_State = !Bleu_State;
digitalWrite(Bleu, Bleu_State);
prevTime_T1 = currentTime;
}
// Task 3: Neopixels s'allument en jaune
strip.begin();
strip.fill(strip.Color(255, 128, 0), 0, 2);// pixel color set to yellow
strip.show();
// Task 3bis: Neopixels commencent à vaciller
strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
strip.show();
delay(random(0,200)); // random delay for flicker effect
// Task 4: LED Vert s'allume avec BT
if (digitalRead(BT)) {
digitalWrite(Vert, LOW);
} else {
digitalWrite(Vert, HIGH);
delay (300);
}
if (Serial.available()) {
brightness = Serial.parseInt();
if (brightness >=0 && brightness <=255) {
analogWrite(Vert, brightness);
}
}
// Task 5: LED Rouge s'allume avec BTN
if (digitalRead(BTN) == HIGH){
for (int i=0; i<4; i=i+1) {
digitalWrite (Rouge, HIGH);
delay (100);
digitalWrite (Rouge, LOW);
delay (100);
}
}
else{
digitalWrite(Rouge, LOW);
}
}
Je ne vois pas d'interaction dans ton code, juste une temporisation de presque une seconde lorsque tu appuies sur le bouton de la led rouge.
Peux-tu expliquer ce qui se passe, et qui n'est pas ce que tu attends ?
Au fait pourquoi ne pas mettre les deux boutons en INPUT_PULLUP ?
Quand j'appuie sur un des boutons les LEDs bleue et orange arrêtent de clignoter le temps que la rouge ou la verte fassent leur travail. Ou bien il ne se passe rien quand on appuie sur un des boutons une fois ou deux avant que ça ne réagisse.
J'ai essayé différente version pour les boutons en essayant de supprimer cela. C'est pour ça que les deux boutons ne sont pas en INPUT_PULLUP. Mais ça n'a pas réglé mon problème.
Quand je disais que je n'étais pas doué pour les langues étrangères...
Je ne sais pas ce que veut dire NF ou NO. Je dessine mon circuit avec Tinkercad. DOnc le bouton présenté par défaut. Qui ressemble à ce que je veux utiliser quand je passerai à la réalisation physique.
Dans ton code lorsque tu appuis sur ton bouton if (digitalRead(BTN) == HIGH)
Tu ne fais rien pour arrêter le clignotement des autres LED.
La majorité de ton programme(ou le programme que tu as récupéré) exécute des actions en "parallèle", c'est à dire que chaque "Task" s'exécute indépendamment.
Enfin en partie car certaines "Task" contiennent des délais(fonction delay), qui casse complétement la logique des Task.
Je pense que dans un premier temps, il faudrait que tu rétablisse la logique multi-tâche.
Sauf si tu veux que ta LED rouge clignote 4 fois, puis plus rien jusqu'au relâchement du bouton.
Et encore cela n'empêche de garder la même logique tout au long du programme.
Donc peut tu redéfinir exactement et précisément ce que tu veux faire.
Par exemple "le temps que la rouge ou la verte fassent leur travail" n'est pas assez précis, car cela correspond à une multitude d'action possible.
@jpbbricole vous avez du mal avec les BP NF ou NO, en général, ces BP n'ayant qu'un seul contact, qu'il soit NO ou NF, un PULL-UP ou un PULL-DOWN (à câbler en hard) ne fait pas de mal pour fixer les états et que l'entrée Arduino ne soit pas flottante dans un des 2 états du BP.
1/ Si vous avez 1 NO, qu'il est relié à 1 coté au + 5V, quand il est ouvert, l'entrée Arduino est flottante, il faut 1 PULLDOWN.
Idem pour 1 NC relié au 5V.
2/ 1 NO relié au 0V, il faut un PULLUP.
Idem pour 1 NC relié au 0V.
Comme il existe des PULLUP interne, autant utilisé le cas 2/ avec 1 NO ou NC
Par contre là
Il manque "(digitalRead(BT)==LOW)" ... ou HIGH selon ton BT et ce que tu en attend.
J'ai analysé ton programme, dans l'ensemble, il est assez bien fait. Mais, mis à part de mettre tes boutons en PULLUP, il y avait une petite erreur dans le test du bouton BT:
Tu as écrit if (digitalRead(BT == LOW)) {
tu dois écrire if (digitalRead(BT) == LOW) {
C'est le genre d'erreur qui empoisonne un programme
On a l'impression que tout doit en effet tourner 'en parallèle'. Or comme dit @terwal une partie du code est bloquante, donc ça ne fonctionne pas en même temps.
@hypsi : il faut que tu dises exactement ce que tu veux obtenir, sinon c'est pas le jeu des 7 différences, c'est le ni oui ni non...
Tu as raison, j'aurais dû commencer par là.
Je veux que toutes les tâches se fassent en paralllèle en effet. Je veux que les LEDs bleue et orange continuent à clignoter quand j'appuie sur un des boutons. De plus je veux aussi que la LED rouge clignote quatre fois rapidement lorsqu'on appuie sur son bouton puis s'éteigne jusqu'au prochain appui. Je souhaite également que la LED verte s'allume une seule fois puis fade out quand on appuie sur son bouton.
Quand je joue sur Tinkercad, j'ai l'impression que lorsque j'appuie sur les boutons, parfois je n'ai pas de réponse de la LED correspondante, ou bien parfois les LEDs bleue et orange arrêtent de clignoter pendant un moment (le temps de l'exécution de la commande du bouton sur lequel j'ai appuyé). Mais peut-être que c'est juste une limite visuelle de Tinkercad.
Je me suis expliqué, j'espère un peu mieux, dans une de mes réponses. Oui je veux tout faire en parallèle. Je comprends que dès qu'on met un delay, il y a blocage. Je ne sais pas encore comment faire pour contourner ce problème et que tout le reste continue à fonctionner.
Regarde le, et si tu as des questions, pose-les sur ce fil de discussion : je pourrai t'aider.
L'idée est de créer une fonction par tâche et d'utiliser millis() comme tu le fais déjà un peu dans ton code.
Les tâches 3 et 3bis n'en font qu'une seule qu'il faudra simplifier :
mettre le strip.begin() dans le setup
task 3 devient :
// Task 3: Neopixels s'allument en jaune
strip.fill(strip.Color(255, 128, 0), 0, 2);// pixel color set to yellow
strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
strip.show();
delay(random(0,200)); // random delay for flicker effect
A mettre ensuite dans une fonction pour exécution sans le delay.
Tu ne parles pas de remplacer "ce" delay par une fonction millis(), n'est-ce pas ?
J'ai lu ton tuto et cela semble assez claire (ton exemple est très bon) mais je ne suis pas certain de voir comment utiliser plus la fonction millis() dans mon cas. Est-ce que je peux l'utiliser avec un bouton ? Et si oui, comment ? Merci d'avance.
Pour les tâches 4 et 5 tu as en effet à la fois le bouton et un delay. Il faut réfléchir à la manière d'utiliser les deux. De toutes façons, je pense que tu peux aussi bien ôter ce delay dans la tâche 4, il ne sert à rien.
Pour la tâche 4 : dans ta fonction, il faut lire le bouton et détecter un changement de son état (passage LOW - HOGH ou l'inverse). Tu peux ajouter un delay(30) pour ne pas être gêné par les rebonds, c'est si court que tu peux utiliser delay ici. Ensuite tu changes l'état de la led, simplement en lui attribuant le même état que le bouton.
En fait, je voulais faire un effet de fade down et non de flash d'ou le delay. Je ne vois pas comment incorporer la fonction FADE dans une fonction conditionnelle IF ELSE.