程序功能
在Arduino提供的例程的基础上做了一些修改,现在的功能是根据串口输入的信息,更改对应引脚的泵开关状态以及时长,主要使用的是串口处理函数和延时函数。
程序内容
String inputString = ""; // a String to hold incoming data
bool start_flag = true;
int time_initial, time_air, time_odor, time_airincrease, time_odorincrease;
bool run_flag = false;
int counter;
int valve1 = 10;
int valve2 = 8;
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(115200);
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
pinMode(valve1, OUTPUT);
pinMode(valve2, OUTPUT);
inputString.reserve(200);
}
// the loop function runs over and over again forever
void loop() {
if (start_flag) {
Serial.println("arduino system is started");
start_flag = false;
digitalWrite(valve1, LOW);
digitalWrite(valve2, LOW);
}
if (run_flag) {
delay(time_initial * 1000); //初始延时
for (counter = 0; counter < 10; counter++) {
digitalWrite(valve1, LOW);
digitalWrite(valve2, HIGH);
delay((time_odor + counter * time_odorincrease) * 1000);//进入循环后的延时
digitalWrite(valve1, HIGH);
digitalWrite(valve2, LOW);
delay((time_air + time_airincrease * counter) * 1000);
Serial.println(counter);
}
run_flag = false;
Serial.println("the circle is finished"); //提示退出循环
}
delay(1);
}
void(* resetFunc) (void) = 0; //复位程序
void splitFcn() {
// 拆分传输下来的信息,填充到各个变量中
time_initial = inputString.substring(0, 3).toInt();
time_odor = inputString.substring(3, 6).toInt();
time_odorincrease = inputString.substring(6, 9).toInt();
time_air = inputString.substring(9, 12).toInt();
time_airincrease = inputString.substring(12, 15).toInt();
inputString = "";
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == '-') {
resetFunc(); // 如果串口传输了特定的符号,就将arduino软复位
}
if (inChar == '*') { // 如果收到了结束符
run_flag = true;
splitFcn();
}
else {
inputString += inChar;
}
}
}
出现的问题
问题1:原先在自己电脑上调试的时候给的时间比较短,一般time_initial都是“5”这个大小,传输到arduino上等于5s的延时,都能正常运行,实际操作的时候需要100s的延时,发现程序在 delay(time_initial * 1000); 这儿就卡死了,怎么都进不了循环。
想到原先给 time_initial 定义的是int,是不是超过了int的大小65535造成的问题,把time_initial这几个变量全部定义成long之后就不会卡住了。
问题2:在程序里添加了一个软复位程序(void(* resetFunc) (void) = 0;),希望当串口输入特定字符(“-”)的时候可以把arduino软复位,结果发现当程序在delay中的时候,这个软复位貌似不能立即起作用,循环还是会继续一小段。只有等跳出循环之后,再输入这个字符可以正常软复位。
问题3:我原本在串口接收函数里添加了一个判断:
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == '-') {
resetFunc(); // 如果matlab传输了特定的符号,就将arduino软复位
}
if (!run_flag) { // 如果当前没有在循环中
if (inChar == '*') { // 如果收到了结束符
run_flag = true;
splitFcn();
}
else {
inputString += inChar;
}
}
else{ // 如果在循环中,就清空串口缓存
while(Serial.read()){} //一直读串口缓存,清空时返回-1
}
}
}
希望当程序已经在循环中时,串口即便接收了数据,也直接清除。结果在测试时发现如果在循环时间内(run_flag=1时)连续传输几次数据,程序只会多响应一次,也就是循环结束后再进入循环一次(就好像串口缓存仍然保存了一次的数据),我也不清楚这个是什么问题,只好把这段多余的判断删除了。
结尾
第一次用arduino,发现编程的确比较简单,但是不了解具体的函数,用起来也没有想象中的那么方便。
随手写一下,如果有人遇到同样的问题也可以作为参考。当然如果有大神能解答我的三个问题那就更好了。