Arduino UNO+SIM800L-向服务器发送数据
Arduino UNO + SIM800L - sending data to server
我使用的是带有调制解调器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.flush()
上的文档,似乎这也可能是串行输出在返回之前无限等待完成的原因。
由于Serial.println()
似乎使用Serial.write()
功能来完成它的任务,我认为如果在某个时刻没有设备从串行端口读取,则写缓冲区会变满,并导致Serial.println()
阻塞。看见https://www.arduino.cc/reference/en/language/functions/communication/serial/write/
注意和警告
从Arduino IDE 1.0开始,串行传输是异步的。如果有传输缓冲区中有足够的空空间,Serial.write()将在通过串行传输任何字符之前返回。如果传输缓冲区已满,则Serial.write()将被阻止,直到缓冲区中有足够的空间。为了避免阻塞对Serial.write()的调用,您可以首先检查传输缓冲区中的可用空间量使用available ForWrite()。
请参阅Serial.flush()
函数的解释https://www.arduino.cc/reference/en/language/functions/communication/serial/flush/注意事项:
Serial.flush()
说明
等待传出串行数据的传输完成。(之前对于Arduino 1.0,这反而删除了任何缓冲的传入串行数据。)
flush()继承自Stream实用程序类。
请参阅本文,https://www.baldengineer.com/when-do-you-use-the-arduinos-to-use-serial-flush.html上面写着">
Serial.flush()做什么?
来自Arduino的Serial.flush参考(在本页上找到):
等待传出串行数据的传输完成。
该语句的关键是"传出"。Serial.flush()没有正如许多人所想的那样清空"传入"缓冲区。它会暂停您的程序,同时刷新传输缓冲区。
在使用Serial.println()
进行任何输出之前,我会使用Serial.availableForWrite()
函数,如果可用的字节数表明写缓冲区已满,则跳过输出。
最好的方法可能是作为Setup()
函数的一部分,在执行Serial.begin()
之后检查写缓冲区大小,并将其存储在全局变量中,然后使用全局变量检查写缓冲区时是否被清空。
请参阅https://www.instructables.com/id/Arduino-Serial/也就是说:
步骤3:命令:可用于写入()
说明
获取可在中写入的字节数(字符)串行缓冲区,而不阻止写入操作。
语法
Serial.available ForWrite()
另请参阅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主页上的每个板。
返回
可读取的字节数。
建议的行动方案
首先,我不认为Setup()
函数中的Serial.flush()
是必要的,并且可以安全地删除它。虽然这使得控制台在Setup()
期间立即输出,但它确实引入了对远程情况的等待,在远程情况下,没有设备从串行线读取以清空输出缓冲区。
我还建议,对于执行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("Config SIM900...");
中一样使用serialPrintLineIfAvailable()
- 将相机数据从服务器实时流式传输到客户端
- 不将数据 socket.io c++(客户端)发送到 nodejs(服务器)socket.io
- Arduino UNO+SIM800L-向服务器发送数据
- 在 1 个服务器 n 客户端套接字 C++ MFC 应用程序中更新数据的客户端
- TCP 服务器的异步读取使用 boost::asio 打印客户端套接字发送的数据
- Java 客户端C++服务器数据发送/接收问题
- QTcpSocket 在 RemoteHostClosedError 后重新连接到服务器时无法传输数据
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 如何使用软化工具包从 OPC UA 服务器异步读取操作回调中的数据值响应中获取 NodeId 详细信息
- 如何在C++中使用带有SFML的http reqest从节点.js服务器获取数据?
- 在 MySQL 中运行 HTTP 服务器以从客户端接收数据
- 使用 Broadcast 发出的从节点服务器发送的数据不能被 C++ 套接字 IO 客户端读取
- 如何使用 asio 本地数据报构建回显服务器和客户端?
- 将数据包从C++服务器发送到NodeJs服务器时出现MessagePack解码错误
- 如何使用gRPC在客户端和服务器之间双向发送和接收流元数据
- 通过TCP将数据从C++客户端发送到JSON服务器
- 如何使客户端在将数据写入 C++ 管道之前检查服务器是否完成了从管道的读取操作
- C++中从客户端到服务器的数据传输问题
- Qt TCP服务器不从客户端读取数据
- 如何使用 C++ 中的 cpprestsdk 发布 json 数据并从本地服务器获取响应