Files
2025-01-21 10:40:29 +00:00

181 lines
5.4 KiB
Python

import network
import socket
import struct
from machine import Timer, ADC, Pin, WDT
import array
import gc
import time
import random
# 配置信息
SSID = "Obscura"
PASSWORD = "Obscura2024"
UDP_HOST = "222.186.10.253"
UDP_PORT = 6002
SERIAL_NUMBER = "ES01-208742cf95-efe5fb"
WATCHDOG_TIMEOUT = 20000 # 增加看门狗超时时间到20秒
class HighSpeedCollector:
def __init__(self):
# 初始化看门狗
self.wdt = WDT(timeout=WATCHDOG_TIMEOUT)
self.sock = None
self.is_connected = False
self.sample_timer = Timer(0)
self.running = False
# ADC配置
self.adc = ADC(Pin(3))
self.adc.atten(ADC.ATTN_11DB)
self.adc.width(ADC.WIDTH_12BIT)
# 看门狗定时器
self.wdt_timer = Timer(1)
self.wdt_timer.init(period=WATCHDOG_TIMEOUT // 4, # 每5秒喂一次狗
mode=Timer.PERIODIC,
callback=self._feed_watchdog)
def _feed_watchdog(self, _):
"""定期喂狗"""
try:
self.wdt.feed()
except Exception as e:
print("喂狗失败:", str(e))
def connect_wifi(self):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect(SSID, PASSWORD)
connect_start = time.ticks_ms()
while not wlan.isconnected():
# 检查WiFi连接超时(30秒)
if time.ticks_diff(time.ticks_ms(), connect_start) > 30000:
raise Exception("WiFi连接超时")
gc.collect()
self.wdt.feed() # WiFi连接过程中喂狗
time.sleep(1)
def setup_udp(self):
"""初始化UDP连接"""
try:
gc.collect()
if self.sock:
try:
self.sock.close()
except:
pass
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.setblocking(False)
self.sock.sendto(SERIAL_NUMBER.encode(), (UDP_HOST, UDP_PORT))
print(f"首次连接,发送序列号: {SERIAL_NUMBER}")
self.is_connected = True
except Exception as e:
print("UDP初始化失败:", str(e))
self.is_connected = False
self.sock = None
def _sample_and_send(self, _):
"""直接采样并发送数据"""
if not self.is_connected:
return
try:
# 在采样开始时也喂狗
self.wdt.feed()
# 检查是否有序列号请求
try:
data, addr = self.sock.recvfrom(1024)
if data == b'REQUEST_SERIAL':
self.sock.sendto(SERIAL_NUMBER.encode(), addr)
return
except:
pass
# 使用相对时间戳
if not hasattr(self, 'start_time'):
self.start_time = time.ticks_ms()
relative_ms = time.ticks_diff(time.ticks_ms(), self.start_time)
timestamp = relative_ms % 65536
# 采集50个数据点
samples = array.array('H', [self.adc.read() for _ in range(50)])
packed_data = struct.pack(
'<HH50H',
timestamp,
0, # chunk_index
*samples
)
self.sock.sendto(packed_data, (UDP_HOST, UDP_PORT))
except Exception as e:
print('发送数据错误:', str(e))
self.is_connected = False
self.sock = None
def start(self):
"""启动采样和发送"""
self.running = True
try:
self.sample_timer.init(
freq=20, # 每秒20次采样和发送
mode=Timer.PERIODIC,
callback=self._sample_and_send
)
print("采样定时器启动成功 - 频率: 20Hz")
except Exception as e:
print(f"采样定时器启动失败: {e}")
self.running = False
def stop(self):
"""停止采样"""
self.running = False
self.sample_timer.deinit()
self.wdt_timer.deinit() # 停止喂狗定时器
if self.sock:
try:
self.sock.close()
except:
pass
def main():
gc.enable()
collector = None
retry_count = 0
max_retries = 3
while retry_count < max_retries:
try:
print(f"初始化采集器... (尝试 {retry_count + 1}/{max_retries})")
collector = HighSpeedCollector()
collector.connect_wifi()
collector.setup_udp()
collector.start()
print("进入主循环...")
while collector.running:
gc.collect()
time.sleep(0.1)
break # 如果正常运行,跳出重试循环
except Exception as e:
print("程序出错:", str(e))
retry_count += 1
if collector:
collector.stop()
time.sleep(5) # 等待5秒后重试
if collector:
collector.stop()
if __name__ == "__main__":
main()