我有一个服务器/接入点ESP8266向接收客户端/站ESP8266传输实验性的 14 字节数据。 我的编程IDE和串行监视器是Arduino。传输的数据以串行监视器中可见的每秒 100 个数据生成,并由 10ms 延迟控制。 但是,接收到的数据会转换为字符串,并且每秒报告的频率低于 2 次。 所以我错过了超过98%的传输数据。 我该怎么做才能加快数据接收速度? 我怀疑缓冲区有限制。 在我的研究中,我读到有一种确认响应很耗时,可以覆盖。 但其中大部分都是通过库抽象出来的,我还没有能够发现它。
最终,我想用加速度计输出替换实验数据。 SD卡将被添加到接收器以捕获/记录数据。 加速度计处于高冲击环境中,可能会损坏SD卡;因此需要将接收器与发射器分开。 我已经测试了加速度计,知道它可以每秒提供 10 个字符串,最多包含 9 个字符的字节,外加一个 \r。 因此,发射器似乎可以处理这个问题,但接收器不能。
我的问题是,接收器的缓冲区管理限制是什么,是否有应答元素,如果有,我可以击败它吗? 我还能做些什么来获得更高的数据接收速度?
以下是发射器/服务器的显著代码:
void loop()
{
WiFiClient client = server.available();
int data_outgoing[5] = {10, 128, 128, 123, 123};
int mapFun[5];
Serial.print("Sent data: ");
Serial.print(millis());
Serial.println();
for(int i = 0; i < 5; i++)
{
mapFun[i] =data_outgoing[i];
client.print(mapFun[i]);
Serial.print(mapFun[i]);
}
client.print('n');
delay(10);
以下是接收方/客户端的显著代码:
void loop()
{
if(client.connect(host, 80));
{
if(client.available());
{
String c = client.readStringUntil('n'); //client.read();
Serial.print(c); Serial.print(" "); Serial.println(millis());
}
}
client.stop();
}
这项工作的基础是基于这个博客。对于其他读者来说,该讨论中有很多很好的提示/技巧。
我发现了一些可以帮助他人并节省大量时间的事情。 如果以下内容不正确,请介入。 以下是我通过阅读多个来源收集的内容,其中一些可能是正确的。 不知道其余的。
TCP 传输涉及一个确认过程,该过程会为每个传输的数据包带来一些开销负担。 为了优化速度和准确性,传输的数据通常被放入适当大小的数据包中,以获得一定的规模经济的确认返回开销。 在ESP8266每个Client.print传输都会将数据包装成一个数据包,无论多小,然后传输。 小数据包对于传输 ESP 和接收 ESP 来说都是昂贵的。 解决我问题的方法是将许多数据元素聚类到一个 Client.print 语句中,加上用于解析接收 ESP 中的行并分隔接收的集群的"\"字符。 然后,多个数据元素可以通过收到的 ESP 进行管理,也可以进行后处理,我一直在电子表格中执行此操作以评估性能。
TCP中的数据包大小有1460字节的限制(可能是Arduino/ESP特定的)。 我发现通过"聚类"12 个三个字符值,加上 12 个控制字符(制表符和逗号的组合),我最终每次传输 48 个字节。 虽然远低于 1460 的限制,但这比我的第一个序列要好得多:传输 3 个字符,等待 ack,传输"n",等待 ack,重复等等。 即使只是将"n"与 3 个字符组合在一起也会是 100% 的改进,但我做到了乘以 12。 所有这些的结果是接收速度大大提高 - 以至于我需要放慢发射器的速度。 当我连接加速度计时,我不想比它生成 x,y,z 坐标的能力更快,我认为大约每秒 10 组。 这也导致了更高的传输成功率 - 除了偶尔的间隙外,几乎是完美的。
说到这一点,每几千个数据元素(有时多达 10K)之后,接收器每次都会停滞 7 秒。 我正在研究那个,但我怀疑设备正在达到温度限制(两个 ESP 触摸起来都非常温暖)。 也许我应该传输更大的数据包,减少频率... 但是每次 7 秒的延迟让我觉得这可能是 Arduino IDE 向我隐藏的其他一些抽象细节。
我读到的解决方案的另一个潜在来源是使用client.stream或server.stream。 我涉足了一点,但很快就放弃了。 我读过2.5 Mbps的数据传输是可能的。这个实验对我有用,最高可达(48B * 8b/B)/0.015mS或25.6 Kbps,因此可能具有更高的速度。 以为我会分享。
接收器代码不会从上面更改。 发送器(服务器)代码循环为:
void loop() //Works - crl 3/7/18
{
WiFiClient client = server.available();
Serial.print("Sent data: ");
Serial.print(millis());
Serial.println();
client.print(String(data_outgoing)+","
+ String(data_outgoing+1)+","
+ String(data_outgoing+2)+'t'
+ String(data_outgoing+3)+","
+ String(data_outgoing+4)+","
+ String(data_outgoing+5)+'t'
+ String(data_outgoing+6)+","
+ String(data_outgoing+7)+","
+ String(data_outgoing+8)+'t'
+ String(data_outgoing+9)+","
+ String(data_outgoing+10)+","
+ String(data_outgoing+11)
+ 'n');
Serial.print(data_outgoing);
data_outgoing += 1;
delay(340); //
}