[作品提交] 【Follow me第二季第2期】任务汇总

qzc飘曳   2024-10-10 19:14 楼主

        本次活动已经接近尾声了,我们一起通过学习实现了物联网的基本流程,本次活动是DigiKey联合EEWorld发起的Follow me活动第二季的第二期,精选高可玩性与教育价值的开发板及仪器套装,携手共赴实践盛宴。

一、物料展示

        主控板卡Arduino UNO R4 WiFi 

image-20241010190627-1.png  

        Arduino UNO R4 WiFi 是一款基于32位Arm® Cortex®-M4 Renesas RA4M1微控制器,具有用于 Wi-Fi® 和蓝牙连接的ESP32模块,具备强大的计算能力和多种连接功能。该板SRAM 32kB,闪存256kB,时钟频率为48MHz,USB端口升级为USB-C,并且最大电源供应电压增加到24V。该板提供了一个CAN总线,允许用户通过连接多个扩展板来最小化布线并执行不同的任务。板载的Qwiic 连接器可以方便地创建即插即用风格的项目。

        传感器一:LTR-329光传感器扩展板

image-20241010190627-2.png  

        LTR-329ALS-01是一款低压I2C数字光传感器[ALS],采用低成本的微细片状无铅表面贴装封装。该传感器将光强度转换为能够直接I2C接口的数字输出信号。它在0.01勒克斯到64k勒克斯的宽动态范围内提供线性响应,非常适合高环境亮度下的应用。共有六种增益设置(1X, 2X, 4X, 8X, 48X和96X)可供用户配置。

        传感器二:SHT40温湿度传感器扩展板

image-20241010190627-3.png  

        SHT4x是一个数字传感器平台,用于测量不同精度等级的相对湿度和温度。其I2C接口提供多个预配置的I2C地址,同时保持超低功耗预算(0.4 μW)。电源修剪的内部加热器可以在三个加热级别使用,从而使传感器在苛刻的环境中运行。四针双平面无引线封装适用于表面贴装技术(SMT)加工,包括可选的封装上专利PTFE[1]膜或可拆卸的保护罩。根据ISO17025的传感器特定校准证书,可通过唯一序列号识别。

二、整体思路

        本次的两个传感器板都是通过Qwiic 连接器进行沟通的,不过本次采购并没有采购连接线,超限了,不过多来了一个传感器还是很超值的,连接线就自己做了,通过连连串的方式进行连接,实现传感器和主控板的连接,然后开发板上有wifi模块可以实现无线连接,通过MQTT协议实现和HA平台的通信。

三、任务实现

        这一部分主要写在了各个分贴中了,进行一下介绍和传送.

        开箱:

        【Follow me第二季第2期】开箱 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        配置开发环境:

        【Follow me第二季第2期】配置开发环境 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        入门任务:

        入门任务是搭建环境并开启第一步Blink / 串口打印Hello EEWorld!,环境我们在上一个章节已经搭建好了,这里主要是实现LED的翻转了和串口打印,这两个小功能也是我们熟悉新的开发板的开始,实际上就setup()和loop()两个函数,一个执行一次相当于初始化,一个是循环操作的。arduino方便的地方在于,很多操作都已经封装好,直接使用就可以,代码如下:

void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
  delay(1000); // wait for a second
  digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
  delay(1000); // wait for a second
  Serial.println("Hello EEWorld!");
}

        启动GPIO和串口只用了两个函数,然后就是通过延时的方法进行循环控制实现LED的翻转:

image.png  

        并在执行一次后串口打印一次"Hello EEWorld!":

image.png          详细内容可以进入分贴查看:

        【Follow me第二季第2期】任务一 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        基础任务:

        基础任务是驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线,实际上这个可以划分成若干个任务.96个LED的组成的矩阵,这个实际上是个单独实现的控制,每一个LED对应一位,为此我们需要设计几个字符进行循环显示并在loop()中定时循环现实:

        循环显示代码如下:

ArduinoLEDMatrix matrix;
void setup() {
 // put your setup code here, to run once:
 matrix.begin();
}
void loop() {
 // put your main code here, to run repeatedly:
 matrix.loadFrame(show_1);
 delay(500); // wait for a second
 matrix.loadFrame(show_2);
 delay(500); // wait for a second
 matrix.loadFrame(show_3);
 delay(500); // wait for a second
 matrix.loadFrame(show_4);
 delay(500); // wait for a second
 matrix.loadFrame(show_E);
 delay(400); // wait for a second
 matrix.clear();
 delay(100); // wait for a second
 matrix.loadFrame(show_E);
 delay(500); // wait for a second
 matrix.loadFrame(show_W);
 delay(1000); // wait for a second
}

        效果如下:

