Esquisse qui répond à certaines commandes, comment fait-on?

D’accord, j’ai un croquis d’Arduino à moitié complet pour le moment. Fondamentalement, l’esquisse ci-dessous fera clignoter une LED sur un mini-bouclier de kegboard si une chaîne de caractères est égale à * {blink_Flow_A} * Cependant, la LED ne clignote qu’une fois avec l’esquisse actuelle chargée sur l’Arduino. J’aimerai que l’Arduino clignote à plusieurs resockets jusqu’à ce que la commande “stop” soit envoyée à l’Arduino. Je voudrais éventuellement ouvrir une vanne, laissez-la ouverte jusqu’à ce que la vanne reçoive la commande de fermeture puis fermez la vanne. Le croquis ressemble à ce qui suit,

/* * kegboard-serial-simple-blink07 * This code is public domain * * This sketch sends a receives a multibyte Ssortingng from the iPhone * and performs functions on it. * * Examples: * http://arduino.cc/en/Tutorial/SerialEvent * http://arduino.cc/en/Serial/read */ // global variables should be identified with _ // flow_A LED int led = 4; // relay_A const int RELAY_A = A0; // variables from sketch example Ssortingng inputSsortingng = ""; // a ssortingng to hold incoming data boolean ssortingngComplete = false; // whether the ssortingng is complete void setup() { Serial.begin(2400); // open serial port, sets data rate to 2400bps Serial.println("Power on test"); inputSsortingng.reserve(200); pinMode(RELAY_A, OUTPUT); } void open_valve() { digitalWrite(RELAY_A, HIGH); // turn RELAY_A on } void close_valve() { digitalWrite(RELAY_A, LOW); // turn RELAY_A off } void flow_A_blink() { digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for one second digitalWrite(led, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second } void flow_A_blink_stop() { digitalWrite(led, LOW); } void loop() { // print the ssortingng when newline arrives: if (ssortingngComplete) { Serial.println(inputSsortingng); // clear the ssortingng: inputSsortingng = ""; ssortingngComplete = false; } if (inputSsortingng == "{blink_Flow_A}") { flow_A_blink(); } } //SerialEvent occurs whenever a new data comes in the //hardware serial RX. This routine is run between each //time loop() runs, so using delay inside loop can delay //response. Multiple bytes of data may be available. void serialEvent() { while(Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputSsortingng: inputSsortingng += inChar; // if the incoming character is a newline, set a flag // so the main loop can do something about it: if (inChar == '\n') { ssortingngComplete = true; } } } 

Si cela fait une différence, un membre de l’IRC m’a dit de rechercher des machines à gratter dans la tête

Une machine à états (au sens le plus simple – cela peut être beaucoup plus compliqué) peut être simplement un ensemble d’instructions conditionnelles (if / else ou switch / case) dans lesquelles vous faites certains comportements en fonction de l’état d’une variable, et modifiez également cette variable Etat. Cela peut donc être considéré comme un moyen de gérer ou de progresser dans une série de conditions.

Donc, vous avez l’état de votre LED / valve – elle clignote (ouverte) ou ne clignote pas (fermée). En pseudo-code ici:

 boolean LED_state = false; //init to false/closed void loop(){ if (checkForCorrectCommand() == true){ // if (LED_State == false){ open_valve(); LED_State = true; } else { close_valve(); LED_State = false; } } } 

La partie LED clignotante devrait être facile à mettre en œuvre si vous comprenez l’essentiel du code ci-dessus. Le checkForCorrectCommand() est une fonction que vous écrivez pour vérifier quelle que soit votre entrée – clé, série, bouton, etc. Il devrait renvoyer un booléen.

Pour faire clignoter une Led sans bloquer le programme, je vous suggère d’utiliser Timer (et la bibliothèque TimerOne ). Je crée un exemple de code rapide:

 #include "TimerOne.h" //Include the librart, follow the previous link to download and install. int LED = 4; const int RELAY_A = A0; boolean ledOn; void setup() { pinMode(LED, OUTPUT) Timer1.initialise(500000) // Initialise timer1 with a 1/2 second (500000µs) period ledOn = false; } void blinkCallback() // Callback function call every 1/2 second when attached to the timer { if(ledOn){ digitalWrite(LED,LOW); ledOn = false; } else{ digitalWrite(LED,HIGH); ledOn = true; } } void open_valve() { digitalWrite(RELAY_A, HIGH); // turn RELAY_A on } void close_valve() { digitalWrite(RELAY_A, LOW); // turn RELAY_A off } void serialEvent() { while(Serial.available()) { char inChar = (char)Serial.read(); inputSsortingng += inChar; if (inChar == '\n') { ssortingngComplete = true; } } } void loop() { // print the ssortingng when newline arrives: if (ssortingngComplete) { Serial.println(inputSsortingng); // clear the ssortingng: inputSsortingng = ""; ssortingngComplete = false; } if (inputSsortingng == "{blink_Flow_A}") { Timer1.attachInterupt(blinkCallback); //Start blinking } if (inputSsortingng == "{stop}") { Timer1.detachInterrupt(); //Stop blinking } if (inputSsortingng == "{open_valve}") { open_valve(); } if (inputSsortingng == "{close_valve}") { close_valve(); } } 

