我开始告诉Arduino没有很好地记录关于函数serialEvent的参考文献。 https://www.arduino.cc/en/Reference/SerialEvent
由于缺乏信息,我误解了这个功能是如何运作的。 由于我有Arduino Mega 2560,它带有4个串行输入/输出,并且它们有自己的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中断都绑定到serialEvent1到Arduino库。
是否可以使用该库从serialEvent1解除绑定TX1并仍然使用Arduino库(Serial1.write()/ read())?
我使用最简单的方法使用Makefile将代码上传到Mega。选择从命令行使用arduino因为它符合我的需求到目前为止,我知道avrdude和avr-gcc是一个更完整或更好的方法从命令行编译/上传,纠正我,如果我错了。
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线使用?这会引导引导程序吗?
非常感谢
答案 0 :(得分:0)
是的,SerialEvent
功能很愚蠢。它们与loop
中的民意没有什么不同。如果您执行某些操作非常耗时并且没有足够快地返回loop
,您仍然可能会丢失数据。解决方案是附加到RX中断,但内置类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