我正在使用带有调制解调器sim800l的arduino UNO板。我想用它每10秒将数据发送到服务器mysql。当我在arduino IDE中打开了串行监视器(数据已保存到mysql数据库中)时,一切工作正常,但是当串行监视器关闭时,则不起作用。
我想使用我的系统远程连接到移动电源。但是它仅在我打开arduino IDE串行监视器时才有效。
如何编辑代码,使微控制器在不连接计算机和开放式串行监视器的情况下工作?
#include <SoftwareSerial.h>
SoftwareSerial gprsSerial(7, 8);
void setup()
{
gprsSerial.begin(19200);
Serial.begin(19200);
Serial.println("Config SIM900...");
delay(2000);
Serial.println("Done!...");
gprsSerial.flush();
Serial.flush();
// attach or detach from GPRS service
gprsSerial.println("AT+CGATT?");
delay(100);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=3,1,\"APN\",\"internet\"");
delay(2000);
toSerial();
// bearer settings
gprsSerial.println("AT+SAPBR=1,1");
delay(2000);
toSerial();
}
void loop()
{
// initialize http service
gprsSerial.println("AT+HTTPINIT");
delay(2000);
toSerial();
// set http param value
gprsSerial.println("AT+HTTPPARA=\"URL\",\"http://server.net/test.php?data1=2&data2=3\"");
delay(2000);
toSerial();
// set http action type 0 = GET, 1 = POST, 2 = HEAD
gprsSerial.println("AT+HTTPACTION=0");
delay(6000);
toSerial();
// read server response
gprsSerial.println("AT+HTTPREAD");
delay(1000);
toSerial();
gprsSerial.println("");
gprsSerial.println("AT+HTTPTERM");
toSerial();
delay(300);
gprsSerial.println("");
delay(10000);
}
void toSerial()
{
while(gprsSerial.available()!=0)
{
Serial.write(gprsSerial.read());
}
}
我不确定Serial
的基本实现,但是可能会无限期地等待Serial.println()
的发生。
因为Serial.println()
似乎使用Serial.write()
功能来完成其工作,所以我想如果某个时刻没有设备从串行端口读取数据,则写缓冲区将变满并导致Serial.println()
阻塞。
我将在使用Serial.availableForWrite()
进行任何输出之前使用Serial.println()
函数,并且如果可用字节数指示写缓冲区已满,则跳过输出。
[也许最好的方法是作为Setup()
函数的一部分,在执行Serial.begin()
之后检查写缓冲区的大小,并将其存储在全局变量中,然后使用该全局变量检查写缓冲区是否被清空是否。
请参见https://www.instructables.com/id/Arduino-Serial/,其中有这句话:
步骤3:命令:
说明
获取可用于写入的字节数(字符)串行缓冲区,而不会阻止写操作。
语法
Serial.availableForWrite()
另请参阅https://www.arduino.cc/reference/en/language/functions/communication/serial/availableforwrite/
还有if (Serial)
可用于检查端口是否可用。 https://www.arduino.cc/reference/en/language/functions/communication/serial/ifserial/但是我怀疑这更多是检查所请求的端口是否可用,而不是该端口是否实际上与链接另一端的设备一起工作。
还有Serial.available()
https://www.arduino.cc/reference/en/language/functions/communication/serial/available/
Serial.available()
说明
获取可从中读取的字节数(字符)串行端口。这是已经到达并存储在串行接收缓冲区(保存64个字节)。
Serial.available()从Stream实用程序类继承。
语法
Serial.available()
参数
Serial:串行端口对象。请参阅可用串行端口列表,以了解串行主页上的每个板。
返回
可读取的字节数。
我的建议是,对于每行
Serial.println()
,首先检查Serial.availableForWrite()
可用的缓冲区字节数,如下所示:
int firstAvailableForWrite = 0; void Setup () { // set up everything you do then add the following statement firstAvailableForWrite = Serial.availableForWrite(); }
然后您将在哪里进行写操作,并使用类似于下面示例的
if
语句进行修改:
if (Serial.availableForWrite() >= firstAvailableForWrite) Serial.println("Config SIM900...");
或者您也可以创建类似以下的函数:
int serialPrintLineIfAvailable (char *aszLine) { int iCount = 0; if (Serial.availableForWrite() >= firstAvailableForWrite) iCount = Serial.println(aszLine); return iCount; }
然后,无论您想在何处使用
Serial.println()
,都应像在serialPrintLineIfAvailable()
中一样使用serialPrintLineIfAvailable("Config SIM900...");