383|1

23

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】一文全面完成任务 [复制链接]

  本帖最后由 金玉其中 于 2024-10-31 15:40 编辑

 

视频链接:https://training.eeworld.com.cn/video/41231

eeworld任务提交

        本次有幸参与得捷电子Follow Me第二季第2期活动,非常感谢论坛和得捷电子。Follow me活动是DigiKey联合EEWorld发起的大型开发板体验活动,每期技术大咖推荐可玩性与可学性较强的开发板/仪器套件,带着大家实际操作,我这次也是主要秉承着学习的态度进行本次的活动,实际上很早就已经收到了采购到的器件,不过还是等到大佬们都完成了才开始我的学习之旅。
一、主要器件
主开发板:Arduino UNO R4 WiFi
        Arduino UNO R4 WiFi 是一款基于32位Arm® Cortex®-M4 Renesas RA4M1微控制器,具有用于 Wi-Fi® 和蓝牙连接的ESP32模块,具备强大的计算能力和多种连接功能。该板SRAM 32kB,闪存256kB,时钟频率为48MHz,USB端口升级为USB-C,并且最大电源供应电压增加到24V。该板提供了一个CAN总线,允许用户通过连接多个扩展板来最小化布线并执行不同的任务。
        板载的Qwiic 连接器可以方便地创建即插即用风格的项目。本次的传感板也都是符合Qwiic 连接器接口的传感器。同时本次活动也提供详尽的开发板资料供我们查略。
传感器1:LTR-329光传感器扩展板
        LTR-329ALS-01是一款低压I2C数字光传感器[ALS],采用低成本微型芯片无铅表面贴装封装。该传感器将光强度转换为能够直接I2C接口的数字输出信号。它在0.01勒克斯至64k勒克斯的宽动态范围内提供线性响应,非常适合高环境亮度下的应用。总共有六种增益设置(1X、2X、4X、8X、48X和96X)可供用户配置。
传感器2:SHT40温湿度传感器扩展板
        SHT4x是一个数字传感器平台,用于测量不同精度等级的相对湿度和温度。其I2C接口提供多个预配置的I2C地址,同时保持超低功耗预算(0.4μW)。功率微调的内部加热器可以在三个加热水平下使用,从而使传感器能够在要求苛刻的环境中运行。四针双扁平无引线封装适用于表面贴装技术(SMT)加工,包括可选的封装专利PTFE[1]膜或可拆卸的保护盖。可提供符合ISO17025的传感器特定校准证书,可通过唯一序列号进行识别。
        秉承着尽可能多的学习,这次直接采购的两个传感器来完成任务,说实话,正好极限的覆盖了,最好的利用方式,线就没有买了,自己做一下就可以了,而且这两个传感器可以直接串联起来,使用一个Qwiic 连接器接口皆可以,毕竟就是多了几个现实参数,在完成物联网显示的时候,显示一个和显示两个没什么差异。
二、学习成果展示
1、配置开发环境
        本次使用的是官方的开发环境,Arduino IDE,可以通过官网下载适配系统的最新版:
        注意哦,还有免安装版本,秉承着能省一步是一本,直接免安装无脑启动;
        通过USB线连接开发板和PC,软件可以直接检测到连接到的开发板:
        然后就可以通过开发板安装对应的基础库了,通过开发板管理器进行搜索:
