Arduino:ISR中的serial.read

时间:2013-04-29 16:18:40

标签: arduino

我正在编写一个小型测试程序,尝试在ISR中执行serial.write()后跟serial.read()。该代码最终将用于提示外部GSM屏蔽定期发送短信。

ISR(TIMER2_OVF_vect) {

    Serial.println("AT+CMGS=\"0123456789\"");     // Tell Sim900 To prepare sms to number 01...
    while(Serial.read()!='>');                    // Wait for Sim900 to respond
    Serial.print("A text message");               // the SMS body
    Serial.write(0x1A);                           //Confirm send instruction
    Serial.write(0x0D);
    Serial.write(0x0A); 
  }
}

经过大量测试后我发现,ISR中的Serial.read()无法读取实时串行提示,而只会读取在ISR被触发之前缓冲的任何输入。

有什么方法吗?

我找到的唯一解决方案是将此代码放在主loop()中。但我想使用定时器中断发送短信。

谢谢

3 个答案:

答案 0 :(得分:1)

您需要将代码放在loop()中,但使用IF:

float toBeSent = interval;

loop() {
    if (millis() > toBeSent) {
        Send();
        toBeSent = milli() + interval;
    }
}

间隔是您的发送间隔(以毫秒为单位)。

答案 1 :(得分:0)

前一段时间我遇到了类似的问题,我通过使用Arduino SoftwareSerial库而不是基于硬件的Serial.read来解决这个问题。

使用SoftwareSerial有一些开销,你一次只能读一个端口,所以我把它留给那些更了解Arduino平台的人,告诉你这是不是一个好主意,但是这个库的好处是你可以在ISR中使用它。

要使用SoftwareSerial库,请在草图顶部添加以下两行代码,记住要将rx_pin和tx_pin与要使用的相应引脚值重新对齐:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(rx_pin, tx_pin);

然后用Serial(或您为SoftwareSerial实例选择的任何名称)替换整个草图中的关键字mySerial

使用SoftwareSerial时要记住的一件重要事情是,您只能使用Arduino上的某些引脚,因此请先阅读documentation

答案 2 :(得分:0)

如果您想要危险地生活,您可以在ISR中启用中断并使用标志来防止重新进入。

int flag=0;

ISR(TIMER2_OVF_vect) {
flag = 1
if (flag){return;}
sei();
Serial.println("AT+CMGS=\"0123456789\"");     // Tell Sim900 To prepare sms to number 01...
while(Serial.read()!='>');                    // Wait for Sim900 to respond
  Serial.print("A text message");               // the SMS body
  Serial.write(0x1A);                           //Confirm send instruction
  Serial.write(0x0D);
  Serial.write(0x0A); 
  }
  flag = 0;
}