image.png  

        视频效果可以看最后的效果视频中的任务二-LED整列显示部分;

        其他部分是对ADC、DAC、放大等部分的操作,并且用到了我们任务一中使用的串口打印,这个时候需要一些外部连接:

image.png  

        放大器的外部配置更加重要,硬件的基本配置通过正向放大器的方式进行,ADC连接到OPAMP的正输入,也就是A1,A2的电压就虚短等于A1处电压,然后通过两个等大的电阻进行2被放大,A2到地连接一个,到输出连接一个,这样A3处的输出就是A1处的2倍了,通过ADC采集进行串口输出绘图。

        部分代码如下:

void setup() {
  // put your setup code here, to run once:
  pinMode(A0, OUTPUT);
  pinMode(A5, INPUT);
  analogReadResolution(12);// 设置 ADC 分辨率为 12 位
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(115200);
  matrix.begin();
  matrix.loadFrame(show_4);
}
void loop() {
  // put your main code here, to run repeatedly:
  for(int i = 0; i < 360; i++){
    float rad = i * PI / 180.0;
    int outputValue = (127 + 127 * sin(rad))/5;// 生成正弦波信号
    analogWrite(A0, outputValue);// 输出到 DAC
    // 控制输出频率
    delay(100);
    int value = analogRead(A5);// 读取 ADC 值
    Serial.println(value);
  }
}

       软件流程如下:

image.png  

        部分效果如下:

image.png          

        显示是通过arduino自带的串口工具查看的,由于只能显示50个数值,所以只能看到正弦波的一部分,详细的可以查看视频讲解中任务二-ADC采集部分;

          详细内容可以进入分贴查看:

        【Follow me第二季第2期】任务二 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        进阶任务:

        通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)。这里主要就包含两部分了,一个是wifi的使用,还有一个是智能家居平台HA(HomeAssistant)的建立,当然了有很多坛友可能这一部分都已经创建了,毕竟玩物联网或者无线的很多都接触过,这个可以参照官方文件选择一个适合自己的方式创建就可以,之后通过MQTT模拟器进行实体的创建,之后我们就可以直接通过MQTT协议进行发送数据了,这一部分我们还可以不通过连接任何传感器,只是随机发送数据进行测试,只是验证MQTT协议和智能家居平台HA是否导通:

#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
char ssid[] = "xxx";        
char pass[] = "xxx";  
const char broker[] = "192.168.72.127";
int        port     = 1883;
const char state_topic2[]  = "homeassistant/sensor/sensorsth40/state";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
JSONVar dataObj;
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println("HA com test");
  Serial.println("connect to WPA SSID: ");
  Serial.println(ssid);
  // attempt to connect to WiFi network:
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    Serial.print("......");
    delay(5000);
  }
  Serial.print("connect wifi succeed!");
  Serial.println();
  Serial.println(WiFi.localIP());
  // You can provide a unique client ID, if not set the library uses Arduino-millis()
  // Each client must have a unique client ID
   mqttClient.setId("clientId");
  // You can provide a username and password for authentication
   mqttClient.setUsernamePassword("admin", "admin");
  Serial.print("connect to the MQTT broker: ");
  Serial.println(broker);
  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());
    while (1);
  }
  Serial.println("connected to the MQTT succeed!");
  Serial.println();
}
void loop() {
  // put your main code here, to run repeatedly:
  mqttClient.poll(); 
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    // save the last time a message was sent
    previousMillis = currentMillis;
    dataObj["cnt"] = count;
    String jsonString = JSON.stringify(dataObj);
    // send message, the Print interface can be used to set the message contents
    mqttClient.beginMessage(state_topic);
    mqttClient.print(jsonString);
    mqttClient.endMessage();
    count++;
    if(count>=90)
      count = 0;
    delay(1000);
  }
}

         整体软件流程如下:

image.png  

         详细内容可以进入分贴查看:

        【Follow me第二季第2期】进阶任务 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        拓展任务一起:

        我们这次选用了两个传感器,将资源利用最大化,为此我们需要制作连接线,arduino板子上直接有现成的接口,和板子是匹配的,一字串联皆可以了,这两个传感器的接口地址是不同,串联就可以,幸亏之前买过这个端子,确实不好掐啊:

