4G FS800DTU上传图像至巴法云
目录
1 前言
2 准备工作
2.1 硬件准备
2.2 软件环境
2.3 硬件连接
3 实现方案
4 巴法云平台账号创建与设备联网配置
4.1 创建账号
4.2 进入巴法云
4.3 获取联网参数
4.4 连接巴法云
5 拍照上传至巴法云
6 ESP32-CAM程序
7 总结
1 前言
巴法云(Bemfa Cloud)是一个专注于 轻量级物联网(IOT)开发的云平台,主要面向智能家居、远程控制、数据监测等场景,提供 MQTT协议 支持,帮助开发者快速实现设备与云端的数据交互。
FS800DTU核心板是基于飞思创4G Cat.1模组设计的,上面集成了DC-DC、SIM卡、天线和串口电平转换电路,支持5-16V供电输入,我们不需要额外的设计,核心板串口可与单片机直连,再接上天线、SIM卡和供电就可以进行数据交互了。
FS800DTU支持4路Socket,支持TCP/UDP/HTTP/MQTT等通信协议,适配了阿里云、OneNET等物联网平台。不需要一条一条发AT指令配置,出厂自带YunDTU固件,通过飞思创提供的配置工具直接填写联网参数即可,连上服务器后数据直接透传,小白也能快速上手。
产品链接:点击跳转
2 准备工作
2.1 硬件准备
- FS800DTU核心板(型号:FS-MCore-F8A2M1)。
- 4G物联卡一张,移动,联通,电信均可。
- USB转TTL模块,若干根杜邦线。
- 4G天线一根。
- ESP32-CAM(MicroPython 含摄像头驱动固件)。
2.2 软件环境
- 巴法云平台。
- SerialPort_To_Network_ConfigTools 配置工具(用于配置 FS800DTU)。
- Thonny(ESP32-CAM 开发环境)。
2.3 硬件连接
电源注意事项:在为 ESP32 - CAM 和 FS800DTU 供电时,建议尽量使用 5V/2A 的电源。若供电不足,可能会导致 ESP32 - CAM 拍照失败,以及 FS800DTU 无法正常注册网络,频繁重启。
3 实现方案
ESP32-CAM 开启 AP 模式并启动 web 服务器,手机连接其生成的 WiFi,在浏览器访问拍照控制界面。按下拍照按钮后,ESP32 - CAM 进行拍照,若拍照数据成功通过串口发送给 FS800DTU,则提示拍照成功,FS800DTU 将收到的照片传输至巴法云;若发送失败,则提示拍照失败。
4 巴法云平台账号创建与设备联网配置
4.1 创建账号
打开巴法云主页:巴法科技&巴法云-巴法设备云-巴法物联网云平台,登录巴法云平台,有账号的话直接点击登录,没有账号就注册后登录。
4.2 进入巴法云
(1)点击图存储
(2)新建主题,获取私钥
私钥:b9d8f1671xxxxxxxxe0d3b33e60,该私钥将用于图片上传接口API的 HTTP 头部字段中。
4.3 获取联网参数
(1)打开巴法云文档中心简介 | 巴法文档中心,选择图片接口->图片上传接口一
API: https://images.bemfa.com/upload/v1/upimages.php
HTTP头部字段:
Authorization: b9d8f1671xxxxxxxxe0d3b33e60(使用时改为自己的巴法云的私钥)
Authtopic: test1(使用时改为自己的定义的主题)
Content-Type: image/jpg
4.4 连接巴法云
使用USB转TTL连接FS800DTU,打开 SerialPort_To_Network_ConfigTools 配置工具,选择 HTTP 协议,并将请求类型设置为 POST。接着,将获取的 API 地址填写到 URL 字段中。 Header 部分,按照 4.3 章节提供的 HTTP 头部字段进行填写,字段之间使用回车换行符([0D][0A])进行分隔,具体格式:Authorization: b9d8f1671xxxxxxxxe0d3b33e60[0D][0A]Authtopic: test1[0D][0A]Content-Type: image/jpg[0D][0A]。
将配置好参数的FS800DTU与ESP32-CAM进行连接。
5 拍照上传至巴法云
(1)打开Thonny运行程序,获取ESP32-CAM的IP地址。
(2)使用手机连接连接ESP32-CAM的WiFi。
(3)浏览器输入ESP32-CAM的IP地址192.168.4.1进入拍照界面。
注意事项:如果连上WiFi之后发现无法访问该网页,可以尝试关闭手机移动数据,并且关闭手机WiFi设置里的“网络优化”或者“自动切换移动数据”功能。
(4) 点击网页上的拍照按钮,ESP32-CAM会进行拍照,拍照成功后提示拍照完成,失败则提示失败。
(5)提示拍照完成后,刷新巴法云界面,查看上传到图片。
6 ESP32-CAM程序
主程序:负责初始化网络和启动 Web 服务器。
def main():try:# 初始化网络network_manager = NetworkManager()network_manager.start_ap(CONFIG['AP_SSID'])# 启动Web服务器server = WebServer(CONFIG['PORT'])server.start()except Exception as e:print('Fatal error:', e)finally:print('System shutdown')
WebServer 类:实现了一个简单的 Web 服务器,用于接收和处理 HTTP 请求,执行捕获图像并通过串口发送,并通过网络通信与客户端进行数据交互。
class WebServer:def __init__(self, port):"""初始化 WebServer 类"""self.port = portself.socket = socket.socket() # 创建一个 socket 对象,用于网络通信self.uart = UART(2, baudrate=CONFIG['UART_BAUDRATE'],tx=CONFIG['UART_TX_PIN'], rx=CONFIG['UART_RX_PIN']) # 初始化 UART 对象,用于串口通信def load_html(self, filename):"""加载 HTML 文件"""try:with open(filename, 'r') as file:return file.read() # 读取 HTML 文件内容并返回except Exception as e:print(f'Error reading HTML file {filename}: {e}')return '<!DOCTYPE html><html><body>Error loading page</body></html>' # 返回错误提示 HTMLdef create_response(self, content_type, body, status_code=200):"""创建 HTTP 响应"""status_text = 'OK' if status_code == 200 else 'Not Found' # 根据状态码确定状态文本response = 'HTTP/1.1 ' + str(status_code) + ' ' + status_text + '\r\n'response += 'Content-Type: ' + content_type + '\r\n'response += 'Connection: close\r\n'response += '\r\n'response += bodyreturn responsedef handle_request(self, request):"""处理 HTTP 请求"""# GET 请求处理if request.startswith('GET'):return self.create_response('text/html', self.load_html(CONFIG['HTML_FILE'])) # 加载并返回 HTML 文件内容# POST 请求处理elif request.startswith('POST'):headers_end = request.find('\r\n\r\n') + 4 # 找到请求头的结束位置if headers_end >= len(request):return self.create_response('text/plain', 'Error: No request body found', 400) # 请求体不存在,返回错误响应body = request[headers_end:].strip() # 提取请求体内容print('Received body:', body)if body == 'capture':try:image_data = CameraController.capture_image() # 调用摄像头控制器捕获图像self.uart.write(image_data) # 将图像数据通过串口发送print('Photo captured and sent via UART')return self.create_response('application/javascript', 'alert("拍照完成");') # 返回拍照完成的提示except Exception as e:print('Capture failed:', e)return self.create_response('application/javascript', 'alert("拍照失败");', 500) # 返回拍照失败的提示else:return self.create_response('application/javascript', 'alert("无效指令");') # 返回无效指令的提示# 其他请求else:return self.create_response('text/plain', 'Not Found', 404) # 返回 404 错误响应def start(self):"""启动 Web 服务器"""addr = socket.getaddrinfo('0.0.0.0', self.port)[0][-1] # 获取服务器地址self.socket.bind(addr) # 绑定地址到 socketself.socket.listen(1) # 开始监听,设置最大连接数为 1print(f'Web server started on {addr}')try:while True:cl, addr = self.socket.accept() # 接受客户端连接print('Client connected from', addr)try:request = cl.recv(1024).decode('utf-8') # 接收客户端请求if not request:continueprint('Request:', request.splitlines()[0]) # 打印请求的第一行response = self.handle_request(request) # 处理请求并获取响应cl.send(response.encode('utf-8')) # 发送响应给客户端except Exception as e:print('Request handling error:', e)finally:cl.close() # 关闭客户端连接except KeyboardInterrupt:print('Server stopped by user') # 用户中断服务器时打印提示finally:self.socket.close() # 关闭服务器 socket
HTML页面:提供了一个简单的拍照界面,点击“拍照”按钮后,通过 POST 请求向服务器发送拍照指令,并根据响应状态显示成功或错误消息,同时执行服务器返回的 JavaScript 代码。
说明:由于ESP32-CAM没有板载按键,这里使用手机访问ESP32-CAM的Web服务器点击拍照来充当拍照按键使用。
<!DOCTYPE html>
<html lang="zh-CN">
<head><title>ESP32-CAM</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><style>/* 页面样式 */body {font-family: Arial, sans-serif;max-width: 800px;margin: 0 auto;padding: 20px;}button {padding: 10px 20px;font-size: 16px;background-color: #4CAF50;color: white;border: none;border-radius: 4px;cursor: pointer;}button:disabled {background-color: #cccccc;}#status {margin-top: 20px;padding: 10px;border-radius: 4px;}.success { background-color: #dff0d8; color: #3c763d; }.error { background-color: #f2dede; color: #a94442; }</style>
</head>
<body><h1>ESP32-CAM拍照界面</h1><!-- 拍照按钮 --><button id="captureBtn">拍照</button><!-- 状态显示区域 --><div id="status"></div><script>// 为拍照按钮添加点击事件监听器document.getElementById('captureBtn').addEventListener('click', async function() {const btn = this; // 引用按钮本身const status = document.getElementById('status'); // 引用状态显示区域try {// 发送 POST 请求到服务器根路径,请求体为 'capture'const response = await fetch('/', {method: 'POST',headers: { 'Content-Type': 'text/plain' },body: 'capture'});// 检查响应状态if (!response.ok) {throw new Error(`HTTP error! status: ${response.status}`);}// 读取响应文本const js = await response.text();status.className = 'success'; // 设置状态样式为成功status.textContent = '拍照指令已发送'; // 显示成功消息// 执行返回的 JavaScript 代码try {new Function(js)();} catch(e) {console.error('JS执行错误:', e); // 捕获并打印 JavaScript 执行错误}// 1秒后自动清除状态消息setTimeout(() => {status.textContent = '';status.className = '';}, 1000); } catch(error) {// 捕获并处理请求失败的情况console.error('拍照请求失败:', error);status.className = 'error'; // 设置状态样式为错误status.textContent = '拍照失败: ' + error.message; // 显示错误消息// 错误信息3秒后清除setTimeout(() => {status.textContent = '';status.className = '';}, 3000);} finally {btn.disabled = false; // 无论成功或失败,都重新启用按钮}});
</script>
</body>
</html>
7 总结
本文介绍了用 ESP32 - CAM 搭配 FS800DTU 上传图像至巴法云的方法,感谢大家的观看。若您对本文章有任何不清楚的地方,可以私信或者在评论区留言,我们看到会及时回复您!