327|0

17

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二期】扩展任务 - LTR329+SHT40传感器的使用并上传数据到HA平台 [复制链接]

 

        扩展任务为连接外部的环境光或者温湿度传感器,采集环境数据,然后通过Arduino上传到智能家居HA平台。在完成先前任务的基础上,本任务的难度相对较低。关键在于掌握如何配置环境光传感器LTR-329和温湿度传感器SHT40,并访问它们采集的数据。一旦这些传感器被正确配置,我们便可以利用在进阶任务中学到的代码,将模拟传感器的数据采集和上传流程应用于实际的传感器,从而实现数据的实时上传。

1. 环境光传感器LTR329的使用

        为了实现环境光数据的采集,我们选用了LTR-329环境光传感器。关于该传感器的具体参数和管脚配置,可以参考官方提供的规格书【5591.pdf (digikey.com)】。为了简化连接过程,我们采用了Qwiic缆线连接方式,将传感器与Arduino开发板相连。

        Arduino平台已经提供了LTR-329传感器的库支持。通过Arduino IDE左侧的Library manager搜索“Adafruit LTR329 and LTR303”,即可找到并安装对应的库。

        安装库之后,我们可以在例程中查看库函数的具体使用方法。首先,我们需要在代码中包含Adafruit_LTR329_LTR303.h头文件,并实例化传感器对象ltr。后面是一些配置的代码,比如确认连接、设置传感器增益、采样时间间隔等等,我们都暂时保持默认即可。

        在主循环中,我们通过调用ltr.readBothChannels(visible_plus_ir, infrared)来获取传感器采集的参数。LTR-329传感器提供两个通道的数据:可见光与红外光的叠加值,以及单独的红外光值。

        由于我们使用了Qwiic缆线连接,因此在代码开头需要包含Arduino Wire.h头文件,并在初始化时确认缆线的连接可用。完整的代码如下:

#include "Adafruit_LTR329_LTR303.h"
#include <Wire.h>

Adafruit_LTR329 ltr = Adafruit_LTR329();

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit LTR-329 advanced test");

  if ( ! ltr.begin(&Wire1) ) {
    Serial.println("Couldn't find LTR sensor!");
    while (1) delay(10);
  }
  Serial.println("Found LTR sensor!");

  ltr.setGain(LTR3XX_GAIN_2);
  Serial.print("Gain : ");
  switch (ltr.getGain()) {
    case LTR3XX_GAIN_1: Serial.println(1); break;
    case LTR3XX_GAIN_2: Serial.println(2); break;
    case LTR3XX_GAIN_4: Serial.println(4); break;
    case LTR3XX_GAIN_8: Serial.println(8); break;
    case LTR3XX_GAIN_48: Serial.println(48); break;
    case LTR3XX_GAIN_96: Serial.println(96); break;
  }

  ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);
  Serial.print("Integration Time (ms): ");
  switch (ltr.getIntegrationTime()) {
    case LTR3XX_INTEGTIME_50: Serial.println(50); break;
    case LTR3XX_INTEGTIME_100: Serial.println(100); break;
    case LTR3XX_INTEGTIME_150: Serial.println(150); break;
    case LTR3XX_INTEGTIME_200: Serial.println(200); break;
    case LTR3XX_INTEGTIME_250: Serial.println(250); break;
    case LTR3XX_INTEGTIME_300: Serial.println(300); break;
    case LTR3XX_INTEGTIME_350: Serial.println(350); break;
    case LTR3XX_INTEGTIME_400: Serial.println(400); break;
  }

  ltr.setMeasurementRate(LTR3XX_MEASRATE_200);
  Serial.print("Measurement Rate (ms): ");
  switch (ltr.getMeasurementRate()) {
    case LTR3XX_MEASRATE_50: Serial.println(50); break;
    case LTR3XX_MEASRATE_100: Serial.println(100); break;
    case LTR3XX_MEASRATE_200: Serial.println(200); break;
    case LTR3XX_MEASRATE_500: Serial.println(500); break;
    case LTR3XX_MEASRATE_1000: Serial.println(1000); break;
    case LTR3XX_MEASRATE_2000: Serial.println(2000); break;
  }
}

void loop() {
  bool valid;
  uint16_t visible_plus_ir, infrared;

  if (ltr.newDataAvailable()) {
    valid = ltr.readBothChannels(visible_plus_ir, infrared);
    if (valid) {
      Serial.print("CH0 Visible + IR: ");
      Serial.print(visible_plus_ir);
      Serial.print("\t\tCH1 Infrared: ");
      Serial.println(infrared);
    }
  }

  delay(100);
}

        运行上述代码后,我们可以通过串口监视器观察到光照强度信息的输出。随着环境光线的变化,例如手动遮挡光源,示数也会相应变化。

        动态的数据接收过程请参考随附的视频。