Remarque :
Pensez à mettre la balise ‘c’ ou ‘java’ pour que la syntaxe soit surlignée dans le code.

Peut-être que quelque chose comme l’exemple de « clignotement sans délai » dans l’ IDE . Vous vérifiez l’heure et décidez quand et comment changer la LED / sortie numérique.

 // Variables will change: int ledState = LOW; // ledState used to set the LED long previousMillis = 0; // will store last time LED was updated // the follow variables is a long because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long interval = 1000; // interval at which to blink (milliseconds) void setup(){ // Your stuff here } void loop() { // Your stuff here. // check to see if it's time to blink the LED; that is, if the // difference between the current time and last time you blinked // the LED is bigger than the interval at which you want to // blink the LED. unsigned long currentMillis = millis(); if(currentMillis - previousMillis > interval) { // save the last time you blinked the LED previousMillis = currentMillis; // if the LED is off turn it on and vice-versa: if (ledState == LOW) ledState = HIGH; else ledState = LOW; // set the LED with the ledState of the variable: digitalWrite(ledPin, ledState); } } 

Permettez-moi de vous proposer une esquisse avec quelques modifications. L’idée de Bastyen d’utiliser une timer est très bonne et rend le code beaucoup plus facile. L’approche que je suggérerais est de faire en sorte que la timer saute à jamais à un intervalle fixe (100 millisecondes dans mon croquis). Si le voyant ne clignote pas, il rest éteint. Si le voyant clignote, il s’éteint ou s’allume à chaque fois que la timer s’éteint.

 #include "TimerOne.h" /* * kegboard-serial-simple-blink07 * This code is public domain * * This sketch sends a receives a multibyte Ssortingng from the iPhone * and performs functions on it. * * Examples: * http://arduino.cc/en/Tutorial/SerialEvent * http://arduino.cc/en/Serial/read */ // global variables should be identified with _ // flow_A LED int led = 4; // relay_A const int RELAY_A = A0; // variables from sketch example Ssortingng inputSsortingng = ""; // a ssortingng to hold incoming data boolean ssortingngComplete = false; // whether the ssortingng is complete boolean shouldBeBlinking = false; boolean ledOn = false; void setup() { Serial.begin(9600); // open serial port, sets data rate to 2400bps Serial.println("Power on test"); inputSsortingng.reserve(200); pinMode(RELAY_A, OUTPUT); pinMode(led, OUTPUT); digitalWrite(led, LOW); Timer1.initialize(100000); Timer1.attachInterrupt(timer1Callback); } void loop() { if (!ssortingngComplete) return; if (inputSsortingng == "{blink_Flow_A}") flow_A_blink_start(); if (inputSsortingng == "{blink_Flow_B}") flow_A_blink_stop(); inputSsortingng = ""; ssortingngComplete = false; } void timer1Callback() { /* If we are not in blinking mode, just make sure the LED is off */ if (!shouldBeBlinking) { digitalWrite(led, LOW); ledOn = false; return; } /* Since we are in blinking mode, check the state of the LED. Turn it off if it is on and vice versa. */ ledOn = (ledOn) ? false : true; digitalWrite(led, ledOn); } void flow_A_blink_start() { shouldBeBlinking = true; open_valve(); } void flow_A_blink_stop() { shouldBeBlinking = false; close_valve(); } void close_valve() { digitalWrite(RELAY_A, LOW); // turn RELAY_A off } void open_valve() { digitalWrite(RELAY_A, HIGH); // turn RELAY_A on } //SerialEvent occurs whenever a new data comes in the //hardware serial RX. This routine is run between each //time loop() runs, so using delay inside loop can delay //response. Multiple bytes of data may be available. void serialEvent() { if (ssortingngComplete) return; while(Serial.available()) { // get the new byte: char inChar = (char)Serial.read(); // add it to the inputSsortingng unless it is a newline if (inChar != '\n') inputSsortingng += inChar; // if the incoming character is a newline, set a flag // so the main loop can do something about it: else { ssortingngComplete = true; } } } 

Quelques notes:

  1. La fonction de configuration établit la timer avec un intervalle de 100 millisecondes et associe la routine de rappel. Sur la base de mes tests, cela ne doit être fait qu’une fois.

  2. La boucle principale ignore tout sauf si une chaîne d’entrée est complète. Si une chaîne d’entrée est prête, deux valeurs connues sont vérifiées et les mesures appropriées sont sockets. La chaîne d’entrée est ensuite supprimée.

  3. La routine de rappel de la timer force le voyant à s’éteindre si nous ne sums pas en mode clignotant. Sinon, il ne fait que basculer l’état de la LED.

  4. Les routines d’écoulement et d’écoulement définissent l’état clignotant au besoin et contrôlent la vanne

  5. La routine d’événements en série comporte deux modifications. D’abord, l’entrée est ignorée (et conservée dans la mémoire tampon) si une chaîne d’entrée est déjà complète. Cela préservera les commandes envoyées à l’Arduino pendant le traitement de la commande en cours. Deuxièmement, le caractère de nouvelle ligne n’est pas ajouté à la chaîne d’entrée. Cela facilite légèrement la vérification de la chaîne d’entrée.