ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于RP2040与W5100S的嵌入式网络视频监控系统设计与实现

基于RP2040与W5100S的嵌入式网络视频监控系统设计与实现 1. 项目缘起为什么用RP2040做网络视频监控最近在捣鼓一个DIY项目想给家里的车库或者后院做个简单的视频监控。市面上现成的方案很多但要么太贵要么不够透明想自己动手折腾一下。核心需求很简单成本低、能联网、画质过得去、最好还能有点扩展性。翻了一圈手头的开发板和模块最后锁定了RP2040、W5100S和OV2640这个组合。你可能要问现在ESP32-CAM那么火为啥不用确实ESP32-CAM集成了Wi-Fi和摄像头开箱即用。但我这个场景有点特殊一是车库位置Wi-Fi信号不太稳定二是我需要更可靠的有线连接三是我想深入了解一下图像采集和网络传输的底层流程而不是仅仅调用一个封装好的库。RP2040作为树莓派基金会推出的双核MCU性能足够社区资源丰富而且其PIO可编程IO特性在处理摄像头数据流时非常灵活。W5100S是一个硬核的以太网控制器处理TCP/IP协议栈不占用MCU太多资源稳定性比软件模拟的强太多。OV2640则是久经考验的200万像素摄像头传感器性价比高资料多。用Arduino框架来开发又能大大降低入门门槛。所以这个项目的核心就是把这三大件攒在一起让RP2040通过OV2640“看见”世界再通过W5100S把看到的画面稳定地发送到网络另一端。这不仅仅是拼积木更涉及到图像采集格式选择、内存管理、网络协议封装等一系列实际工程问题。下面我就把自己从硬件连接到软件调试再到优化传输的完整过程以及踩过的那些坑详细拆解一遍。2. 硬件选型与连接搭建稳定的数据通路硬件是项目的骨架连接不可靠后面软件写得再好也是白搭。这一部分我会详细说明每个模块的选型理由、关键参数以及具体的接线方法。2.1 核心大脑RP2040开发板的选择与考量RP2040是一个芯片我们需要一个载板。常见的有Raspberry Pi Pico、Pico W以及第三方出的各种Pico兼容板。这里我强烈推荐使用标准的Raspberry Pi Pico而不是Pico W。原因如下引脚功能清晰标准Pico的GPIO功能定义明确没有像Pico W那样部分引脚被Wi-Fi/蓝牙模块复用在连接多个外设时更省心。成本与专注本项目使用W5100S进行有线网络通信Pico W自带的Wi-Fi功能是冗余的且其天线和射频电路可能引入不必要的噪声干扰。标准Pico更便宜也让我们更专注于以太网和摄像头的调试。供电稳定确保你的Pico可以通过USB口或者VSYS引脚获得稳定的5V供电因为W5100S和OV2640模块工作时功耗不小。RP2040的核心优势在于其264KB的SRAM和可编程IOPIO。OV2640输出的图像数据量很大充足的SRAM是用于缓存图像帧的关键。而PIO可以让我们用极低的CPU开销来实现特定的时序协议例如驱动摄像头或与W5100S进行高速SPI通信。2.2 图像之眼OV2640模块的识别与配置要点市面上OV2640模块很多常见的有带FPC排线接口的。我们需要关注以下几点供电电压绝大多数模块是3.3V逻辑电平与RP2040完美匹配。但务必确认模块的供电电压是3.3V接5V会烧毁。引脚定义模块通常引出以下关键信号SCCB (I2C) 接口用于配置摄像头参数如分辨率、格式、曝光等。对应RP2040的I2C引脚。VSYNC/HREF/PCLK垂直同步、行参考和像素时钟用于图像数据流同步。D0-D78位数据总线用于输出像素数据。XCLK主时钟输入需要由MCU提供通常24MHz。晶振好的模块会自带晶振为传感器提供时钟。劣质模块可能省略导致工作不稳定。在连接前最好用万用表测一下模块的VCC和GND避免短路。OV2640的功耗在活跃状态下约60mA启动瞬间可能有峰值电源要能扛住。2.3 网络桥梁W5100S以太网模块的关键细节W5100S是W5100的升级版功耗和性能有所优化。它集成了TCP/IP协议栈TCP, UDP, ICMP, IPv4, ARP, IGMP等和以太网MAC/PHY最大支持8个独立Socket。选择它而不是更便宜的ENC28J60主要是因为其硬件协议栈处理和更大的缓冲区在传输视频这种持续大数据流时更稳定CPU负担小。模块通常是3.3V工作电压通过SPI接口与MCU通信。需要注意SPI频率W5100S支持最高80MHz的SPI时钟我们可以用RP2040的高速SPI来充分发挥性能。中断引脚模块的INT引脚可以连接到RP2040的一个GPIO用于事件驱动如数据接收完成、连接建立等比轮询方式更高效。网络变压器好的W5100S模块会集成网络变压器那个黑色的方块可以直接连接网线。如果没有你需要一个单独的RJ45带变压器模块。2.4 硬件连接图与接线表将所有模块连接起来需要仔细规划GPIO避免冲突。下面是我的连接方案兼顾了信号完整性和代码编写的便利性。接线表示例RP2040 (Raspberry Pi Pico) 引脚连接至功能说明GP0OV2640 SIOCSCCB (I2C) 时钟线GP1OV2640 SIODSCCB (I2C) 数据线GP2OV2640 VSYNC垂直同步信号GP3OV2640 HREF行同步信号GP4OV2640 PCLK像素时钟GP5OV2640 XCLK摄像头主时钟输出GP6 - GP13OV2640 D0 - D78位像素数据总线GP14W5100S SCKSPI 时钟GP15W5100S MOSISPI 主出从入GP16W5100S MISOSPI 主入从出GP17W5100S /CSSPI 片选GP18W5100S RST复位信号可选可通过软件控制GP19W5100S INT中断信号可选但推荐3V3(OUT)OV2640 VCC, W5100S VCC3.3V电源GNDOV2640 GND, W5100S GND共地注意1电源务必确保所有模块使用同一个3.3V电源供电并且电流足够建议1A以上。最好从Pico的3V3_EN引脚取电或者使用一个外部的3.3V LDO稳压模块单独供电避免因电流不足导致摄像头或网络模块工作异常、频繁复位。注意2XCLK生成OV2640需要24MHz的输入时钟。我们可以使用RP2040的PWM或PIO来生成一个精确的24MHz方波信号输出到GP5。在Arduino框架下有专门的库函数可以配置时钟输出。连接时建议使用杜邦线先进行功能测试确认无误后再考虑焊接或使用面包板。长线连接可能会引入干扰影响图像质量或网络稳定性。3. 软件环境搭建与核心库解析硬件连好后就要让软件跑起来了。我们将使用Arduino IDE进行开发因为它对RP2040和众多库的支持已经非常成熟。3.1 Arduino IDE与RP2040开发环境的配置首先确保你安装了最新版本的Arduino IDE1.8.x或2.x均可。然后我们需要添加对Raspberry Pi RP2040板的支持。打开Arduino IDE进入文件 - 首选项。在“附加开发板管理器网址”中添加以下URLhttps://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json点击“确定”然后打开工具 - 开发板 - 开发板管理器。搜索“Raspberry Pi Pico”找到并安装“Raspberry Pi Pico/RP2040 by Earle F. Philhower”这个包。这个包非常强大集成了几乎所有常用功能。安装完成后在工具 - 开发板中选择“Raspberry Pi Pico”。接下来我们需要安装几个核心的库。打开项目 - 加载库 - 管理库...。Ethernet3这是一个针对W5100/W5200/W5500包括W5100S的增强版库比Arduino自带的Ethernet库更稳定对RP2040兼容性更好。搜索并安装“Ethernet3 by Seeed Studio”。OV2640 Camera Library我们需要一个能驱动OV2640的库。搜索“OV2640”可能会找到多个。我推荐使用“rpi_pico_tinyusb_camera”或“esp32-camera”的移植版。但更直接的方法是我们可以使用“Arduino_OV2640”这个库它通常与“Arduino_GFX”库配合使用。为了简单起见我们可以先安装“Arduino_GFX”库它通常包含了常见摄像头的驱动。在库管理器中搜索“Arduino_GFX”并安装。如果库管理器找不到合适的摄像头驱动你可能需要手动从GitHub下载。一个可行的方案是使用“RP2040_Camera”相关的开源项目代码。这里我们可以采用一种更实用的方法直接使用Pico官方SDK中关于OV2640的示例并将其适配到Arduino框架。但为了快速上手我假设我们使用一个经过简化的、易于理解的驱动方式。3.2 理解OV2640的数据流与采集策略在写代码前必须明白OV2640是如何输出数据的。它支持多种输出格式YUV JPEG RGB565。对于网络传输JPEG格式是唯一可行的选择。原因很简单RAW格式如YUV或RGB数据量太大。一张320x240的RGB565图片就有3202402153600字节远超网络实时传输的能力。而JPEG是压缩格式同样分辨率的图片可能只有几KB到十几KB非常适合流式传输。OV2640可以在硬件内部将图像压缩成JPEG格式输出这大大减轻了MCU的压力。我们的任务就是配置OV2640进入JPEG输出模式然后通过RP2040的GPIO和PIO按照VSYNC、HREF、PCLK的时序将D0-D7上的JPEG数据流“搬运”到内存缓冲区中。这个过程是高速且连续的。一帧图像的数据就像一条河VSYNC标志一条河的起点一帧开始HREF标志河面的宽度一行开始PCLK是水流的速度每个时钟读取一个字节D0-D7就是水里的鱼像素数据。我们需要在河边RP2040的SRAM挖一个足够大的池塘缓冲区来临时存放这些“鱼”然后再用网络卡车W5100S把池塘里的鱼运走。RP2040的PIO可以完美扮演“挖池塘工人”的角色。我们可以编写一个PIO程序让它专门监听VSYNC、HREF和PCLK自动将数据总线上的值存入指定的内存区域而几乎不占用CPU时间。这是实现流畅采集的关键。3.3 W5100S网络通信的基础配置W5100S通过SPI通信。Ethernet3库已经帮我们封装了底层细节。我们需要做的是初始化SPI设置正确的SPI引脚和频率。初始化Ethernet提供MAC地址可以自定义但局域网内需唯一、IP地址、网关和子网掩码。对于简单监控我们可以使用静态IP。创建SocketW5100S支持多个Socket。我们将创建一个TCP Server Socket监听一个端口比如8080等待客户端如电脑上的浏览器或VLC播放器连接。处理连接与数据发送一旦有客户端连接我们就不断地将采集到的JPEG图像数据通过这个Socket发送出去。为了能让浏览器直接显示我们需要在发送图像数据前发送一个简单的HTTP响应头内容类型Content-Type设置为image/jpeg并使用multipart/x-mixed-replace技术实现视频流效果。4. 核心代码实现从采集到传输的全流程理论讲完是时候上代码了。我将分模块解释关键代码段。请注意以下代码是概念性的需要根据你实际使用的库进行调整和整合。4.1 OV2640的初始化和JPEG采集首先我们需要初始化与OV2640的I2C通信并写入一系列寄存器配置值将其设置为JPEG输出模式和所需的分辨率例如QVGA: 320x240。#include Wire.h #define OV2640_I2C_ADDR 0x30 // OV2640的I2C地址通常是0x30 void setupCamera() { Wire.begin(); // 初始化I2C使用默认引脚GP0(SDA), GP1(SCL) delay(100); // 写入一系列初始化寄存器配置通常由厂家提供或从示例代码中获取 // 这是一个简化示例实际需要一长串的寄存器地址和值 writeReg(0xff, 0x01); // 切换到DSP寄存器区 writeReg(0x12, 0x80); // 复位所有寄存器 delay(100); // ... 省略数十行配置包括设置时钟、像素格式、窗口大小、JPEG模式等 ... // 例如设置输出为JPEG格式 writeReg(0xff, 0x00); writeReg(0x44, 0x32); // 相关JPEG控制寄存器 // 设置分辨率 QVGA writeReg(0xff, 0x01); writeReg(0x12, 0x40); // 设置QVGA格式 // ... 更多分辨率相关配置 ... writeReg(0xff, 0x01); writeReg(0x15, 0x00); // 设置VSYNC等极性根据硬件连接调整 Serial.println(Camera configured for JPEG QVGA.); } void writeReg(uint8_t reg, uint8_t val) { Wire.beginTransmission(OV2640_I2C_ADDR); Wire.write(reg); Wire.write(val); Wire.endTransmission(); }接下来是最关键的部分使用PIO捕获数据。这里我们展示一个概念性的PIO程序思路。实际中你可能需要参考RP2040的PIO SDK示例或使用现成库中已编写好的PIO程序。// 伪代码/概念描述 // 1. 编写一个PIO程序 (capture.pio)它等待VSYNC下降沿帧开始 // 然后对每个PCLK上升沿如果HREF为高在行有效期内 // 就从8个数据引脚读取一个字节并存入FIFO。 // 2. 在主程序中初始化这个PIO状态机并为其分配一个内存缓冲区。 // 3. 启动状态机它会在后台自动抓取数据。 // 4. 通过检查缓冲区指针或使用DMA完成中断来知道一帧数据何时抓取完毕。 #include hardware/pio.h #include capture.pio.h // 假设这是你编译好的PIO程序头文件 PIO pio pio0; uint sm 0; uint8_t image_buffer[320 * 240 * 2]; // 缓冲区大小要足够容纳一帧JPEG可能比这大 void setupPIOCapture() { // 加载PIO程序 uint offset pio_add_program(pio, capture_program); // 配置状态机 sm pio_claim_unused_sm(pio, true); capture_program_init(pio, sm, offset, PIN_VSYNC, PIN_HREF, PIN_PCLK, PIN_D0); // 设置DMA将PIO FIFO中的数据自动搬运到image_buffer // ... DMA配置代码 ... } // 在loop中检查一帧是否完成 void loop() { if (frame_ready_flag) { // 由DMA中断或标志位设置 processAndSendJPEG(image_buffer, frame_length); frame_ready_flag false; // 重新启动下一帧捕获 } }由于在Arduino环境下直接操作PIO和DMA相对复杂很多现成的库如rpi_pico_tinyusb_camera已经封装好了这些底层操作。我们的任务往往是调用类似cam.grab()或cam.capture()的函数来获取一帧图像。4.2 W5100S网络服务与MJPEG流推送假设我们使用Ethernet3库并已成功初始化网络。我们将创建一个TCP服务器并在客户端连接后推送MJPEG流。#include Ethernet3.h byte mac[] { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; IPAddress ip(192, 168, 1, 177); // 设置你的静态IP IPAddress gateway(192, 168, 1, 1); IPAddress subnet(255, 255, 255, 0); EthernetServer server(8080); // 在8080端口创建服务器 EthernetClient client; bool clientConnected false; void setupNetwork() { Ethernet.begin(mac, ip, gateway, subnet); server.begin(); Serial.print(Server is at ); Serial.println(Ethernet.localIP()); } void handleClient() { // 监听新的客户端连接 client server.available(); if (client) { Serial.println(New client connected); clientConnected true; // 发送HTTP响应头声明这是一个MJPEG流 client.println(HTTP/1.1 200 OK); client.println(Content-Type: multipart/x-mixed-replace; boundaryframe); client.println(); client.flush(); } // 如果客户端已连接则持续发送图像 if (clientConnected client.connected()) { sendMJEPGFrame(); } else { // 客户端断开连接 clientConnected false; Serial.println(Client disconnected); } } void sendMJEPGFrame() { // 1. 从摄像头获取一帧JPEG数据及其长度 // 假设 getJPEGFrame 函数将数据填充到全局缓冲区 jpegBuffer并返回长度 size_t jpegSize getJPEGFrame(jpegBuffer, sizeof(jpegBuffer)); if (jpegSize 0) { // 2. 发送MJPEG分界头和图像信息 client.println(--frame); client.print(Content-Type: image/jpeg\r\n); client.print(Content-Length: ); client.println(jpegSize); client.println(); // 空行分隔头部和主体 // 3. 发送JPEG图像数据 client.write(jpegBuffer, jpegSize); client.println(); // 可选再添加一个换行 client.flush(); // 确保数据发送出去 // 可以在这里打印帧率或大小用于调试 // Serial.printf(Sent frame: %d bytes\n, jpegSize); } else { Serial.println(Failed to capture frame); } }在loop()函数中我们不断调用handleClient()和图像捕获逻辑。void loop() { handleClient(); // 处理网络连接 // 主循环的核心是尽可能快地捕获和发送帧 // 如果摄像头库支持非阻塞捕获可以在这里调用 // 否则捕获过程可能是阻塞的这会影响网络响应 // 理想情况是网络发送和图像捕获在不同的核心或通过中断/DMA异步进行 }4.3 双核处理与性能优化初探RP2040是双核处理器我们可以利用这个特性来提升性能。一个核心Core 0专门负责繁重的图像采集和JPEG编码如果使用软件编码工作另一个核心Core 1则专门处理网络通信发送数据。这涉及到多核编程和进程间通信。在Arduino环境下可以使用FreeRTOS已集成在Earle Philhower的板支持包里或者更底层的pico_multicoreSDK函数。一个简单的模式是使用一个共享的环形缓冲区ring bufferCore 0 捕获一帧JPEG后将其放入环形缓冲区。Core 1 不断检查环形缓冲区如果有数据就取出并通过网络发送。需要小心处理缓冲区满和空的状态避免数据竞争。对于初学者可以先实现单核阻塞版本确保功能正常。在优化阶段如果发现帧率上不去网络发送太慢阻塞了下一帧捕获再考虑引入双核和缓冲区机制。另一个简单的优化是降低分辨率从QVGA降到176x144或更低或降低JPEG质量这能显著减少每帧数据量提高帧率。5. 调试、踩坑与实战优化把代码烧录进去只是第一步真正的挑战在于调试和优化。下面是我在实现过程中遇到的一些典型问题及解决方案。5.1 图像采集失败时序与电源的玄学问题现象初始化摄像头后读取到的帧数据全是0或者杂乱无章有时VSYNC或HREF信号根本没有变化。排查1电源问题。这是最常见的原因。用万用表测量连接摄像头VCC引脚处的电压在摄像头工作时是否稳定在3.3V是否有大幅跌落如果跌落严重说明你的USB电源或LDO输出能力不足。解决方案使用带独立电源的USB Hub或者使用一个输出能力大于1A的3.3V稳压模块单独给摄像头和W5100S供电Pico仅作为信号控制。排查2XCLK时钟。OV2640的XCLK引脚必须有24MHz的时钟输入。用逻辑分析仪或示波器检查GP5引脚是否有24MHz的方波输出。如果没有检查代码中时钟配置部分。在Arduino for RP2040中可以使用analogWriteFreq(24000000);和analogWrite(PIN_XCLK, 128);来在指定引脚生成50%占空比的24MHz PWM波作为时钟源。排查3I2C通信。确认I2C引脚连接正确SDA, SCL并且上拉电阻存在通常模块板载了。可以写一个简单的I2C扫描程序看看是否能检测到地址0x30的设备。排查4同步信号极性。OV2640的VSYNC和HREF极性是可以配置的。我的模块是VSYNC低电平有效HREF高电平有效。如果你的信号反了需要在初始化寄存器时配置COM10等寄存器来反转极性。最笨但有效的方法用逻辑分析仪同时抓取VSYNC、HREF、PCLK和一条数据线对照OV2640数据手册的时序图检查。5.2 网络连接不稳定或无法建立问题现象Pico获取不到IP或者客户端能连接但很快断开数据发送卡顿。排查1SPI通信速率。初始化Ethernet时可以尝试降低SPI速率。虽然W5100S支持高速但接线较长或质量不好时高速SPI容易出错。在Ethernet.init(cs_pin)后可以尝试SPI.setClockDivider(SPI_CLOCK_DIV8);来降低速度。排查2MAC地址冲突。确保你的MAC地址在局域网内是唯一的。如果有多块开发板要修改MAC地址。排查3路由器/交换机限制。有些企业级网络设备会禁止未认证设备通信。确保你的Pico和客户端电脑在同一个简单的家用路由器网络下。排查4缓冲区与发送策略。TCP协议保证数据可靠送达但如果发送太快而网络或客户端处理不过来数据会在W5100S的内部缓冲区堆积最终导致发送阻塞。解决方案在client.write()后检查client.availableForWrite()返回值如果缓冲区快满了就延迟一下再发送下一部分数据。不要一次性发送整帧大的JPEG数据。可以将一帧数据分多次client.write()每次写一个小块如512字节并在中间短暂延时或检查网络缓冲区。在发送HTTP头后调用client.setNoDelay(true);禁用Nagle算法它会缓冲小数据包合并发送对于实时视频流我们需要更低的延迟。5.3 帧率低下与系统稳定性提升问题表现视频流卡顿帧率远低于预期如低于5帧。瓶颈分析采集端检查从触发捕获到一帧数据就绪的时间。如果使用阻塞式cam.capture()这个时间可能很长。考虑使用异步捕获或降低分辨率。传输端JPEG帧太大。QVGA的JPEG在复杂场景下可能超过20KB。计算一下20KB * 10帧/秒 200KB/s。这对于100M以太网不是问题但对于MCU处理和TCP栈来说是个负担。优化措施降低分辨率尝试176x144 (QCIF) 或 160x120。提高JPEG压缩比通过修改OV2640的量化表Q-table寄存器提高压缩率会降低画质。这需要深入研究OV2640的数据手册。限制最大帧大小在代码中如果捕获的一帧JPEG超过某个阈值如15KB就丢弃这一帧等待下一帧。这能防止因某一帧过大导致的长时间网络阻塞。动态帧率控制不要以固定速度发送。在sendMJEPGFrame()函数中计算每帧的发送耗时。如果上一帧发送耗时太长就在发送下一帧前主动延时一段时间避免系统过载。内存管理频繁地分配和释放大块内存如图像缓冲区会产生内存碎片最终导致分配失败系统崩溃。解决方案在全局区静态分配图像缓冲区uint8_t jpegBuffer[MAX_JPEG_SIZE];并复用这个缓冲区。确保你的捕获函数也是填充这个缓冲区而不是返回一个新的指针。5.4 客户端观看浏览器与专业软件的选择发送的是MJPEG流客户端如何观看网页浏览器最简单。在Chrome、Firefox等浏览器地址栏输入http://[你的Pico IP]:8080即可。因为我们的HTTP响应头是正确的multipart/x-mixed-replace浏览器会自动识别并持续更新图像形成视频流。注意Safari浏览器对MJPEG支持可能有问题。VLC播放器更专业功能更强。打开VLC点击媒体 - 打开网络串流输入http://[你的Pico IP]:8080点击播放。VLC能更好地处理网络波动。自定义客户端你可以用PythonOpenCV、C#甚至Processing编写一个简单的客户端程序连接TCP端口解析MJPEG流并显示。这为你后期添加运动检测、录像等功能提供了可能。6. 项目扩展与进阶思路一个基础的视频监控系统已经搭建完成。但它的潜力不止于此这里有几个扩展方向6.1 添加运动检测与报警触发我们可以在RP2040上实现简单的运动检测而不需要将视频流上传到服务器处理。帧差分法在内存中保留上一帧图像的缩小灰度图例如40x30。捕获新帧后也将其转换为同样大小的灰度图。然后逐像素比较两帧的差值如果超过某个阈值的像素数量达到一定比例就认为检测到运动。触发动作检测到运动后可以通过W5100S向指定的服务器发送一个HTTP GET请求如IFTTT Webhook触发手机通知。控制一个连接到RP2040的继电器打开警报器或灯光。将触发前后一段时间的高质量JPEG帧保存到RP2040外接的SD卡中需要添加SD卡模块。优化性能运动检测在低分辨率灰度图上进行计算量很小RP2040完全能胜任。可以将检测任务放在第二个核心上。6.2 集成SD卡进行本地录像添加一个SPI接口的Micro SD卡模块可以实现循环录像或事件触发录像。挑战SD卡写入速度。高质量的视频流会产生大量的写入操作。需要选择Class 10或以上的高速卡并使用高效的文件系统库如SdFat。写入时最好将多帧JPEG数据缓存在内存中组成一个较大的数据块后再一次性写入SD卡以减少文件系统开销。文件格式最简单的就是按时间戳将JPEG文件依次存入SD卡。后期可以用FFmpeg等工具将其合成为MP4视频。也可以尝试实现一个简单的AVI容器格式直接在MCU端生成可播放的视频文件。6.3 探索低功耗与无线备份方案虽然本项目主打有线稳定但也可以考虑低功耗场景。低功耗模式在无人时段如通过运动检测判断可以让RP2040进入深度睡眠Dormant模式仅由外部传感器如PIR中断唤醒。唤醒后快速启动摄像头和网络抓拍几张图片并上传后再次休眠。无线备份保留Pico的Wi-Fi能力使用Pico W将以太网作为主链路Wi-Fi作为备用链路。当网线被拔掉或路由器故障时系统可以自动切换到Wi-Fi连接通过MQTT或HTTP向云端发送报警信息和低帧率的快照。这个基于RP2040、W5100S和OV2640的视频监控系统项目从硬件连接到软件调试再到问题排查和性能优化几乎涵盖了一个嵌入式多媒体应用的所有关键环节。它不仅仅是一个监控工具更是一个理解图像传感器、实时数据流、网络协议栈和微控制器多任务处理的绝佳学习平台。当你看到浏览器中显示出来自自己亲手搭建系统的实时画面时那种成就感是无可替代的。希望我的这些经验和踩过的坑能帮助你更顺利地完成自己的项目。
返回列表