- 2024-10-30
-
加入了学习《得捷电子Follow Me第二季第2期》,观看 得捷电子Follow Me第二季第2期
- 2024-10-10
-
发表了主题帖:
【Follow me第二季第2期】任务汇总
本帖最后由 qzc飘曳 于 2024-11-1 12:20 编辑
本次活动已经接近尾声了,我们一起通过学习实现了物联网的基本流程,本次活动是DigiKey联合EEWorld发起的Follow me活动第二季的第二期,精选高可玩性与教育价值的开发板及仪器套装,携手共赴实践盛宴。
一、物料展示
主控板卡: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 连接器可以方便地创建即插即用风格的项目。
传感器一:LTR-329光传感器扩展板
LTR-329ALS-01是一款低压I2C数字光传感器[ALS],采用低成本的微细片状无铅表面贴装封装。该传感器将光强度转换为能够直接I2C接口的数字输出信号。它在0.01勒克斯到64k勒克斯的宽动态范围内提供线性响应,非常适合高环境亮度下的应用。共有六种增益设置(1X, 2X, 4X, 8X, 48X和96X)可供用户配置。
传感器二:SHT40温湿度传感器扩展板
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的翻转:
并在执行一次后串口打印一次"Hello EEWorld!":
详细内容可以进入分贴查看:
【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
}
效果如下:
视频效果可以看最后的效果视频中的任务二-LED整列显示部分;
其他部分是对ADC、DAC、放大等部分的操作,并且用到了我们任务一中使用的串口打印,这个时候需要一些外部连接:
放大器的外部配置更加重要,硬件的基本配置通过正向放大器的方式进行,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);
}
}
软件流程如下:
部分效果如下:
显示是通过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);
}
}
整体软件流程如下:
详细内容可以进入分贴查看:
【Follow me第二季第2期】进阶任务 - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)
拓展任务一起:
我们这次选用了两个传感器,将资源利用最大化,为此我们需要制作连接线,arduino板子上直接有现成的接口,和板子是匹配的,一字串联皆可以了,这两个传感器的接口地址是不同,串联就可以,幸亏之前买过这个端子,确实不好掐啊:
接下来只要实现这两个传感器的驱动就可以了,依然得益于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);
}
整体的软件流程如下:
详细内容可以进入分贴查看:
【Follow me第二季第2期】传感器数据上传到HA - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn)
相关的配置和重点注意事项大家可以去对应的帖子查看。
四、代码分享
所有任务代码可以直接放到对应的工程中打开,注意支持的库函数要进行适配下载,以及一些配置的地方配置成自己的内容。
五、视频讲解
得捷电子Follow Me第二季第2期 - 得捷电子Follow Me第二季第2期 - EEWORLD大学堂
或者直接点开下面的视频查看:
[localvideo]f1855d8647910fa7639c05e6b869c294[/localvideo]
六、活动总结
本次活动可以是第一次实现了物联网的功能,这一次使用的HA平台,可以说这个是本次最大的收获之一,就是实现了HA平台的搭建,再有一个就是Arduino的使用真的是非常便捷,对于功能模块的验证非常方便,为活动点赞!也期待更多的坛友加入EEW的大家庭!
- 2024-10-03
-
回复了主题帖:
【Follow me第二季第2期】配置开发环境
lansebuluo 发表于 2024-9-11 13:55
Arduino一直都比较火,不知道这个优势在什么地方
就是集成库比较方便,不用写驱动了
-
回复了主题帖:
【Follow me第二季第2期】开箱
yangjiaxu 发表于 2024-9-11 11:55
这板子真的好看啊, 而且还是个沉金的,电路看起来真的很不错,还用了type-C接口
新一代的R4
-
回复了主题帖:
【Follow me第二季第2期】任务一
yangjiaxu 发表于 2024-9-11 11:53
用arduino真的不错,我觉得arduino就是为了避免重复造轮子,而且库也是真的多啊
集成库非常全,就是编译方式有点鸡肋,每次都是从头到尾编译
-
回复了主题帖:
【Follow me第二季第2期】任务二
yangjiaxu 发表于 2024-9-11 11:53
驱动12x8点阵LED是不是得用扩展IO芯片了,这样的话会占用更少的IO,比较有优势啊
如原理图一样,内部已经集成了
-
回复了主题帖:
【Follow me第二季第2期】传感器数据上传到HA
yangjiaxu 发表于 2024-9-11 11:52
这个HA是什么?是一个硬件吗还是一个什么东东呢?而且我看好像是一个物联网的系统
挺好用的,就是前期安装比较费事
-
回复了主题帖:
【Follow me第二季第2期】进阶任务
yangjiaxu 发表于 2024-9-11 11:50
做的很好啊,效果很炫酷的,而且MQTT我觉得还是比较方便好用的,主要是在于订阅这种,不用长连接
主要是这些集成库很好用,直接配置好了,直接发送就行
- 2024-09-10
-
发表了主题帖:
【Follow me第二季第2期】进阶任务
通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)。
实际上我们通过在HA系统中注册设备和实体后,只要通过固定的接口按照规则发送数据就能实现整个正常的解析和显示了。
我们打开HA,配置MQTT模块:
主要是IP地址要和你的HA系统的IP地址相一致;
然后通过MQTT模块的自发现功能,使用MQTT模拟器进行连接注册,首先要连接到我们的HA:
设备注册通过下面语句进行(config topic):
homeassistant/sensor/sensorsth40tem/config
如果为空则是删除对应的设备,否则需要添加配置项:
{
"name":"tem",
"device_class":"temperature",
"state_topic":"homeassistant/sensor/sensorsth40/state",
"value_template":"{{ value_json.tem}}",
"unit_of_measurement":"C",
"unique_id":"sth40-001-tem",
"device":{
"identifiers":[
"STH40"
],
"name":"SHT40-Sensor",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi"
}
}
同理创建了同样的设备下的3个实体:
其中cnt用于显示上报次数,这个在我们没有进行传感器采集的时候用于进行实物测试,其实这个时候说明已经实现了HA系统的打通,不过我们还是使用模拟器进行一下具体数据传的测试:
发送:
homeassistant/sensor/sensorsth40/state
{ "tem": 23.20, "hum": 43.70 ,"cnt":1}
输出结果符合预期:
以上内容我们都是通过PC软件实现的,接下来我们使用开发板进行上述功能的实现。
这里主要设计wifi连接和MQTT协议的内容:
#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);
}
}
串口打印状态:
HA系统中的效果展示参见最终的效果视频-进阶任务。
-
发表了主题帖:
【Follow me第二季第2期】传感器数据上传到HA
咱们已经实现了开发板和HA之间的程序,接下来我们就要实现传感器数据的采集,本次一共采购了两个传感器,也就是光照和环境传感器。
实际上两个扩展任务基本上是一致,也就是说模式都是采集传感器数据然后传输到HA,由于传感器的不同,我们需要再建立一个光照数据的设备和实体:
homeassistant/sensor/sensorLTR-329/config
{
"name":"LTR-329",
"state_topic":"homeassistant/sensor/sensorLTR-329/state",
"value_template":"{{ value_json.LTR}}",
"unique_id":"LTR-329",
"device":{
"identifiers":[
"LTR-329"
],
"name":"LTR-329-Sensor",
"manufacturer": "Arduino",
"model": "UNO R4 WiFi"
}
}
接下来实现传感器数据的采集,并通过串口打印:
这里我们需要安装两个库文件及其依赖的基础库:
#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);
}
}
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));
delay(1000);
}
可以看到结果如下:
接下来将数据与物联网HA系统进行融合显示:
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();
效果可以查看最终的效果展示视频的扩展任务部分。
最终的视频展示:
https://training.eeworld.com.cn/course/68650/learn?preview=1#lesson/41079[localvideo]020f1462437b698b1112a31255bb0104[/localvideo]
-
发表了主题帖:
【Follow me第二季第2期】任务二
基础任务(必做):驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
可以看到基础任务中是包含很多的任务的,下面我们根据不同任务进行分别实现。
一、驱动12x8点阵LED
这是一个总共96个LED的组成的矩阵:
可以不太关心的具体的硬件组成,我们在使用的时候主要参考的是Arduino_LED_Matrix,目前下载的板卡库里面就包括这个独立的库,那么我们如何去定义具体的显示内容呢?在例程中可以看到:
const uint32_t chip[] = {
0x1503f811,
0x3181103,
0xf8150000
};
96个LED被3个32位的数定义,然后通过matrix.loadFrame(chip);进行一次的显示,我们定义几个字符进行显示控制,我们可以通过一些点阵实现编码,然后进行循环显示,这里我们定义了几个汉字和字符:
// 欢
const uint32_t show_1[] = {
0x0003A04B,
0xE3501182,
0x98464182
};
// 迎
const uint32_t show_2[] = {
0x0002FE09,
0x22922F22,
0x105FE000
};
// 加
const uint32_t show_3[] = {
0x0001007D,
0xE1522522,
0x5245E880
};
// 入
const uint32_t show_4[] = {
0x0000C004,
0x00600901,
0x08606800
};
const uint32_t show_E[] = {
0x0000003F,
0xE3083F83,
0x003FE000
};
const uint32_t show_W[] = {
0x00000066,
0x22643541,
0x98110000
};
然后进行循环显示,代码如下:
#include "Arduino_LED_Matrix.h"
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
}
思路依然是先初始化,然后循环显示“欢迎加入EEW”,其中通过清屏实现另个EE之间的分割,效果参见最后的效果视频部分的任务二:1、12x8点阵LED控制。
二、DAC生成正弦波,用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
这一部分实际上坟成三个小任务,一个是DAC输出正玄波,一个是用OPAMP放大DAC信号,另外一个是ADC采集并打印,我们简单分析一下,这其中只有串口打印可以进行状态展示,配合IDE的串口绘图仪可以实现图形的绘制。所以我们的一般步骤就是串口的控制——ADC的采集并打印——DAC控制到ADC采集——DAC控制并放大,然后到ADC采集。
我们先实现串口打印图形,默认打印1241:
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
matrix.begin();
matrix.loadFrame(show_4);
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println(1241);
delay(10);// 读取间隔
}
效果如下,打印波形正常:
接下来我们看一下硬件部分:
可以看到删除A0-A5都可以设置成ADC的功能,那么我们将A5设置为ADC采集,并通过A0的DAC输出幅值为1V的正弦波波形给到A5的ADC进行采集,注意需要外部通过杜邦线连接A0和A5:
然后初始化两个模拟接口:
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);
}
}
这次依然使用的是IDE里的串口绘图工具查看的,不过同时显示的点只有50个,这就导致无法看到比较完整的波形,只能通过视频的方式录制,本次的峰值为1V,所以对应的ADC采集到的变化区间大概是0-800之间左右,具体视频参照任务二中的ADC采集DAC的视屏展示。
接下来进行OPAMP放大DAC信号,然后进行ADC采集串口打印,这里也是为什么前面的测试使用1V幅值,这里通过OPAMP进行两倍的放大,避免超过限值,注意放大功能依然需要外部电阻的配置。
硬件的基本配置通过正向放大器的方式进行,ADC连接到OPAMP的正输入,也就是A1,A2的电压就虚短等于A1处电压,然后通过两个等大的电阻进行2被放大,A2到地连接一个,到输出连接一个,这样A3处的输出就是A1处的2倍了,通过ADC采集进行串口输出绘图。
软件上只要通过OPAMP.begin(OPAMP_SPEED_HIGHSPEED);就可以开启了。
#include <OPAMP.h>
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
和ADC采集一样,循环变化,ADC的采集值在0-1600之间变化,具体视频参照任务二中的ADC采集DAC放大后的视屏展示。
-
发表了主题帖:
【Follow me第二季第2期】任务一
入门任务(必做):搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
我们在上一步已经将相应的开发环境已经搭建,接下来就是进行程序编程的第一步,实现Blink,并串口打印Hello EEWorld。
点灯永远是了解一个板子的第一步,我们进行先新建一个测试工程,通过另存保存:
可以看到有setup()和loop()两个函数,实际上一个就是相当于初始化配置,只运行一次,另一个是循环运行的内容。
虽然Arduino的优点就是高度集成化,我们不需要看到底是什么样的硬件,直接通过固件中函数进行驱动就可以,不过我们还是简单看一下LED的硬件配置:
实际上就是P102低电平的时候这个可控的LED是点亮的。
咱们先简单的看一下:
void setup() {
// put your setup code here, to run once:
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
}
也是此处进行LED引脚的初始化,注意HIGH对应的电平是低的,这个时候LED被点亮了。
接下来咱们实现Blink / 串口打印Hello EEWorld功能,实际上就是通过延时功能实现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:
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!");
}
可以使用IDE自带的串口监视器进行查看:
-
发表了主题帖:
【Follow me第二季第2期】配置开发环境
本次使用的是官方的开发环境,Arduino IDE,其实我还真没有使用过,所以也准备一篇开发环境的配置篇。‘
我们可以从官网下载Arduino IDE:
打开官网https://www.arduino.cc;
当前最新版本2.3.2,注意看一下是不是和自己的电脑匹配,我是win10 64位,能带动;
一路跳过,仅下载,下载速度还可以:
arduino-ide_nightly-20240630_Windows_64bit是免安装版本,直接就可以用了;
换成中文,其他设置也可以改一下;
如果连接开发板的话,可以看到直接就能识别出来:
这个时候我们还需要安装对应的开发板:
不然验证的时候会提示错误:
-
发表了主题帖:
【Follow me第二季第2期】开箱
如期收到了开发板,准备开始学习之旅!
这次得捷没有过渡包装,采用的是比较务实的包装,包裹的非常严实;
最近一直在给这个东西,是干嘛用的?好像是什么购物回馈,不知道咱们这种参加活动的是不是也能参加;
正主出现,一个开发板和两个传感器板,算是比较豪华的配置了;
实际上我没有真正接触过Arduino,有需要测试的东西都是用现有的开发板或者demo板进行,从头到尾配置的那种。
细节真的是做的很好,还给配了结构底座,插排上也印刷了字。
Arduino UNO R4 WiFi,这款革命性的开发板,搭载了高效的32位Arm® Cortex®-M4 Renesas RA4M1微控制器,并集成了ESP32模块,实现了Wi-Fi®与蓝牙的无缝连接,展现出前所未有的计算能力与广泛的连接潜能。其配备的32kB SRAM与256kB闪存,确保项目运行流畅无阻,而48MHz的时钟频率则进一步提升了处理速度。尤为值得一提的是,该板已升级至USB-C接口,不仅提升了充电与数据传输的便利性,还兼容更多现代设备。同时,最大电源供应电压提升至24V,满足更多高功率项目的需求。板载的Qwiic连接器以其即插即用的特性,为项目搭建带来了前所未有的便捷性,让创意与实现之间的距离更近一步。无论是对于电子爱好者还是专业开发者而言,Arduino UNO R4 WiFi都是一款不可多得的创新工具。
- 2024-08-14
-
回复了主题帖:
>>征集 | 使用 MCU,哪些问题最令你头大?
芯片缺货与替代难题
痛点:疫情期间,特定型号的MCU经常出现缺货情况,导致项目延期甚至停滞。替代芯片的选择不仅需要考虑性能参数匹配,还需考虑软件兼容性、封装尺寸、引脚排列等因素,这大大增加了设计复杂度。
解决方案:
提前规划:建立多元化的供应商体系,减少对单一供应商的依赖。
模块化设计:在设计初期就考虑使用模块化架构,便于在需要时快速更换MCU模块。
软件抽象层:开发通用的软件抽象层(HAL),减少对特定MCU硬件的直接依赖,提高代码的可移植性。
衍生问题-软硬件适配问题
痛点:不同MCU之间的寄存器配置、中断系统、外设接口等存在差异,导致软件迁移和适配工作量大。
解决方案:
使用中间件:利用RTOS(实时操作系统)、文件系统、图形库等中间件,它们通常提供较好的跨平台支持。
代码重构:采用面向对象或组件化的编程方法,将硬件相关的代码封装成独立的模块,降低耦合度。
自动化测试:建立全面的自动化测试体系,确保每次更改后都能快速验证软硬件的适配性。
- 2024-05-24
-
加入了学习《泰克 4 系列 B MSO》,观看 4系列B MSO示波器
- 2024-05-16
-
回复了主题帖:
新手上路:探秘我的首次测评之旅
多学多练综合提高,有一就有二,慢慢来
-
回复了主题帖:
【NUCLEO-U083RC】EXIT中断测试及功耗测试
USER_BUTTON_IRQHANDLER(void)这个是重新编写了还是重定义的,直接用回调函数就可以把
-
回复了主题帖:
EPS硬件开发
慢慢来,跨行实际上还是有点基础的,接受起来还算不错了
-
回复了主题帖:
尴尬的硬件开发工程师
只会一些基本的操作,看太复杂的信号还得找老师傅