2. 温湿度传感器SHT40的使用

        有了环境光传感器的经验,温湿度传感器只需要如法炮制即可。与环境光传感器类似,我们可以通过Arduino的库来简化集成过程。首先,通过Arduino IDE的Library manager搜索并安装“Adafruit SHT4X”库。这个库为SHT40传感器提供了封装好的接口。

        打开其中的例程,其实现的过程和环境光传感器是一样的。我们可以在代码中包含Adafruit_SHT4X.h头文件,并实例化一个SHT40传感器对象sht4。

        主循环部分,主要是通过sht4.getEvent(&humidity, &temp)来获取温湿度的读数,然后通过串口分别发送。同样,我们因为通过Qwiic缆线来连接开发板和传感器,包含对应的头文件并检查确认其连接即可,具体的代码如下:

#include "Adafruit_SHT4x.h"
#include <Wire.h>

Adafruit_SHT4x sht4 = Adafruit_SHT4x();

void setup() {
  Serial.begin(9600);

  while (!Serial)
    delay(10);     // will pause Zero, Leonardo, etc until serial console opens

  Serial.println("Adafruit SHT4x test");
  if (! sht4.begin(&Wire1)) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  // You can have 3 different precisions, higher precision takes longer
  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION:
       Serial.println("High precision");
       break;
     case SHT4X_MED_PRECISION:
       Serial.println("Med precision");
       break;
     case SHT4X_LOW_PRECISION:
       Serial.println("Low precision");
       break;
  }

  // You can have 6 different heater settings
  // higher heat and longer times uses more power
  // and reads will take longer too!
  sht4.setHeater(SHT4X_NO_HEATER);
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER:
       Serial.println("No heater");
       break;
     case SHT4X_HIGH_HEATER_1S:
       Serial.println("High heat for 1 second");
       break;
     case SHT4X_HIGH_HEATER_100MS:
       Serial.println("High heat for 0.1 second");
       break;
     case SHT4X_MED_HEATER_1S:
       Serial.println("Medium heat for 1 second");
       break;
     case SHT4X_MED_HEATER_100MS:
       Serial.println("Medium heat for 0.1 second");
       break;
     case SHT4X_LOW_HEATER_1S:
       Serial.println("Low heat for 1 second");
       break;
     case SHT4X_LOW_HEATER_100MS:
       Serial.println("Low heat for 0.1 second");
       break;
  }
 
}


void loop() {
  sensors_event_t humidity, temp;
 
  uint32_t timestamp = millis();
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  timestamp = millis() - timestamp;

  Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
  Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");

  Serial.print("Read duration (ms): ");
  Serial.println(timestamp);

  delay(1000);
}

        运行上述代码后,我们可以通过串口监视器观察到温湿度信息的输出。随着环境温湿度的变化,示数也会相应变化。温度传感器的结果将和扩展任务一同展示。动态的数据接收过程请参考随附的视频。

3. 扩展任务(必做):通过外部传感器上传信息到HA,并通过HA面板显示数据

        在成功集成环境光传感器LTR-329和温湿度传感器SHT40之后,我们的目标是将这些传感器的数据上传至Home Assistant (HA) 平台,并在HA界面上显示这些数据。由于我们只有一条Qwiic缆线,我们将以温湿度传感器SHT40为例进行演示。

        我们删除了上个任务中打印wifi信息的相关函数,因为我们暂时不需要显示这些,来精简一下代码。我们包含了所有必要的头文件,并开始配置HA平台。我们将新添加的传感器实例化为模拟信号传感器,具体代码如下:

HASensorNumber analogSensor("AnalogInput", HASensorNumber::PrecisionP1);
HASensorNumber uptimeSensor("Uptime");
HASensorNumber TempSensor("Temperature", HASensorNumber::PrecisionP2);
HASensorNumber HumidSensor("Humid", HASensorNumber::PrecisionP3);
//HASensorNumber LightSensor("Light", HASensorNumber::PrecisionP2);

