在尝试通过套接字将数据从两个ESP8266发送到PC时,我偶然发现了ERNOMEM错误。 仅当我每秒发送数据超过5次时,它才会发生。 ESP之一是 另一个esp和PC连接。 PC有一个可以接收所有数据并将其保存到csv文件的客户端。 在运行期间,csv中只有30行,然后ERNOMEM发生,并带有一些随机E:M656(不知道那是什么意思)。是否有人知道如何解决此问题或如何以其他方式每10毫秒发送一次数据? 这是用于接入点esp另一个esp作为站和客户端(在pc上)的代码: 为了避免出现问题-关闭和打开套接字是为了并行比较两个esp的数据
import usocket as socket
from machine import I2C, Pin
import mpu6050
from utime import sleep_ms
ssid = 'DRFT'
passwd = 'fiberteam'
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=ssid, authmode=3, password=passwd, hidden=0)
AP_IP = ap.ifconfig()[0]
print("AP's IP:",AP_IP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((AP_IP, 8888))
s.listen(1)
i2c = I2C(scl=Pin(5), sda=Pin(4))
accelerometer = mpu6050.accel(i2c)
print(accelerometer.get_values())
while True:
if not ap.isconnected():
print("waiting for connection...")
sleep_ms(5000)
else:
while True:
clientsocket, addr = s.accept()
values = accelerometer.get_values()
data_string = str(values['AcX'])+','+str(values['AcY'])+','+str(values['AcZ'])+','
clientsocket.send(bytes(data_string, 'utf-8'))
print(data_string)
clientsocket.close()
sleep_ms(100)
另一个ESP:
import network
import usocket as socket
from machine import I2C, Pin
import mpu6050
from utime import sleep_ms
ssid = 'DRFT'
passwd = 'fiberteam'
station = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF) # do not fucin delete dis
ap_if.active(False) # its to turn off access point mode (cuz its a station duh)
station.active(True)
station.connect(ssid, passwd)
station.ifconfig(('192.168.4.69', '255.255.255.0', '192.168.4.1', '8.8.8.8'))
STA_IP = '192.168.4.69'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((STA_IP, 8888))
s.listen(1)
i2c = I2C(scl=Pin(5), sda=Pin(4))
accelerometer = mpu6050.accel(i2c)
print(accelerometer.get_values())
while True:
if not station.isconnected():
print("waiting for connection...")
sleep_ms(5000)
else:
while True:
clientsocket, addr = s.accept()
values = accelerometer.get_values()
data_string = str(values['AcX'])+','+str(values['AcY'])+','+str(values['AcZ'])+','
clientsocket.send(bytes(data_string, 'utf-8'))
print(data_string)
clientsocket.close()
sleep_ms(100)
客户:
import socket
import time
import os
time_now = time.strftime("%Y-%m-%d_%H-%M")
f = open(os.path.join(os.getcwd(), 'DRFT_ride_data'+time_now+'.csv'), 'w+')
f.close()
last_ip_dot = ['1', '69'] # last parts of IP's of boards
curr = 0
last = 0
file = os.path.join(os.getcwd(), 'DRFT_ride_data'+time_now+'.csv')
f = open(file, 'a+')
f.write('fAcX,fAcY,fAcZ,fGyX,fGyY,fGyZ,rAcX,rAcY,rAcZ,rGyX,rGyY,rGyZ,\n')
f.close()
while True:
for dot in last_ip_dot:
curr = int(dot)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect(('192.168.4.'+dot, 8888))
data = s.recv(128)
if len(data) <= 0:
s.close()
continue
if curr == last:
continue
with open(file, 'a+') as f:
f.write(data.decode('utf-8'))
if curr == 69:
f.write('\n')
f.close()
last = curr
s.close()
答案 0 :(得分:0)
使用socket.print_pcbs()并查看其报告。
尽管套接字已关闭,但很可能您用光了套接字。 一段时间后,套接字在关闭后处于TIME_WAIT状态。 通常,对于具有大量内存的大型计算平台而言,这不是问题。
但是在内存受限的设备中,连接数不受限制。
lwip的MEMP_NUM_NETCONN宏(默认值为8)负责可使用的并发套接字数。 您可以对其进行调整,以增加同时连接的数量,但是会丢失一部分RAM以供不时之需。
在接受新连接或打开新连接之前,您可以尝试通过以下方式清除陈旧的套接字:
https://gist.github.com/d-a-v/ed67f7a6f476a043d1c7f347c829087e
// https://github.com/esp8266/Arduino/issues/1923
// https://github.com/esp8266/Arduino/issues/4213
// compatible with lwip-v1 and -v2
// no need for #include
struct tcp_pcb;
extern struct tcp_pcb* tcp_tw_pcbs;
extern "C" void tcp_abort (struct tcp_pcb* pcb);
void tcpCleanup ()
{
while (tcp_tw_pcbs != NULL)
{
tcp_abort(tcp_tw_pcbs);
}
}
也可以从TCP切换到UDP。 这样,您将加快数据传输速度,但会失去传递保证。