2、入门任务:搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
        编程的开始就是实现点灯,我们新建一个工程:
        显然,存在两个关键函数:setup()和 loop()。其中,setup()扮演着初始化配置的角色,仅执行一次以设置初始状态;而 loop()则负责循环执行的内容,持续不断地运行以维持或改变程序的状态。
        Arduino的卓越之处,在于其高度集成化的特性,让我们无需深究硬件的繁复细节,仅凭固件内预设的函数便能轻松驾驭。尽管如此,为了更全面地理解,我们还是简要概览一下LED的硬件配置:
        可以看出来只有DL4是实际上我们可以控制的,DL3是供电只是等,另外两个是串口传输指示。对于LED和串口的控制不需要而外的固件,板载固件就可以使用,我们实现一下任务:
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:
  // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, HIGH);
  // wait for a second
  delay(500);
  // turn the LED off by making the voltage LOW
  digitalWrite(LED_BUILTIN, LOW);
  // wait for a second
  delay(500);
  Serial.println("Hello EEWorld!");
}

        本次的任务还是比较简单,毕竟是入门的第一个任务,对上面的程序进行一下简单的介绍,本次任务主要用到的LED串口口,我们需要进行一下相应的初始化,可以看到初始化直接调用一个函数就本上就完成了,通过不同的板子的库文件,内部都已经进行好了关联,直接配置重要的参数就可以,然后就是阻塞式的实现LED的闪烁,并同时循环的发送“Hello EEWorld!”。

        点击上传会自动进行工程的编译和下载,然后就可以通过观察板子的L等和IDE自带的串口监视器进行效果观察了:
        注意配置好波特率。
3、基础任务:驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线。
        其实这个任务是一个组合任务,可以拆分出多个任务,比如驱动LED、DAC输出正弦波、OPAMP信号放大、ADC的采集并通过接口上传显示。可以拆分出多个不相关的任务,为了实现更好的效果展示,我们经过拆分和再组合,分成了下面三个小任务:
        第一个就是12x8点阵LED点阵的控制;
        第二个就是DAC生成正弦波,然后通过OPAMP放大2倍,在通过ADC采集信号进行串口输出,这里面我们可以通过示波器进行对应节点的一个测量,例如DAC的输出,放大信号的输出,都可以通过示波器进行状态展示。
        接下来我们先看看12x8点阵LED点阵的控制:
        基本硬件如上图,也通过各位大佬的学习,有的人是通过静态显示的方法实现点阵的设计实现不同字符的显示,也有人通过不同的库文件实现动态的显示,个人也比较喜欢动态显示的方式,有点大街上小店的横幅的感觉。
        点阵的LED的基础库是"Arduino_LED_Matrix.h",而动态显示文本的库是"ArduinoGraphics.h",注意ArduinoGraphics需要单独安装:
#include "Arduino_LED_Matrix.h"
#include "ArduinoGraphics.h"
ArduinoLEDMatrix matrix;
void setup() {
  matrix.begin();
}
void loop() {
  matrix.beginDraw();
  matrix.stroke(0xFFFFFFFF);
  matrix.textScrollSpeed(50);
  const char text[] = "  EEWorld && DigiKey  ";
  matrix.textFont(Font_5x7);
  matrix.beginText(0, 1, 0xFFFFFF);
  matrix.println(text);
  matrix.endText(SCROLL_LEFT);
  matrix.endDraw();
}

        接下来就是模拟部分的控制:

        DAC输出:我们直接使用内置的"analogWave.h",由于后面的实验要求,我们需要限制一下幅值,具体代码如下:
#include "analogWave.h" // Include the library for analog waveform generation
analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin
int freq = 10;  // in hertz, change accordingly
void setup() {
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  pinMode(A0, OUTPUT);
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4
  wave.sine(freq);       // Generate a sine wave with the initial frequency
}
void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  delay(500);
}

        结果如下:

        接下来是放大部分,需要使用OPAMP,启动OPAMP很方便:
#include "analogWave.h"
#include <OPAMP.h>
void setup() {
  Serial.begin(115200);
  pinMode(A0, OUTPUT);
  wave.amplitude(0.25);
  wave.sine(freq);      
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
}

        同时需要进行外部的连接:

        有上图也可以看到,Vpp的幅值有1.23V增加到了2.44V,我是用的是两个一样的电阻,所以是增加两倍的效果。
        接下来我们将A3和A5连接,是的,我们准备用A5进行ADC采集,一下为本阶段最终代码:
