在 Arduino Mega 2560 的 TX 引脚上禁用中断
Disabling interrupts on TX pin on Arduino Mega 2560
我要说的是,关于 Arduino 函数 serialEvent 的参考文献没有很好的记录。
https://www.arduino.cc/en/Reference/SerialEvent
由于缺乏信息,我误解了这个函数的工作原理。
因为我有 Arduino Mega 2560,它带有 4 个串行 inputs/outputs,并且它们有自己的 serialEventX 函数(其中 X = {'',1,2,3})。
我已经与 ESP8266 模块成功通信,一旦客户端连接到它,它就会发送和接收信息。
使用 serialEvent1(1 因为它连接到 RX1 和 TX1)我希望 serialEvent1 仅在数据传入时被调用,但实际上在我使用 Serial1.write(msg) 时也会被调用,所以这意味着正在发送消息时。
#define DEBUG_ESP8622 1
#include <esp8622.h>
#include <string.h>
#include "common.h"
#include <stdlib.h>
Wifi esp = Wifi(); //Here Serial1.begin(115200) happens
void setup() {
Serial.begin(9600); //First of all SERIAL for debugging
Serial.println("Starting");
while(!esp.sReachable()); //Works
Serial.println("ESP found");
while(!esp.sSetMode(1)); //Works
Serial.println("Mode set to Client");
while(!esp.sConnect(WIFISSID,WIFIPASSWORD)); //Works
Serial.println("Connected");
Serial.print("IP:");
Serial.println(esp.getIP());
while(!esp.sStartServer(80)); //Works
Serial.println("Server started");
}
void loop() {
if(Serial.available()>0){
int inByte=Serial.read();
/*HERE whenever I call Serial1.write(inByte)
serialEvent1 will be called at the end of the loop
but actually I don't want it to
*/
Serial1.write(inByte);
}
}
void serialEvent(){
return;
}
void serialEvent1(){
Serial.println("Write or Read event?");
while(Serial1.available()>0){
int inByte=Serial1.read();
//Serial.write(inByte);
}
//esp.onSerialEvent(); //Stores message and parses it, not relevant
return;
}
所以现在,知道 Arduino 库是基于 AVR libc 库的,我想微控制器内部的 RX1 和 TX1 中断都通过 Arduino 库绑定到 serialEvent1。
是否可以使用该库从 serialEvent1 中仅解除 TX1 的绑定并仍然使用 Arduino 库 (Serial1.write()/read())?
我使用最简单的方法使用 Makefile 将代码上传到 Mega。选择从命令行使用 arduino,因为到目前为止它适合我的需要,我知道 avrdude 和 avr-gcc 是从命令行 compile/upload 的更完整或更好的方法,如果我错了请纠正我。
CC=arduino
upload: terminal.ino
$(CC) terminal.ino --upload
verify: terminal.ino
$(CC) terminal.ino --verify
如果我开始使用 ,是否应该开始学习如何使用 avrdude 和 avr-gcc? (或者可能与使用 AVR 库无关)
最后,我使用上面的 Makefile 和 USB 数据线,如果我使用 avrdude 和 avr-gcc 是通过 ICSP 还是仍然可以通过 USB 数据线使用?这会删除引导加载程序吗?
非常感谢
是的,SerialEvent
函数很傻。它们与 loop
中的轮询没有什么不同。如果您做某事 time-consuming 而没有足够快地 return 到 loop
,您仍然会丢失数据。解决方案是附加到 RX 中断,但 built-in class、HardwareSerial
.
不支持
我已经发布了 HardwareSerial
的修改版本,允许您附加到 RX 中断。它被称为NeoHWSerial。
因为是替换,所以必须只使用NeoSerial[#]
变量。您不能在同一个草图中使用 Serial
和 NeoSerial1
。只需使用 NeoSerial
而不是 Serial
,即使您不调用 NeoSerial.attachInterrupt
:
void setup()
{
NeoSerial.begin( 9600 ); // replaces `Serial.begin(9600)`
NeoSerial.println( F("Started.") ); // ... and all your prints, too
NeoSerial1.attachInterrupt( myRxFunction );
NeoSerial1.begin( 9600 );
请记住 myRxFunction
在 中断期间被调用 。您必须快速处理每个字符,并且不要调用依赖于 而不是 的东西处于中断状态,例如 print
甚至 millis()
。糟糕的 juju!
并确保将匹配的 IDE 版本子目录(例如 1.6.5r2)中的文件复制到您的 libraries/NeoHWSerial
子目录中。 不要将它们放入libraries/1.0.5
或libraries/1.6.5r2
我要说的是,关于 Arduino 函数 serialEvent 的参考文献没有很好的记录。 https://www.arduino.cc/en/Reference/SerialEvent
由于缺乏信息,我误解了这个函数的工作原理。 因为我有 Arduino Mega 2560,它带有 4 个串行 inputs/outputs,并且它们有自己的 serialEventX 函数(其中 X = {'',1,2,3})。
我已经与 ESP8266 模块成功通信,一旦客户端连接到它,它就会发送和接收信息。
使用 serialEvent1(1 因为它连接到 RX1 和 TX1)我希望 serialEvent1 仅在数据传入时被调用,但实际上在我使用 Serial1.write(msg) 时也会被调用,所以这意味着正在发送消息时。
#define DEBUG_ESP8622 1
#include <esp8622.h>
#include <string.h>
#include "common.h"
#include <stdlib.h>
Wifi esp = Wifi(); //Here Serial1.begin(115200) happens
void setup() {
Serial.begin(9600); //First of all SERIAL for debugging
Serial.println("Starting");
while(!esp.sReachable()); //Works
Serial.println("ESP found");
while(!esp.sSetMode(1)); //Works
Serial.println("Mode set to Client");
while(!esp.sConnect(WIFISSID,WIFIPASSWORD)); //Works
Serial.println("Connected");
Serial.print("IP:");
Serial.println(esp.getIP());
while(!esp.sStartServer(80)); //Works
Serial.println("Server started");
}
void loop() {
if(Serial.available()>0){
int inByte=Serial.read();
/*HERE whenever I call Serial1.write(inByte)
serialEvent1 will be called at the end of the loop
but actually I don't want it to
*/
Serial1.write(inByte);
}
}
void serialEvent(){
return;
}
void serialEvent1(){
Serial.println("Write or Read event?");
while(Serial1.available()>0){
int inByte=Serial1.read();
//Serial.write(inByte);
}
//esp.onSerialEvent(); //Stores message and parses it, not relevant
return;
}
所以现在,知道 Arduino 库是基于 AVR libc 库的,我想微控制器内部的 RX1 和 TX1 中断都通过 Arduino 库绑定到 serialEvent1。
是否可以使用该库从 serialEvent1 中仅解除 TX1 的绑定并仍然使用 Arduino 库 (Serial1.write()/read())?
我使用最简单的方法使用 Makefile 将代码上传到 Mega。选择从命令行使用 arduino,因为到目前为止它适合我的需要,我知道 avrdude 和 avr-gcc 是从命令行 compile/upload 的更完整或更好的方法,如果我错了请纠正我。
CC=arduino
upload: terminal.ino
$(CC) terminal.ino --upload
verify: terminal.ino
$(CC) terminal.ino --verify
如果我开始使用 ,是否应该开始学习如何使用 avrdude 和 avr-gcc? (或者可能与使用 AVR 库无关)
最后,我使用上面的 Makefile 和 USB 数据线,如果我使用 avrdude 和 avr-gcc 是通过 ICSP 还是仍然可以通过 USB 数据线使用?这会删除引导加载程序吗?
非常感谢
是的,SerialEvent
函数很傻。它们与 loop
中的轮询没有什么不同。如果您做某事 time-consuming 而没有足够快地 return 到 loop
,您仍然会丢失数据。解决方案是附加到 RX 中断,但 built-in class、HardwareSerial
.
我已经发布了 HardwareSerial
的修改版本,允许您附加到 RX 中断。它被称为NeoHWSerial。
因为是替换,所以必须只使用NeoSerial[#]
变量。您不能在同一个草图中使用 Serial
和 NeoSerial1
。只需使用 NeoSerial
而不是 Serial
,即使您不调用 NeoSerial.attachInterrupt
:
void setup()
{
NeoSerial.begin( 9600 ); // replaces `Serial.begin(9600)`
NeoSerial.println( F("Started.") ); // ... and all your prints, too
NeoSerial1.attachInterrupt( myRxFunction );
NeoSerial1.begin( 9600 );
请记住 myRxFunction
在 中断期间被调用 。您必须快速处理每个字符,并且不要调用依赖于 而不是 的东西处于中断状态,例如 print
甚至 millis()
。糟糕的 juju!
并确保将匹配的 IDE 版本子目录(例如 1.6.5r2)中的文件复制到您的 libraries/NeoHWSerial
子目录中。 不要将它们放入libraries/1.0.5
或libraries/1.6.5r2