HAButton buttonA("myButtonA");
HAButton buttonB("myButtonB");

        然后我们在初始化完wifi模块和MQTT的连接以后,具体方法参考上一则报告【【Follow me第二期】进阶任务 - WiFi+MQTT协议连接智能家居HA平台 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)】,给HA界面上各传感器的显示增加更多细节,包括进行命名的区分以及增加具体的单位,代码如下:

  analogSensor.setName("Analog voltage");
  analogSensor.setUnitOfMeasurement("V");
  uptimeSensor.setName("Update Time");
  uptimeSensor.setUnitOfMeasurement("s");
  TempSensor.setName("Temperature");
  TempSensor.setUnitOfMeasurement("degrees C");
  HumidSensor.setName("Humidity");
  HumidSensor.setUnitOfMeasurement("% rH");
  //LightSensor.setUnitOfMeasurement("lkx");

        最后初始化SHT4X模块,我们把全部配置参数都设成默认,然后合并成一个SHT40_init()函数。

        在主循环中,我们直接使用例程中的温湿度数据获取的函数,然后通过Sensor.setValue()函数显示到HA界面上。具体代码如下:

    sensors_event_t humidity, temp;
    sht4.getEvent(&humidity, &temp);
    Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println("degrees C");
    Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
    TempSensor.setValue(temp.temperature);
    HumidSensor.setValue(humidity.relative_humidity);

        最后完整的代码如下:

#include <WiFiS3.h>
#include <ArduinoHA.h>
#include <Wire.h>

#include "arduino_secrets.h"
#include "analogWave.h"

#include "Adafruit_SHT4x.h"
#include "Adafruit_LTR329_LTR303.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)
int status = WL_IDLE_STATUS;     // the WiFi radio's status
unsigned long lastUpdateAt = 0;
int freq = 1;

WiFiClient client;
HADevice device(MQTT_CLIENT_ID);
HAMqtt mqtt(client, device);

HASensorNumber analogSensor("AnalogInput", HASensorNumber::PrecisionP1);
HASensorNumber uptimeSensor("Uptime");
HASensorNumber TempSensor("Temperature", HASensorNumber::PrecisionP2);
HASensorNumber HumidSensor("Humid", HASensorNumber::PrecisionP3);
//HASensorNumber LightSensor("Light", HASensorNumber::PrecisionP2);

HAButton buttonA("myButtonA");
HAButton buttonB("myButtonB");

analogWave wave(DAC);
Adafruit_SHT4x sht4 = Adafruit_SHT4x();
Adafruit_LTR329 ltr = Adafruit_LTR329();

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to WiFi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);

    // wait 10 seconds for connection:
    delay(10000);
  }

  // you're connected now, so print out the data:
  Serial.print("You're connected to the network");

  Serial.println("\nStart connecting to MQTT server");
  if (!mqtt.begin(MQTT_SERVER, MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD)){
    Serial.print("Connection falied");
    Serial.print(mqtt.getState());
    Serial.println("Try again in 5 seconds");
    delay(5000);
  }
  wave.sine(freq);
  wave.amplitude(0.5);

  analogReadResolution(14);

  device.setName("Arduino");
  device.setSoftwareVersion("1.0.0");
  buttonA.setIcon("mdi:fire");
  buttonA.setName("Click me A");
  buttonB.setIcon("mdi:home");
  buttonB.setName("Click me B");

  analogSensor.setName("Analog voltage");
  analogSensor.setUnitOfMeasurement("V");
  uptimeSensor.setName("Update Time");
  uptimeSensor.setUnitOfMeasurement("s");
  TempSensor.setName("Temperature");
  TempSensor.setUnitOfMeasurement("degrees C");
  HumidSensor.setName("Humidity");
  HumidSensor.setUnitOfMeasurement("% rH");
  //LightSensor.setUnitOfMeasurement("lkx");

  SHT40_init();
  //LTR329_init();
}

void loop() {
  // check the network connection once every 10 seconds:
  mqtt.loop();
  if ((millis() - lastUpdateAt) > 1000) { // 1000ms debounce time
    uint16_t reading = analogRead(A0);
    float voltage = reading * 5.f / 16383.f; // 0.0V - 5.0V
    Serial.print("Volt:");
    Serial.println(voltage);
    analogSensor.setValue(voltage);

    unsigned long uptimeValue = millis() / 1000;
    Serial.print("Uptime:");
    Serial.println(uptimeValue);
    uptimeSensor.setValue(uptimeValue);

    sensors_event_t humidity, temp;
    sht4.getEvent(&humidity, &temp);
    Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println("degrees C");
    Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
    TempSensor.setValue(temp.temperature);
    HumidSensor.setValue(humidity.relative_humidity);

    // bool valid;
    // uint16_t visible_plus_ir, infrared;
    // if (ltr.newDataAvailable()) {
    //   valid = ltr.readBothChannels(visible_plus_ir, infrared);
    //   if (valid) {
    //     Serial.print("CH0 Visible + IR: ");
    //     Serial.print(visible_plus_ir);
    //     Serial.print("\t\tCH1 Infrared: ");
    //     Serial.println(infrared);
    //   }
    //   LightSensor.setValue(visible_plus_ir);
    // }
 
    lastUpdateAt = millis();
  }
}