#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC);   // Create an instance of the analogWave class, using the DAC pin
int freq = 10;  // in hertz, change accordingly
void setup() {
  Serial.begin(115200);  // Initialize serial communication at a baud rate of 115200
  pinMode(A0, OUTPUT);
  pinMode(A5, INPUT);
  analogReadResolution(12);// 设置 ADC 分辨率为 12 位
  wave.amplitude(0.25); //设置幅度值为4.7 的1/4
  wave.sine(freq);       // Generate a sine wave with the initial frequency
  OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
}
void loop() {
  // Read an analog value from pin A5 and map it to a frequency range
  int value = analogRead(A5);// 读取 ADC 值
  Serial.println(value);
}

        效果显示还是不太理想,主要是显示个数限制太厉害了,不过也是可以看到趋势的:

4、进阶任务及扩展任务
        通过对任务的分析,实际上进阶任务和扩展任务是一致的内容,都是通过本开发板实现和HomeAssistant智能家居平台进行通信,这里通过时板载的wifi功能,通信协议为Mqtt。
将任务打碎后重组,我们需要完成一下三个工作:
        第一:实现传感器数据的采集,也就是SH40和光传感器数据的采集,这一部分还不涉及无线通信能力,通过接口连接,实现数据采集后通过串口进行数据打印即可,可以通过串口工具进行查看;
        第二:HomeAssistant智能家居平台的操作实现,HA支持很多种系统,我们需要实现HA平台的搭建工作;
        第三:实现wifi的驱动,同时配置Mqtt协议的相关参数,实现和HomeAssistant智能家居平台的沟通,实现SH40和光传感器数据的在线查看。
        接下来就实现过程:
        通过串联的方式连接传感器,安装对应的传感器库:
        首先进行两个传感器的初始化:
#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(9600);
  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;
  }
// You can have 3 different precisions, higher precision takes longer
  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;
  }
// 6 different heater settings
  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);    
  }
}

        初始化成功:

        循环读取程序就简单的多了: 
 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));

        读取成功:

        接下来就是实现HA的通信和数据上传,这一部分主要包括的事HA系统的安装和,由于每个人使用的都不一样,可以看到有容器版的,有用树莓派的,也有用虚拟机的,对于当前的情况来说,使用虚拟机会比较方便一点,毕竟没有多余的硬件。这里根据官方的安装指南可以实现非常方便的安装,咱们打开HA看一下:
        主要是需要加入mqtt固件,并通过MQTT模拟器进行设备和实体的注册,我们需要确认光照传感器有一个参数,SH40有两个参数,为此,我们创建三个实体:
        接下来就是通过Mqtt,配置基本参数,主要是往"homeassistant/sensor/Roomsensor/state"写对应的数据:
char ssid[] = "开发板连接的wifi";        
char pass[] = "开发板连接的wifi密码";  
const char broker[] = "目标地址ip";
int        port     = 1883;
const char state_topic[]  = "homeassistant/sensor/Roomsensor/state";
然后就是循环采集发送:
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["light"] = visible_plus_ir;
  dataObj["hum"] = hum;
  dataObj["tem"] = tem;
  String jsonString1 = JSON.stringify(dataObj);
  mqttClient.beginMessage(state_topic);
  mqttClient.print(jsonString1);
  mqttClient.endMessage();
  delay(1000);
}

        整体软件流程:

 

        结果如下:

        遮挡一下:
        这里需要注意一下,串口的通信可能会影响Mqtt的连接,之前一直报错,反应的是目标地址访问被拒绝,后来加个while (!Serial)解决的。
代码汇总:
        大家可以下载代码直接进行修改测试,入门任务以及进阶任务都是比较简单的,进阶任务还是挺让人回味的
任务代码汇总.zip (5.63 KB, 下载次数: 1)
总结:
        本次的活动主要依着学习的态度进行,确实Arduino的各种丰富的固件非常适合功能验证,也感谢论坛和各位网友的精彩分享。

最新回复

整合的挺不错,有不少任务可以合到一起进行     详情 回复 发表于 2024-10-3 22:14
点赞 关注
 
 

回复
举报

6470

帖子

9

TA的资源

版主

沙发
 

整合的挺不错,有不少任务可以合到一起进行  

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表