ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

基于树莓派Pico与Nextion屏的桌面气象站:Visuino图形化开发实践

基于树莓派Pico与Nextion屏的桌面气象站:Visuino图形化开发实践 1. 项目缘起为什么选择PicoNextionVisuino做气象站最近在捣鼓一个桌面小玩意儿想实时显示一下温湿度、气压这些数据最好还能有个漂亮的界面。市面上成品气象站不少但总感觉少了点DIY的乐趣和定制化的空间。于是我把目光投向了手头的几样“积木”一块小巧但性能不俗的树莓派Pico一块带触摸屏的Nextion智能串口屏以及一个号称能“图形化编程”微控制器的工具Visuino。把它们组合起来一个完全由自己定义界面和功能的桌面气象站听起来就很有意思。这个组合的吸引力在于它巧妙地平衡了开发难度、硬件成本和最终效果。树莓派Pico作为核心负责数据采集和逻辑处理其双核RP2040芯片和丰富的GPIO接口应付几个传感器绰绰有余。Nextion屏则解决了显示和人机交互的难题它自带处理器和图形库我们只需要通过串口发送简单的指令就能控制它显示图片、文字和响应触摸无需在Pico上耗费大量资源去驱动复杂的图形界面。而Visuino则是连接两者的“粘合剂”和“加速器”。它通过拖放组件、连接管脚和设置属性的方式自动生成Arduino框架下的C代码极大降低了嵌入式开发的入门门槛让我们可以更专注于功能逻辑本身而不是繁琐的底层寄存器配置和通信协议调试。所以这个项目本质上是一个典型的“微控制器 智能外设 高效开发工具”的物联网终端应用。它非常适合那些想快速实现一个带UI的嵌入式项目但又对纯代码开发感到畏惧或者希望缩短开发周期的爱好者。接下来我将从硬件选型、Visuino环境搭建、核心通信逻辑实现、传感器集成以及界面设计等多个维度详细拆解整个构建过程。2. 硬件清单与核心电路连接解析动手之前得先把“积木”准备好并弄清楚它们之间如何正确“拼接”。硬件连接是整个项目的物理基础一步错可能导致后续所有调试都徒劳无功。2.1 核心组件选型与功能定位主控树莓派Pico型号Raspberry Pi Pico带焊盘的版本更方便。角色项目的大脑。负责运行Visuino生成的固件通过I2C或SPI总线读取传感器数据进行必要的计算如海拔换算并通过串口UART与Nextion屏幕进行指令交互。选型理由价格低廉性能足够133MHz双核ARM Cortex-M0GPIO丰富社区支持好Visuino对其有良好支持。显示与交互Nextion智能串口屏型号根据需求选择尺寸如NX3224T0242.4寸、NX4024T0323.2寸等。建议选择带触摸功能的型号以增加交互性如切换显示页面、设置阈值。角色项目的脸面。独立完成所有图形渲染和触摸检测接收来自Pico的串口指令更新显示内容并将触摸事件坐标通过串口回传给Pico。选型理由开发极其简单无需编写屏驱代码丰富的上位机软件Nextion Editor用于设计界面大大降低了图形化项目的难度。开发工具Visuino角色项目的“脚手架”和“代码生成器”。图形化编程环境将硬件操作抽象为组件通过连线定义数据流和逻辑。选型理由对非专业开发者或快速原型开发非常友好能直观地构建复杂逻辑自动处理许多底层细节如定时器初始化、中断配置生成高质量、可读的Arduino代码。气象传感器BME280型号Bosch BME280模块市面上常见的是集成I2C上拉电阻和电平转换的模块。角色项目的感官。集成高精度温度、湿度和气压传感器通过I2C接口与Pico通信。选型理由一颗芯片解决三大气象要素精度和稳定性都很好且拥有广泛的软件库支持在Visuino中也有现成的组件。2.2 电路连接详解与原理连接的核心是建立两条独立的通信链路Pico与BME280之间的I2C总线以及Pico与Nextion之间的串口UART总线。电源需要统一。电源部分重中之重 所有设备必须共地GND。Nextion屏幕和Pico都可以通过USB 5V供电。但强烈建议使用一个外部5V/2A以上的电源适配器通过Pico的VSYS引脚或Nextion的5V引脚接入为整个系统供电。因为Nextion屏幕在背光全亮、刷新复杂图形时功耗可能超过500mA仅靠电脑USB口可能供电不足导致屏幕闪烁、复位或通信异常。I2C连接Pico - BME280 I2C是同步、半双工的总线需要两根线时钟线SCL和数据线SDA都需要上拉电阻通常BME280模块已集成。PicoGP5(I2C1 SCL) - BME280SCLPicoGP4(I2C1 SDA) - BME280SDAPico3V3(OUT)- BME280VCC(注意BME280是3.3V器件切勿接5V)PicoGND- BME280GND串口连接Pico - Nextion 串口是异步、全双工的通信方式需要交叉连接TX和RX。PicoGP0(UART0 TX) - NextionRX(黄色线)PicoGP1(UART0 RX) - NextionTX(蓝色线)PicoGND- NextionGND(黑色线)电源将外部5V电源正极同时接到Pico的VSYS引脚和Nextion的5V引脚。注意接线时务必断电操作。Nextion的TX/RX引脚是3.3V电平与Pico的GPIO电平兼容可以直接连接。如果使用其他逻辑电平的屏幕可能需要电平转换模块。3. Visuino环境配置与项目框架搭建硬件连好后我们进入“软件装配”环节。Visuino的使用逻辑和常见的纯代码开发有所不同理解其组件化思维是关键。3.1 Visuino的安装与基础设置首先确保你电脑上安装了最新版的Visuino。启动后我们需要进行两步关键设置安装树莓派Pico支持包在Visuino中点击顶部菜单栏的Tools-Board-Boards Manager...。在弹出的对话框中搜索“Raspberry Pi Pico”找到并安装“Raspberry Pi Pico by Raspberry Pi”支持包。安装完成后在Tools-Board下就能选择“Raspberry Pi Pico”了。配置串口监视器用于调试Nextion和Pico之间通过串口通信我们可能需要观察它们之间“聊”了什么来排查问题。在Visuino中Tools-Serial Terminal可以打开一个串口终端。但Visuino的终端功能相对基础。一个更专业的做法是在生成代码并上传到Pico后使用独立的串口调试助手如Arduino IDE的串口监视器、Putty或VS Code的PlatformIO串口监视器来监听Pico的调试输出如果代码中启用了Serial打印。3.2 创建项目与添加核心组件在Visuino中新建一个项目选择开发板为“Raspberry Pi Pico”。你会看到一个空白的“设计表面”。我们从左侧的组件面板拖拽需要的组件进来时钟源Clock从Components-System拖一个Clock组件到设计表面。它相当于一个定时器用于周期性触发我们的主逻辑比如每秒读取一次传感器并更新屏幕。将其Frequency属性设置为1单位选择Hz表示每秒触发一次。I2C通道Pico的I2C功能本身已集成在板卡定义中但我们还需要一个软件层面的I2C通信组件来管理BME280。从Components-Communication-I2C拖一个I2C组件进来。将其Channel属性设置为1以匹配我们硬件连接中使用的I2C1GP4, GP5。BME280传感器组件从Components-Sensors-Environmental找到BME280组件并拖入。将其I2C属性下的Channel也设置为1。这样BME280组件就知道通过哪个I2C通道去通信了。串口UART组件从Components-Communication-Serial拖一个Serial组件进来。这是Pico与Nextion通信的桥梁。将其Channel属性设置为0以匹配我们使用的UART0GP0, GP1。波特率Baud Rate暂时设置为9600这是Nextion的默认波特率后续可以在Nextion Editor里修改但两者必须一致。文本格式化组件To TextBME280读取到的温度、湿度是浮点数气压是整数。我们需要把它们转换成Nextion能显示的文本字符串。从Components-System-Converter拖入多个To Text组件。每个组件负责转换一个数据。在其Format属性中可以设置格式例如温度可以设为0.1°C表示保留一位小数并加上单位。3.3 组件连线与数据流构建Visuino的核心是“数据流”编程。我们需要用“线”把组件的输出管脚圆圈和输入管脚菱形连接起来定义信息的流动路径。触发传感器读取将Clock1组件的Out管脚连接到BME2801组件的Read管脚。这样每秒时钟触发一次就命令BME280读取一次数据。提取传感器数据BME2801组件读取成功后会在其Temperature、Humidity、Pressure等管脚输出数据。将这些管脚分别连接到对应的To Text组件的In管脚。格式化数据To Text组件会将输入的数字转换为其Format属性定义的字符串并从Out管脚输出。发送数据到串口关键步骤这里需要构造Nextion指令。Nextion通过串口接收特定格式的指令来更新屏幕上的元件。例如更新一个名为t0的文本控件指令格式为t0.txt\25.6\加上结束符0xFF 0xFF 0xFF。我们需要为每个数据温度、湿度、气压构造这样的指令。Visuino提供了Concat Text组件在System-Text下来拼接字符串。以温度为例拖入一个Concat Text。在其Text属性中第一部分输入t0.txt\假设温度文本框在Nextion中的对象名是t0。然后将格式化温度字符串的To Text组件的Out管脚连接到Concat Text的一个输入管脚点击Concat Text组件在属性面板的Pins里可以添加输入管脚。最后再添加一个Text常量组件值为\连接到Concat Text的另一个输入管脚闭合引号。这样Concat Text的输出就是类似t0.txt\23.5\的字符串。但这还不是完整指令缺少Nextion要求的三个0xFF结束符。Visuino的Serial组件在发送时可以自动添加结束符吗通常不行。更可靠的做法是再使用一个Concat Text将上一个的输出与一个特殊的“结束符”字符串拼接。我们可以创建一个Text Constant其值设置为三个十六进制FF对应的字符。但注意在C语言字符串中0xFF可能不是有效ASCII字符。一个更通用的方法是在后续生成的代码中手动添加。或者利用Visuino的Code组件注入自定义代码。对于初学者我们可以先在Visuino中完成主体框架生成代码后再在Arduino IDE中手动补充指令结尾的0xFF 0xFF 0xFF。这是Visuino结合手动代码调整的常见做法。连接串口发送将最终拼接好的完整指令字符串例如t0.txt\23.5\连接到Serial0组件的In管脚。同时别忘了将Clock1的Out也连接到Serial0的Send管脚以确保每秒触发一次数据发送。至此一个最简单的、单向Pico-Nextion数据流框架就在Visuino中搭建好了。点击Visuino右上角的“生成代码”按钮F9它会为你生成一个完整的Arduino项目代码。4. Nextion界面设计与指令系统深入Pico这边的逻辑框架有了Nextion屏幕需要显示内容。这部分工作在Nextion Editor软件中完成它是一个所见即所得的图形化设计工具。4.1 使用Nextion Editor创建基础界面新建项目打开Nextion Editor选择与你屏幕型号完全一致的模板。设置分辨率、波特率需与Visuino中Serial组件的波特率一致如9600等参数。添加控件文本控件Text用于显示温度、湿度、气压的数值。拖入三个Text控件到画布上。分别双击它们在属性面板中修改其“objname”为有意义的名称如txtTemp、txtHumi、txtPres。这个“objname”就是我们在Pico代码中发送指令时需要指定的对象名。同时可以设置字体、颜色、对齐方式等。图片控件Picture可以添加一些图标如太阳、云朵、温度计图标使界面更美观。进度条控件Progress Bar如果想用进度条直观显示湿度百分比可以添加一个并设置其objname如barHumi。页面Page可以创建多个页面通过触摸按钮切换显示更详细的信息如历史曲线、设置菜单。编译与下载设计完成后点击菜单栏的“文件”-“编译”会生成一个.tft文件。然后通过USB转TTL串口工具或Pico的USB口虚拟串口如果屏幕支持并配置了USB下载将.tft文件下载到Nextion屏幕中。下载时屏幕会黑屏并显示进度条完成后自动重启加载新界面。4.2 Nextion指令系统精讲与Visuino实现Nextion的指令是其灵魂。除了上面用到的objname.txtvalue来更新文本还有非常丰富的指令集。修改控件属性objname.attributevalue。例如barHumi.val65可以设置进度条的值pic1.pic2可以更改图片控件显示的图片ID。切换页面page pageID。例如在Pico代码中发送page 1指令屏幕就会切换到ID为1的页面。读取触摸事件当用户触摸屏幕时Nextion会主动通过串口上报事件。格式如touch j, btn1, 1表示在页面j上对象btn1被按下1表示按下0表示释放。Pico需要解析这些上报数据来做出响应。在Visuino中实现复杂的指令构造和事件解析有时会显得笨拙。这就是为什么很多项目会采用“Visuino生成框架 手动编写核心通信代码”的混合模式。混合开发模式实践在Visuino中完成硬件初始化和数据采集保留我们之前搭建的Clock触发BME280读取并获取到温度、湿度、气压数值的部分。在生成的代码中手动添加Nextion指令发送函数打开Visuino生成的.ino文件通常在C:\Users\[用户名]\Documents\Visuino\Generated目录下。在loop()函数之外定义一个辅助函数void sendToNextion(const char* componentName, const char* property, const char* value) { Serial.print(componentName); Serial.print(.); Serial.print(property); Serial.print(\); Serial.print(value); Serial.print(\); Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF); // 发送三条结束符 }修改loop()函数中由Visuino生成的发送逻辑。找到类似Serial1.print(...)的代码段具体串口对象名取决于你的设置将其替换为对自定义函数的调用。例如发送温度// 假设 tempStr 是Visuino生成的温度字符串变量 sendToNextion(txtTemp, txt, tempStr);在Visuino中添加串口接收解析逻辑从Components-Communication-Serial拖一个Serial组件作为接收器如果和发送是同一个UART则共用同一个组件但需要处理其Out管脚的数据。将Serial组件的Out管脚连接到一个Text Receive组件在System-Text下它可以将接收到的字节流缓冲成字符串。再连接一个Logic组件如Compare Text来判断接收到的字符串是否包含特定事件如touch j, btn1, 1。根据判断结果触发相应的动作比如切换一个全局状态变量或者控制另一个Clock组件来改变数据更新频率。这种混合方式既利用了Visuino快速配置硬件、生成初始化代码的优势又通过手动编码实现了灵活、复杂的通信协议处理是构建此类项目的有效策略。5. 传感器数据采集、处理与显示优化有了通信框架我们需要关注数据的质量。直接从传感器读出的原始数据有时需要经过处理才能更好地显示。5.1 BME280数据读取与Visuino组件配置在Visuino中BME280组件已经封装了复杂的I2C通信协议。我们主要需要配置其采样模式和滤波器以平衡精度、功耗和响应速度。打开组件属性双击设计表面的BME2801组件。配置模式在属性窗口中找到Mode。通常选择Normal Mode正常模式传感器会周期性地测量。Forced Mode强制模式则只在被请求时测量一次更省电。配置过采样率Oversampling分别设置温度、湿度、气压的过采样率。例如都设置为x4或x8。过采样率越高数据噪声越小精度越高但每次测量的时间也越长功耗略增。对于桌面气象站x4通常是个不错的平衡点。配置滤波器FilterIIR滤波器可以有效平滑数据的短期波动使显示值更稳定。例如将Filter设置为x4或x8。这特别适用于气压值因为气压本身变化缓慢过滤掉高频噪声后曲线更平滑。这些配置会直接影响BME2801组件输出管脚的数据。配置好后Visuino在生成代码时会自动写入相应的BME280初始化寄存器。5.2 数据平滑与单位换算即使开启了硬件滤波器我们可能还需要在软件层面进行进一步平滑比如使用移动平均滤波。在Visuino中实现简单移动平均 Visuino提供了Average组件在Math-Statistics下。我们可以将BME2801的Temperature输出管脚先连接到一个Average组件再将Average的输出连接到To Text组件。在Average组件的属性中设置Sample Size样本大小为比如10表示对最近10次读数求平均。这样显示的温度就是过去10秒假设1秒读一次的平均值避免了数字的剧烈跳动。单位换算 BME280读取的气压单位通常是帕斯卡Pa。而日常生活中常用百帕hPa或毫米汞柱mmHg。我们可以在Visuino中完成换算。从Math-Operators拖入一个Divide除法组件。将BME2801的Pressure输出管脚连接到Divide的A输入。再拖入一个Constant常量组件在Math-Constants下设置其值为100.0并将其输出连接到Divide的B输入。此时Divide的输出就是气压值hPa。再将其连接到To Text组件进行格式化。对于海拔高度估算可以使用公式altitude 44330 * (1 - pow((pressure / seaLevelPressure), 0.1903))其中seaLevelPressure是当地海平面气压可从天气预报获取近似值。这个计算在Visuino中实现较为复杂涉及幂运算。更简单的方式是在生成的代码中用pow()函数手动计算或者如果精度要求不高使用线性近似。5.3 在Nextion上实现动态效果与多页面管理静态显示数字有些枯燥。Nextion支持一些简单的动态效果。数值颜色变化例如温度高于30度显示红色低于10度显示蓝色。这可以在Pico端判断然后发送修改文本颜色的指令txtTemp.bcoRED其中RED是Nextion预定义的颜色值或直接用16进制RGB值如63488代表红色。在Visuino中可以通过Compare比较组件连接温度值和阈值常量其输出可以控制一个Switch开关组件选择发送不同的指令字符串。简单动画Nextion支持让图片控件在不同图片间切换形成帧动画。可以设计一组表示“晴天”、“多云”、“下雨”的图标。Pico根据湿度、气压趋势判断天气状况然后循环发送picWeather.pic1、picWeather.pic2... 指令在Nextion上形成简单的动画效果。这需要预先将多张图片下载到Nextion的Flash中。多页面与触摸切换设计多个页面Page。在主页Page0显示概要信息在Page1显示历史曲线需要Pico存储一段时间的数据并发送绘图指令或Nextion高级型号支持本地数据记录和绘图在Page2显示设置如单位切换、阈值设置。在Nextion Editor中为页面上的按钮Button控件添加“触摸释放事件”在事件里写入指令page 1来跳转页面。Pico需要监听页面切换事件通过串口接收page ID指令以便在切换到不同页面时发送该页面需要的数据。6. 系统集成、调试与常见问题排查当硬件连接妥当、Visuino逻辑搭建完成、Nextion界面设计好并下载后就到了最激动人心也最可能遇到问题的环节——联调。6.1 完整工作流程与代码集成Visuino生成与代码导出在Visuino中完成所有图形化设计后点击F9生成代码。Visuino会生成一个完整的Arduino项目文件夹。手动代码增强用Arduino IDE或VS Code打开生成的项目文件夹中的.ino主文件。按照第4.2节和第5.2节所述添加自定义的Nextion指令发送函数、数据平滑算法或单位换算逻辑。将Visuino生成的发送代码替换为对自定义函数的调用。库依赖管理Visuino生成的代码会自动包含必要的库如Wire、BME280的库。确保这些库已安装在你的开发环境中Arduino IDE的库管理中。对于BME280常用的库是Adafruit_BME280Visuino通常使用其自带的封装但原理相同。编译与上传选择正确的开发板Raspberry Pi Pico和端口编译并上传代码到Pico。上传时需要先按住Pico板上的BOOTSEL按钮再插入USB线待电脑识别出RPI-RP2磁盘后再将编译好的.uf2文件拖入。系统上电代码上传成功后断开Pico的USB线。按照第2.2节的连接图将Pico、Nextion、BME280和外部5V电源全部连接好然后给电源上电。6.2 系统调试方法与工具调试的核心是信息隔离和分段验证。分段验证1Nextion独立测试断开Nextion与Pico的连线将其通过USB转TTL模块连接到电脑。打开串口调试助手如Arduino IDE串口监视器、Putty设置正确的COM口和波特率与Nextion Editor中设置的相同。在发送区手动输入Nextion指令如txtTemp.txt\25.5\然后发送注意在指令后添加三个十六进制字节0xFF 0xFF 0xFF在有些调试助手中可以输入FF FF FF并选择以十六进制发送。观察屏幕上的txtTemp控件是否更新为“25.5”。这可以验证Nextion硬件、固件和通信链路是否正常。分段验证2Pico与传感器测试暂时注释掉Pico代码中所有与SerialNextion通信的部分。在setup()函数中初始化Serial.begin(115200)用于连接电脑调试。在读取BME280数据的代码段后通过Serial.print()将温度、湿度、气压值打印出来。打开Arduino IDE的串口监视器查看数据是否正常输出数值是否合理室温约20-30°C湿度30-70%RH气压约1013hPa。这可以验证Pico、BME280和I2C连接是否正常。分段验证3Pico与Nextion通信测试恢复Pico与Nextion的连线并将Pico通过USB连接到电脑此时Pico由USB供电Nextion由外部5V供电务必共地。在Pico代码中简化发送逻辑例如只每秒发送一次固定的测试指令page 0。同时将电脑的串口调试助手连接到Pico的USB虚拟串口注意不是Nextion的串口监视Pico实际发送出的数据。你应该能看到每秒发送的page 0指令以及三个0xFF。观察Nextion屏幕是否每秒切换回第0页如果不在第0页。这验证了Pico的串口发送和指令格式是否正确。联合调试将以上所有部分整合。在串口监视器中观察Pico发送的完整指令字符串并与Nextion屏幕的实际显示进行对比。如果显示不正确检查指令字符串格式、对象名objname是否与Nextion Editor中完全一致、结束符是否发送。6.3 常见问题与解决方案Nextion屏幕无显示或白屏检查电源这是最常见的问题。确保使用足够功率5V/2A以上的外部电源并且电源线接触良好。用万用表测量Nextion的5V和GND引脚间电压是否在4.8V-5.2V之间。检查固件.tft文件是否成功下载尝试重新编译并下载一次工程文件到Nextion。检查背光有时背光被意外设置为0。尝试发送指令dim100来设置背光为最亮。Pico无法上传程序确保在上传前按住了BOOTSEL按钮再上电电脑识别出RPI-RP2磁盘。尝试更换USB线或USB端口。在Arduino IDE中尝试使用不同的上传方法例如如果使用arduino-pico核心可能有“UF2 Bootloader”和“Picotool”两种方式。传感器读数异常NaN、0、极大/极小值检查I2C连接确认SDA、SCL、3.3V、GND四根线连接正确且牢固。可以用万用表测量BME280模块的VCC电压是否为稳定的3.3V。检查I2C地址BME280的I2C地址通常是0x76或0x77取决于模块上的跳线。在Visuino的BME280组件属性中或手动代码中检查地址设置是否正确。可以在代码中添加I2C扫描程序来确认设备地址。检查Visuino组件配置确认BME280组件的I2C通道设置与硬件连接一致I2C1。Nextion显示数据不更新或乱码检查波特率确保Nextion Editor中设置的波特率与Pico代码中Serial.begin()的波特率完全一致。检查指令结束符确认每条指令后都发送了三个0xFF。这是最容易遗漏的地方。检查对象名确保代码中发送指令的对象名如txtTemp与Nextion Editor中控件的“objname”属性完全一致包括大小写。检查串口线序确认Pico的TX接Nextion的RXPico的RX接Nextion的TX。系统运行不稳定偶尔复位电源干扰电机、继电器等大电流设备与系统共用电源可能导致电压跌落。为气象站系统使用独立的、干净的电源。代码逻辑阻塞避免在loop()中使用长时间的delay()。使用非阻塞的定时方式Visuino的Clock组件就是基于此原理。检查是否有复杂的字符串处理或计算占用了过多时间。串口缓冲区溢出如果Pico向Nextion发送指令过快或者Nextion响应触摸事件过快可能导致串口缓冲区溢出。可以适当降低数据更新频率或在代码中检查串口发送缓冲区是否就绪。通过以上步骤你应该能够构建并调试一个稳定运行的Raspberry Pi Pico Nextion气象站。这个项目的魅力在于其高度的可定制性。掌握了基本框架后你可以轻松地添加更多传感器如光照强度、空气质量传感器设计更复杂的交互界面甚至让Pico连接Wi-Fi将数据上传到物联网平台实现远程监控。Visuino的图形化起点大大降低了门槛而深入底层代码的调整又给予了充分的灵活性这正是嵌入式开发从入门到精进的乐趣所在。
返回列表