M-Design设计竞赛-ESP32-S3阿里云温湿度光照系统
该项目使用了Android软件,arduino软件,C语言,实现了ESP32­S3­WROOM­1­N16R8温湿度光照的设计,它的主要功能为:使用NSHT30,BH1750获取周围温度和光照,通过云平台进行显示。
标签
PCB
Arduino
ESP32
C语言
阿里云
NSHT30
BH1750
Android
冲向天空的猪
更新2025-04-01
21

M-Design设计竞赛-ESP32-S3阿里云温湿度光照系统

项目背景

本次我选择的任务是方向三:无线通信、物联网,我选择这个项目来作为实现方向。

在日常生活中,我们需要检测周围的环境情况,在电子世界中,环境的数据就是通过一个一个传感器来获取的,这里通过传感器来搭建属于我们自己的传感器系统,想做一个小巧又可以随时安放的开发板,可以随时检测当前环境的情况,也希望代码量少一点,方便更多人能及时上手。

项目功能

  1. 环境监测
    • 温湿度检测:通过NSHT30传感器实时检测环境中的温度和湿度,并将数据发送到阿里云平台。
    • 光照强度检测:使用BH1750传感器测量环境光照强度,并将数据上传至云端。
  2. 无线通信与物联网连接
    • 利用ESP32-S3-WROOM-1-N16R8作为主控芯片,支持Wi-Fi连接,确保设备可以稳定地与阿里云IoT平台进行通信。
    • 实现了MQTT协议的集成,使得设备能够订阅和发布消息,便于远程监控和控制。
  3. 智能响应机制
    • 根据光照强度自动调整LED状态(开/关),当环境光低于一定阈值时开启辅助照明。
    • 支持接收来自阿里云平台的指令,如手动调节LED状态或设置温度报警阈值等。
  4. 移动端应用
    • 开发了Android应用程序,用于展示温湿度、光照强度等环境参数的实时数据。
    • 提供了简洁直观的用户界面(UI),让用户可以方便地查看环境信息,并能接收到来自设备的状态更新通知。


项目材料

主控芯片:ESP32­S3­WROOM­1­N16R8

温湿度芯片:NSHT30

光照传感器:BH1750

串口芯片:CH340N

使用平台:Arduino和阿里云的云平台和Android

流程图

硬件部分

原理图

PCB

焊接完成图

软件部分

Arduino

这次的代码只是裸机实现,后期可以修改为操作系统或者时间片轮询

引入的头文件

#include <Wire.h>
#include <DHT11.h>
#include <BH1750.h>
#include "SHTSensor.h"
#include <WiFi.h>         // 引入 WiFi 模块
#include <AliyunIoTSDK.h> // 引入阿里云 IoT SDK

这里的SDK需要做一些修改与我们的阿里云进行json解析适配

在AliyunIoTSDK.cpp,替换这个函数进行解析

static void parmPass(JsonVariant parm)
{
  // 遍历回调函数数组
  for (int i = 0; i < DATA_CALLBACK_SIZE; i++)
  {
      if (poniter_array[i].key) // 如果当前回调数组元素的 key 不为空
      {
          // 检查传入的 JSON 中是否包含 "items" 部分,并且检查 "items" 中是否包含要查找的 key
          bool hasKey = parm["items"].containsKey(poniter_array[i].key);
          if (hasKey) // 如果存在该 key
          {
              // 调用与该 key 绑定的回调函数,传递 items 部分的数据
              poniter_array[i].fp(parm["items"]);
          }
      }
  }
}

初始化代码

void setup() {
Serial.begin(115200);
Wire.begin(1, 2);
Wire1.begin(21, 20);
sht.init(Wire);
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); // 设置传感器精度
lightMeter.begin(BH1750::CONTINUOUS_HIGH_RES_MODE,0x23,&Wire1);
wifiInit(WIFI_SSID, WIFI_PASSWD);
AliyunIoTSDK::begin(espClient, PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, REGION_ID);
if(AliyunIoTSDK::subscribe(topic_Set,0))Serial.println("订阅成功");
pinMode(5,OUTPUT);
pinMode(4,OUTPUT);
}

主循环

void loop() {
// 读取SHT传感器的数据
if (sht.readSample()) {
  humi = sht.getHumidity();
  temp = sht.getTemperature();
}
mlux = lightMeter.readLightLevel();

if(mlux<10)
{
  light = 1;
}else{
  light = 0;
}
digitalWrite(4, light);
AliyunIoTSDK::bindData("templight", handleItemData);
AliyunIoTSDK::send("templight", temp1);
AliyunIoTSDK::send("light", light);
AliyunIoTSDK::send("mlux", mlux);
AliyunIoTSDK::send("EnvironmentTemperature", temp);
AliyunIoTSDK::send("EnvironmentHumidity", humi);
AliyunIoTSDK::loop();
// 等待1秒后继续下一次读取
delay(1000);
}
// WiFi连接初始化
void wifiInit(const char *ssid, const char *passphrase) {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, passphrase);
while (WiFi.status() != WL_CONNECTED) {
  delay(1000);
  Serial.println("WiFi not connected");
}
Serial.println("Connected to AP");
}