image.png  

        接下来只要实现这两个传感器的驱动就可以了,依然得益于arduino的高集成,我们只要需要使用对应的应用函数就可以,不过我们需要配置一些传感器忙着一部分在初始化中完成:

#include "Adafruit_SHT4x.h"
#include "Adafruit_LTR329_LTR303.h"
Adafruit_SHT4x sht4;
Adafruit_LTR329 ltr = Adafruit_LTR329();
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  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;
  }
  sht4.setPrecision(SHT4X_HIGH_PRECISION);
  switch (sht4.getPrecision()) {
     case SHT4X_HIGH_PRECISION:
       Serial.println(F("SHT40 set to High precision"));
       break;
     case SHT4X_MED_PRECISION:
       Serial.println(F("SHT40 set to Medium precision"));
       break;
     case SHT4X_LOW_PRECISION:
       Serial.println(F("SHT40 set to Low precision"));
       break;
  }
  sht4.setHeater(SHT4X_NO_HEATER);
  switch (sht4.getHeater()) {
     case SHT4X_NO_HEATER:
       Serial.println(F("SHT40 Heater turned OFF"));
       break;
     case SHT4X_HIGH_HEATER_1S:
       Serial.println(F("SHT40 Heater: High heat for 1 second"));
       break;
     case SHT4X_HIGH_HEATER_100MS:
       Serial.println(F("SHT40 Heater: High heat for 0.1 second"));
       break;
     case SHT4X_MED_HEATER_1S:
       Serial.println(F("SHT40 Heater: Medium heat for 1 second"));
       break;
     case SHT4X_MED_HEATER_100MS:
       Serial.println(F("SHT40 Heater: Medium heat for 0.1 second"));
       break;
     case SHT4X_LOW_HEATER_1S:
       Serial.println(F("SHT40 Heater: Low heat for 1 second"));
       break;
     case SHT4X_LOW_HEATER_100MS:
       Serial.println(F("SHT40 Heater: Low heat for 0.1 second"));
       break;
  }  
  if (! sht4.begin(&Wire1)) {
    Serial.println(F("SHT40 sensor not found!"));
    while (1) ;
  }
   else
  {
    Serial.print(F("SHT40 detected!\t"));
    Serial.print(F("Serial number:\t"));
    Serial.println(sht4.readSerial(), HEX);    
  }
}

        循环中不断获取数据就可以,最后和上传数据进行一下关联,我们在HA中看到的就是传感器实时采集到的数据了:

void loop() {
  // put your main code here, to run repeatedly:
  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);
    }
  }
  sensors_event_t humidity, temp;
  sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
  float tem = temp.temperature;
  Serial.println("Temp *C = " + String(tem));
  float hum = humidity.relative_humidity;
  Serial.println("Hum. % = " + String(hum));

    dataObj["cnt"] = count;
    dataObj["hum"] = hum;
    dataObj["tem"] = tem;
    String jsonString1 = JSON.stringify(dataObj);
    mqttClient.beginMessage(state_topic1);
    mqttClient.print(jsonString1);
    mqttClient.endMessage();
    dataObj["LTR"] = visible_plus_ir;
    String jsonString2 = JSON.stringify(dataObj);
    mqttClient.beginMessage(state_topic2);
    mqttClient.print(jsonString2);
    mqttClient.endMessage();
								
  delay(1000);
}

         整体的软件流程如下:

image.png           详细内容可以进入分贴查看:

        【Follow me第二季第2期】传感器数据上传到HA - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)

        相关的配置和重点注意事项大家可以去对应的帖子查看。

四、代码分享

        所有任务代码可以直接放到对应的工程中打开,注意支持的库函数要进行适配下载,以及一些配置的地方配置成自己的内容。

【Follow me第二季第2期】任务汇总代码.zip (5.02 KB)
(下载次数: 4, 2024-10-10 19:08 上传)

五、视频讲解

        得捷电子Follow Me第二季第2期 - 得捷电子Follow Me第二季第2期 - EEWORLD大学堂

        或者直接点开下面的视频查看:

得捷电子Follow Me第二季第2期视频展示

六、活动总结

        本次活动可以是第一次实现了物联网的功能,这一次使用的HA平台,可以说这个是本次最大的收获之一,就是实现了HA平台的搭建,再有一个就是Arduino的使用真的是非常便捷,对于功能模块的验证非常方便,为活动点赞!也期待更多的坛友加入EEW的大家庭!

 

 

 

 

本帖最后由 qzc飘曳 于 2024-11-1 12:20 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复