好吧,我现在有一个半完整的Arduino草图。基本上,如果一串字符等于* {blink_Flow_A},下面的草图将使kegboard-mini屏蔽上的LED闪烁*但是,只有当Arduino上加载的当前草图时,LED才会闪烁一次。我希望Arduino反复闪烁,直到“停止”命令被发送到Arduino。我最终想要打开一个阀门,保持打开,直到阀门接到关闭命令,然后关闭阀门。草图如下所示,
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String 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
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string is complete
void setup() {
Serial.begin(2400); // open serial port, sets data rate to 2400bps
Serial.println("Power on test");
inputString.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 string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{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 inputString:
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
stringComplete = true;
}
}
}
如果有任何不同,IRC上的某人告诉我研究状态机刮擦头
答案 0 :(得分:1)
要在不阻止程序的情况下使Led闪烁,我建议您使用Timer(以及TimerOne library)。我快速编写示例代码:
#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();
inputString += inChar;
if (inChar == '\n') {
stringComplete = true;
}
}
}
void loop()
{
// print the string when newline arrives:
if (stringComplete) {
Serial.println(inputString);
// clear the string:
inputString = "";
stringComplete = false;
}
if (inputString == "{blink_Flow_A}") {
Timer1.attachInterupt(blinkCallback); //Start blinking
}
if (inputString == "{stop}") {
Timer1.detachInterrupt(); //Stop blinking
}
if (inputString == "{open_valve}") {
open_valve();
}
if (inputString == "{close_valve}") {
close_valve();
}
}
注意:
考虑将标记“c”或“java”放在代码上进行语法高亮显示。
答案 1 :(得分:0)
也许类似于 IDE 中的“闪烁无延迟”示例。您检查时间并决定何时以及如何更改LED /数字输出。
// 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);
}
}
答案 2 :(得分:0)
状态机(最简单 - 它可能要复杂得多)可以只是一组条件语句(if / else或switch / case),你可以根据变量的状态执行某些行为,还可以改变那个变量状态。因此,它可以被认为是处理或进展一系列条件的一种方式。
所以你有LED /阀的状态 - 它是闪烁(打开)还是不闪烁(关闭)。在伪代码中:
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;
}
}
}
如果您掌握上述代码的要点,闪烁的LED部件应该易于实现。 checkForCorrectCommand()
位是您编写的用于检查输入内容的函数 - 键,串行,按钮等。它应该返回一个布尔值。
答案 3 :(得分:0)
让我提供一个建议的草图,但有一些变化。 Bastyen使用计时器的想法非常好,使代码更容易。我建议的方法是让计时器以固定的间隔永久弹出(在我的草图中为100毫秒)。如果LED不闪烁则保持关闭状态。如果LED应该闪烁,每次定时器熄灭时,它会从关闭切换为开启,反之亦然。
#include "TimerOne.h"
/*
* kegboard-serial-simple-blink07
* This code is public domain
*
* This sketch sends a receives a multibyte String 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
String inputString = ""; // a string to hold incoming data
boolean stringComplete = false; // whether the string 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");
inputString.reserve(200);
pinMode(RELAY_A, OUTPUT);
pinMode(led, OUTPUT);
digitalWrite(led, LOW);
Timer1.initialize(100000);
Timer1.attachInterrupt(timer1Callback);
}
void loop() {
if (!stringComplete)
return;
if (inputString == "{blink_Flow_A}")
flow_A_blink_start();
if (inputString == "{blink_Flow_B}")
flow_A_blink_stop();
inputString = "";
stringComplete = 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 (stringComplete)
return;
while(Serial.available()) {
// get the new byte:
char inChar = (char)Serial.read();
// add it to the inputString unless it is a newline
if (inChar != '\n')
inputString += inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
else {
stringComplete = true;
}
}
}
一些注意事项:
setup函数以100毫秒的间隔建立定时器并附加回调例程。根据我的测试,这只需要完成一次。
除非输入字符串完整,否则主循环会忽略所有内容。如果输入字符串已就绪,则检查输入字符串是否有两个已知值,并采取适当的步骤。然后丢弃输入字符串。
如果我们没有处于闪烁模式,定时器回调例程会强制关闭LED。否则,它只是切换LED的状态。
流量开启和关闭程序根据需要设置闪烁状态并控制阀门
串行事件例程有两处更改。首先,如果输入字符串已经完成,则忽略输入(并保留在缓冲区中)。这将保留在处理当前命令时发送到Arduino的命令。其次,换行符未添加到输入字符串中。这使得检查输入字符串更容易。