《ESP32 物联网全栈实战-10》微信小程序入门

0 阅读3分钟

第 10 篇:微信小程序入门——3 小时写出第一个 IoT 小程序

前 9 篇都在搞硬件和云端。这篇开始写前端——用微信小程序把数据展示到手机上。不需要学 React/Vue,小程序框架自带一切。


1. 环境搭建

Step 1: 下载微信开发者工具
        https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html

Step 2: 注册小程序
        https://mp.weixin.qq.com → 注册 → 个人主体即可
        拿到 AppID

Step 3: 新建项目
        打开开发者工具 → 新建 → 填入 AppID
        → 选"不使用云服务" → 选"JavaScript 基础模板"

目录结构:

miniprogram/
├── app.js          # 小程序入口
├── app.json        # 全局配置(页面路径、窗口样式)
├── app.wxss        # 全局样式
├── pages/
│   └── index/
│       ├── index.wxml   # 页面结构 (HTML 类似物)
│       ├── index.wxss   # 页面样式 (CSS 类似物)
│       ├── index.js     # 页面逻辑
│       └── index.json   # 页面配置
└── project.config.json

2. MQTT 在小程序里怎么连?

小程序不能直接用 TCP 连 MQTT——它只支持 WebSocket。所以 EMQX 的 WebSocket 端口(8083/8084)就派上用场了。

小程序 ←→ WebSocket(wss://) ←→ EMQX 8084 ←→ MQTT 1883 ←→ ESP32

在小程序里引用 mqtt.js(支持浏览器/WebSocket 的 MQTT 库):

# 在项目根目录
npm init -y
npm install mqtt

然后在开发者工具里:工具 → 构建 npm


3. 主页面代码

pages/index/index.wxml

<!-- 温湿度显示 -->
<view class="container">
  <view class="card">
    <text class="title">客厅环境</text>

    <view class="data-row">
      <view class="data-item">
        <text class="label">温度</text>
        <text class="value temp">{{temperature}}°C</text>
      </view>
      <view class="data-item">
        <text class="label">湿度</text>
        <text class="value humi">{{humidity}}%</text>
      </view>
    </view>

    <view class="status">
      <text class="{{connected ? 'online' : 'offline'}}">
        {{connected ? '● 在线' : '○ 离线'}}
      </text>
    </view>
  </view>

  <!-- 开关控制 -->
  <view class="card">
    <text class="title">设备控制</text>
    <switch checked="{{relayOn}}" bindchange="toggleRelay">
      插座开关
    </switch>
  </view>
</view>

pages/index/index.wxss

.container { padding: 20rpx; background: #f5f5f5; min-height: 100vh; }
.card { background: #fff; border-radius: 16rpx; padding: 30rpx; margin-bottom: 20rpx; }
.title { font-size: 32rpx; font-weight: bold; color: #333; display: block; margin-bottom: 20rpx; }
.data-row { display: flex; justify-content: space-around; }
.data-item { text-align: center; }
.label { font-size: 24rpx; color: #999; display: block; }
.value { font-size: 64rpx; font-weight: bold; margin-top: 10rpx; display: block; }
.temp { color: #ff6b6b; }
.humi { color: #48dbfb; }
.online { color: #2ecc71; font-size: 24rpx; }
.offline { color: #e74c3c; font-size: 24rpx; }
switch { margin-top: 20rpx; }

pages/index/index.js

const mqtt = require('mqtt');

Page({
  data: {
    temperature: '--',
    humidity: '--',
    relayOn: false,
    connected: false,
  },

  onLoad() {
    this.connectMQTT();
  },

  connectMQTT() {
    // EMQX WebSocket 地址(小程序必须用 wss://)
    const options = {
      clientId: 'wx_miniprogram_' + Math.random().toString(16).slice(2, 8),
      username: 'wx_user',
      password: 'public',
      clean: true,
    };

    this.client = mqtt.connect('wss://your-broker.com:8084/mqtt', options);

    this.client.on('connect', () => {
      console.log('MQTT 已连接');
      this.setData({ connected: true });

      // 订阅传感器数据
      this.client.subscribe('sensor/livingroom', { qos: 1 });
    });

    this.client.on('message', (topic, payload) => {
      const data = JSON.parse(payload.toString());
      console.log('收到数据:', data);

      this.setData({
        temperature: data.temp.toFixed(1),
        humidity: data.humi.toFixed(1),
      });
    });

    this.client.on('error', (err) => {
      console.error('MQTT 错误:', err);
      this.setData({ connected: false });
    });

    this.client.on('close', () => {
      this.setData({ connected: false });
    });
  },

  // 开关控制
  toggleRelay(e) {
    const on = e.detail.value;
    this.client.publish('device/relay/cmd', on ? 'ON' : 'OFF', { qos: 1 });
    this.setData({ relayOn: on });
  },

  onUnload() {
    if (this.client) {
      this.client.end();
    }
  },
});

4. app.json 配置

{
  "pages": [
    "pages/index/index"
  ],
  "window": {
    "navigationBarTitleText": "IoT 温湿度计",
    "navigationBarBackgroundColor": "#2c3e50",
    "navigationBarTextStyle": "white"
  },
  "sitemapLocation": "sitemap.json"
}

重要:小程序必须配置服务器域名白名单,否则连不上。

在微信公众平台 → 开发 → 开发设置 → 服务器域名 → 添加 socket 合法域名:

wss://your-broker.com

本地开发时可以勾选"不校验合法域名"跳过。


5. 测试

1. ESP32 上电 → 每 5 秒发一条 {"temp":25.6,"humi":58.3}
2. 开发者工具编译 → 预览
3. 手机上看到温度 25.6°C、湿度 58.3%
4. 点击开关 → ESP32 控制继电器吸合/断开

从零到能看到数据,正常 2-3 小时。 下一篇我们加上历史图表和告警推送。


下一篇:小程序进阶——ECharts 温度曲线 + 告警推送