void SHT40_init() {
  Serial.println("Adafruit SHT4x test");

  if (! sht4.begin(&Wire1)) {
    Serial.println("Couldn't find SHT4x");
    while (1) delay(1);
  }
  Serial.println("Found SHT4x sensor");
  Serial.print("Serial number 0x");
  Serial.println(sht4.readSerial(), HEX);

  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION:
       Serial.println("High precision");
       break;
     case SHT4X_MED_PRECISION:
       Serial.println("Med precision");
       break;
     case SHT4X_LOW_PRECISION:
       Serial.println("Low precision");
       break;
  }

  sht4.setHeater(SHT4X_NO_HEATER);
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER:
       Serial.println("No heater");
       break;
     case SHT4X_HIGH_HEATER_1S:
       Serial.println("High heat for 1 second");
       break;
     case SHT4X_HIGH_HEATER_100MS:
       Serial.println("High heat for 0.1 second");
       break;
     case SHT4X_MED_HEATER_1S:
       Serial.println("Medium heat for 1 second");
       break;
     case SHT4X_MED_HEATER_100MS:
       Serial.println("Medium heat for 0.1 second");
       break;
     case SHT4X_LOW_HEATER_1S:
       Serial.println("Low heat for 1 second");
       break;
     case SHT4X_LOW_HEATER_100MS:
       Serial.println("Low heat for 0.1 second");
       break;
  }
}

void LTR329_init() {
  Serial.println("Adafruit LTR-329 advanced test");

  if ( ! ltr.begin(&Wire1) ) {
    Serial.println("Couldn't find LTR sensor!");
    while (1) delay(10);
  }
  Serial.println("Found LTR sensor!");

  ltr.setGain(LTR3XX_GAIN_2);
  Serial.print("Gain : ");
  switch (ltr.getGain()) {
    case LTR3XX_GAIN_1: Serial.println(1); break;
    case LTR3XX_GAIN_2: Serial.println(2); break;
    case LTR3XX_GAIN_4: Serial.println(4); break;
    case LTR3XX_GAIN_8: Serial.println(8); break;
    case LTR3XX_GAIN_48: Serial.println(48); break;
    case LTR3XX_GAIN_96: Serial.println(96); break;
  }

  ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);
  Serial.print("Integration Time (ms): ");
  switch (ltr.getIntegrationTime()) {
    case LTR3XX_INTEGTIME_50: Serial.println(50); break;
    case LTR3XX_INTEGTIME_100: Serial.println(100); break;
    case LTR3XX_INTEGTIME_150: Serial.println(150); break;
    case LTR3XX_INTEGTIME_200: Serial.println(200); break;
    case LTR3XX_INTEGTIME_250: Serial.println(250); break;
    case LTR3XX_INTEGTIME_300: Serial.println(300); break;
    case LTR3XX_INTEGTIME_350: Serial.println(350); break;
    case LTR3XX_INTEGTIME_400: Serial.println(400); break;
  }

  ltr.setMeasurementRate(LTR3XX_MEASRATE_200);
  Serial.print("Measurement Rate (ms): ");
  switch (ltr.getMeasurementRate()) {
    case LTR3XX_MEASRATE_50: Serial.println(50); break;
    case LTR3XX_MEASRATE_100: Serial.println(100); break;
    case LTR3XX_MEASRATE_200: Serial.println(200); break;
    case LTR3XX_MEASRATE_500: Serial.println(500); break;
    case LTR3XX_MEASRATE_1000: Serial.println(1000); break;
    case LTR3XX_MEASRATE_2000: Serial.println(2000); break;
  }
}

        完成代码编写后,我们启动Docker Engine,打开HA和EMQX平台的容器,并将代码烧录到Arduino。测试结果显示,我们可以看到网络连接和MQTT连接的信息,并确认了SHT40传感器的连接。传感器开始通过串口向上位机发送温湿度信息(截图时我已经把连接线断开了,所以显示了未连接)。

        当我们打开HA平台时,可以看到设备增加了新的传感器,并且更新了数据单位信息,数据也会随时间不断更新。动态的展示请参考随附的视频。

        至此我们完成了本次Follow me活动的全部任务,汇总帖和视频正在全力整合中。

        

LTR+SHT传感器使用+上传HA平台

点赞 关注
个人签名

就是个臭打游戏

 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表