void handleItemData(JsonVariant items) {
  // 获取 "templight" 项的数据
  int value = items["templight"]["value"];
  if (value == 1)
  {
    temp1 = 1;
    digitalWrite(5,LOW);
      // 启动设备
  } else{
    temp1 = 0;
    digitalWrite(5,HIGH);
  }
}

阿里云部分

这里需要我们创建一个阿里云,物联网平台的账号,创建我们的产品,设备,配置好云产品转流。

Android部分

消息解析显示

            public void handleMessage(Message msg) {
              super.handleMessage(msg);
              switch (msg.what) {
                  case 1: //开机校验更新回传
                      break;
                  case 2: // 反馈回传
                      break;
                  case 3: //MQTT 收到消息回传   UTF8Buffer msg=new UTF8Buffer(object.toString());
                      String message = msg.obj.toString();
                      Log.d("nicecode", "handleMessage: "+ message);
                      try {
                          JSONObject jsonObjectALL = null;
                          jsonObjectALL = new JSONObject(message);
                          JSONObject items = jsonObjectALL.getJSONObject("items");

                          JSONObject obj_temp = items.getJSONObject("EnvironmentTemperature");
                          JSONObject obj_humi = items.getJSONObject("EnvironmentHumidity");
                          JSONObject obj_light = items.getJSONObject("mlux");
                          JSONObject obj_templight = items.getJSONObject("templight");
                          temp = obj_temp.getInt("value");
                          humi = obj_humi.getInt("value");
                          light = obj_light.getInt("value");

                          Temp.setText(temp + "");
                          Humi.setText(humi + "");
                          Light.setText(light + "");
                          Log.d("nicecode", "temp: "+ temp);
                          Log.d("nicecode", "humi: "+ humi);
                          Log.d("nicecode", "light: "+ light);
                      } catch (JSONException e) {
                          e.printStackTrace();
                          break;
                      }
                  case 30: //连接失败
//                       Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show();
                      connect.setText("服务器连接失败");
                      break;
                  case 31:   //连接成功
//                       Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
                      connect.setText("服务器连接成功");
                      try {
                          client.subscribe(sub_topic, 1);
                      } catch (MqttException e) {
                          e.printStackTrace();
                      }
                      break;
                  default:
                      break;
              }
          }
      };
  }

MQTT初始化

private void mqtt_init() {
  try {

      String clientId = "k1pkwhcnphr.Android";
      Map<String, String> params = new HashMap<String, String>(16);
      params.put("productKey", productKey);
      params.put("deviceName", deviceName);
      params.put("clientId", clientId);
      String timestamp = String.valueOf(System.currentTimeMillis());
      params.put("timestamp", timestamp);
      // cn-shanghai
      String host_url ="tcp://"+ productKey + ".iot-as-mqtt.cn-shanghai.aliyuncs.com:1883";
      String client_id = clientId + "|securemode=2,signmethod=hmacsha1,timestamp=" + timestamp + "|";
      String user_name = deviceName + "&" + productKey;
      String password = com.example.iotandroid.AliyunIoTSignUtil.sign(params, deviceSecret, "hmacsha1");

      //host为主机名,test为clientid即连接MQTT的客户端ID,一般以客户端唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存
      System.out.println(">>>" + host_url);
      System.out.println(">>>" + client_id);

      //connectMqtt(targetServer, mqttclientId, mqttUsername, mqttPassword);

      client = new MqttClient(host_url, client_id, new MemoryPersistence());
      //MQTT的连接设置
      options = new MqttConnectOptions();
      //设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接
      options.setCleanSession(false);
      //设置连接的用户名
      options.setUserName(user_name);
      //设置连接的密码
      options.setPassword(password.toCharArray());
      // 设置超时时间 单位为秒
      options.setConnectionTimeout(10);
      // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制
      options.setKeepAliveInterval(60);
      //设置回调
      client.setCallback(new MqttCallback() {
          @Override
          public void connectionLost(Throwable cause) {
              //连接丢失后,一般在这里面进行重连
              System.out.println("connectionLost----------");
          }

          @Override
          public void deliveryComplete(IMqttDeliveryToken token) {
              //publish后会执行到这里
              System.out.println("deliveryComplete---------" + token.isComplete());
          }

          @Override
          public void messageArrived(String topicName, MqttMessage message)
                  throws Exception {
              //subscribe后得到的消息会执行到这里面
              System.out.println("messageArrived----------");
              Message msg = new Message();
              //封装message包
              msg.what = 3;   //收到消息标志位
              msg.obj =message.toString();
              //发送messge到handler
              handler.sendMessage(msg);   // hander 回传
          }
      });
  } catch (Exception e) {
      e.printStackTrace();
  }
}

显示界面

效果展示

手机端展示

实物效果展示

总结与收获

感谢M-Design设计竞赛提供的活动资金,可以为自己设计资源提供了很大帮助,也通过这次的活动也了解到自己从硬件设计到软件开发,最后到实现也有所进展。后面可以改进的地方有很多,如温度传感器不能距离MCU太近,在连接网络MCU发热严重会影响采集的温度效果,适当也可以加算法,对我们的温湿度光照进行滤波处理,让我们的采集到的数据更加准确,可以优化一下UI,将arduino代码从裸机移植到操作系统当中。

附件下载
安卓+原理图+代码.7z
团队介绍
热爱电子的学生
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号