下面是我Follow me 第二季第2期各个功能的贴子,具体的细节可以进行查看。
Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld!
https://bbs.eeworld.com.cn/thread-1294799-1-1.html
Follow me 第二季第2期任务基础任务点阵/DAC/ADC采集
https://bbs.eeworld.com.cn/thread-1294800-1-1.html
https://bbs.eeworld.com.cn/thread-1295342-1-1.html
Follow me 第二季第2期进阶任务MQTT平台HA任务
https://bbs.eeworld.com.cn/thread-1295082-1-1.html
Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示
https://bbs.eeworld.com.cn/thread-1295431-1-1.html
Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示
https://bbs.eeworld.com.cn/thread-1295434-1-1.html
视频:
Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld!
LED闪烁代码:
void setup() {
// 初始化数字引脚LED_BUILTIN为输出状态
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // 打开LED灯
delay(1000); // 等待一秒
digitalWrite(LED_BUILTIN, LOW); // 关闭LED灯
delay(1000); // 等待一秒
}
工作流程:
开始(Start)
流程图的起点。
初始化
调用setup()函数。
设置LED_BUILTIN引脚为输出模式(pinMode(LED_BUILTIN, OUTPUT))。
主循环(Loop)
调用loop()函数,这是一个无限循环。
打开LED
在loop()中,首先调用digitalWrite(LED_BUILTIN, HIGH)将LED灯打开。
等待一秒
调用delay(1000),等待1000毫秒(即1秒)。
关闭LED
调用digitalWrite(LED_BUILTIN, LOW)将LED灯关闭。
再次等待一秒
再次调用delay(1000),等待1000毫秒(即1秒)。
回到主循环
流程回到loop()的开始,重复步骤4到7。
结束(End)
理论上,由于这是一个无限循环,流程不会真正结束,但在流程图中可以用一个圆形结束符号表示流程图的视觉结束点。
串口打印Hello EEWorld!
void setup() {
// 初始化数字引脚LED_BUILTIN为输出状态
pinMode(LED_BUILTIN, OUTPUT);
// 初始化串口通信,设置波特率为9600
Serial.begin(9600);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // 打开LED灯
delay(1000);
digitalWrite(LED_BUILTIN, LOW); // 关闭LED灯
delay(1000);
// 串口打印Hello EEWorld!
Serial.println("Hello EEWorld!");
}
输出结果:
Follow me 第二季第2期任务基础任务DAC/ADC采集
驱动12x8点阵LED
Arduino UNO R4 WiFi开发板上点阵LED的行列控制引脚正确连接到开发板的数字I/O接口。
在Arduino IDE中编写代码,使用digitalWrite或shiftOut等函数控制点阵LED的行列,实现显示功能。
通过循环或数组来控制LED的亮灭,形成图案或文字。
下面代码中,显示‘MY’。
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
byte frame[8][12] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0 },
{ 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0 },
{ 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 },
{ 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 },
{ 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
void setup() {
Serial.begin(115200);
matrix.begin();
matrix.renderBitmap(frame, 8, 12);
}
void loop() {
}
输出结果:
用DAC生成正弦波:
Arduino UNO R4 WiFi开发板上的DAC接口需要被正确配置。根据开发板的文档,设置DAC的分辨率、输出范围等参数。
生成正弦波:编写代码,使用数学函数(如sin)生成正弦波的数据点。将数据点通过DAC输出到模拟引脚。
#include "analogWave.h"
analogWave wave(DAC); // 使用DAC引脚实例化模拟曲线对象wave
float freq = 0.5; // 设置曲线初始频率
void setup() {
Serial.begin(115200); // 串口波特率
wave.sine(freq); // 使用模拟曲线对象wave按照初始频率生成正弦波
wave.amplitude(0.5);
}
void loop() {
printf("%d\n",analogRead(A4)); // 读取正弦值
delay(100);
}
#include "analogWave.h":这行代码包含了一个名为analogWave的头文件,这个头文件中可能定义了用于生成模拟波形的类和相关函数。
analogWave wave(DAC);:使用DAC引脚实例化一个名为wave的analogWave对象。这意味着这个对象将使用指定的DAC引脚来输出模拟波形。
float freq = 0.5;:设置一个初始频率为0.5的浮点数变量freq。这个频率可能用于控制生成的正弦波的周期。
void setup() {... }:
Serial.begin(115200);:初始化串口通信,设置波特率为 115200。
wave.sine(freq);:使用wave对象调用sine函数,传入初始频率freq,以生成正弦波。
wave.amplitude(0.5);:设置生成的正弦波的幅度为 0.5。
void loop() {... }:
printf("%d\n",analogRead(A4));:读取A4引脚的模拟值,并通过串口打印出来。
delay(100);:延迟 100 毫秒,以控制程序的执行速度。
主要功能是使用一个名为analogWave的类来生成正弦波,并通过DAC引脚输出。代码在主循环中不断读取A4引脚的模拟值并通过串口打印出来。
用OPAMP放大DAC信号
生成一个正弦波,并可以通过读取模拟输入引脚 A5 的值来动态调整正弦波的频率,然后将更新后的频率信息打印到串口监视器上。
#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
int reading = 0;
void setup() {
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
analogWriteResolution(14);
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
freq = map(analogRead(A5), 0, 1024, 0, 10000);
// Print the updated frequency to the serial monitor
Serial.println("Frequency is now " + String(freq) + " hz");
reading = analogRead(A4);
Serial.print(reading);
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(50); // Delay for one second before repeating
}
使用的工具与器件有:
电阻10K--1个
电阻30K--1个
手持示波器--一台。
电阻连接示意图:
用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
代码的主要功能是通过读取模拟输入引脚 A5 的值来动态调整正弦波的频率,并将该频率信息打印到串口监视器上。代码使用 analogWave 类在指定的 DAC 引脚上生成正弦波,并通过读取 A4 引脚的模拟值进行一些可能的后续处理(这里只是将其打印出来)。
#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
int reading = 0;
void setup() {
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
analogWriteResolution(14);
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
freq = map(analogRead(A5), 0, 1024, 0, 10000);
// Print the updated frequency to the serial monitor
Serial.println("Frequency is now " + String(freq) + " hz");
reading = analogRead(A4);
Serial.print(reading);
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(50); // Delay for one second before repeating
}
程序工作流程:
开始
标记为“开始”的圆形节点。
初始化
包含库:analogWave.h 和 <OPAMP.h>
创建实例:analogWave wave(DAC);
设置变量:int freq = 10; 和 int reading = 0;
设置OPAMP:OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
初始化串口:Serial.begin(115200);
设置DAC分辨率:analogWriteResolution(14);
生成初始波形:wave.sine(freq);
标记为“处理框”或“步骤”的矩形节点,包含上述初始化步骤。
主循环
标记为“循环开始”的圆形节点(通常有一个小箭头指向它,表示循环)。
读取A5引脚
读取模拟值:freq = map(analogRead(A5), 0, 1024, 0, 10000);
标记为“处理框”的矩形节点,显示读取和映射操作。
打印频率
输出到串口:Serial.println("Frequency is now " + String(freq) + " hz");
标记为“输出”的菱形节点,显示串口输出。
读取A4引脚
读取模拟值:reading = analogRead(A4);
输出到串口:Serial.print(reading);
标记为“处理框”的矩形节点,显示读取和输出操作。
设置波形频率
更新波形频率:wave.freq(freq);
标记为“处理框”的矩形节点,显示频率更新操作。
延迟
延时:delay(50);
标记为“延迟”的菱形节点,显示延迟时间。
循环结束
回到“主循环”的圆形节点,形成闭环。
结束
标记为“结束”的圆形节点。
输出效果图:
Follow me 第二季第2期进阶任务MQTT平台HA任务
MQTT服务器:EMQX或Mosquitto,可以选择安装一个MQTT服务器,或者在云服务上使用一个现有的MQTT服务。
配置MQTT服务器:根据MQTT服务器的文档,配置必要的参数,。记录MQTT服务器的地址、端口和认证信息(用户名和密码)。
// 引入必要的库
#include <ArduinoMqttClient.h> // 注意:这个库可能不是标准的Arduino库,需要确认其来源和兼容性
#include <WiFiS3.h> // 这个库可能也不是标准的,通常我们使用<WiFi.h>
#include <WiFiClient.h> // 用于创建WiFi客户端对象,与MQTT服务器通信
// WiFi网络的SSID和密码
char ssid[] = "CMCC-qM7y";
char pass[] = "15074219167";
// WiFi连接状态
int status = WL_IDLE_STATUS;
// MQTT代理的IP地址和端口号
const char broker[] = "192.168.1.113";
int port = 1883;
// 要发布的MQTT主题
const char topic[] = "/aht10/test";
// 创建WiFi客户端和MQTT客户端对象
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient); // 注意:MqttClient类的构造函数可能需要根据实际库进行调整
void setup() {
// 初始化串口通信,用于调试
Serial.begin(9600);
// 等待串口连接(仅对某些开发板必要)
while (!Serial) {
// 空循环,等待串口准备就绪
}
// 检查WiFi模块是否存在
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("WiFi模块通信失败!");
// 如果WiFi模块不存在,则停止执行
while (true);
}
// 检查WiFi固件版本(这个步骤可能不是必需的)
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) { // 注意:WIFI_FIRMWARE_LATEST_VERSION可能需要定义或根据实际情况调整
Serial.println("请升级固件!");
}
// 尝试连接到WiFi网络
while (status != WL_CONNECTED) {
Serial.print("正在尝试连接到WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass); // 开始连接到指定的SSID和密码
delay(10000); // 等待10秒以尝试连接
}
// 打印当前连接的网络信息
Serial.print("您已连接到网络");
printCurrentNet();
printWifiData();
// 尝试连接到MQTT代理
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT连接失败!错误代码 = ");
Serial.println(mqttClient.connectError()); // 打印连接错误的详细信息
// 如果连接失败,则停止执行
while (1);
}
Serial.println("您已连接到MQTT");
}
// 打印当前网络的信息
void printCurrentNet() {
// 打印连接的SSID
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// 打印路由器的MAC地址
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// 打印接收到的信号强度
long rssi = WiFi.RSSI();
Serial.print("信号强度 (RSSI):");
Serial.println(rssi);
// 打印加密类型
byte encryption = WiFi.encryptionType();
Serial.print("加密类型:");
Serial.println(encryption, HEX); // 以十六进制格式打印
Serial.println();
}
// 打印MAC地址的函数
void printMacAddress(byte mac[]) {
for (int i = 0; i < 6; i++) {
if (i > 0) {
Serial.print(":"); // 在MAC地址的每个字节之间打印冒号
}
// 如果MAC地址的某个字节小于16,则在前面打印0
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX); // 以十六进制格式打印MAC地址的每个字节
}
Serial.println();
}
// 打印WiFi数据(IP地址和MAC地址)
void printWifiData() {
// 打印开发板的IP地址
IPAddress ip = WiFi.localIP();
Serial.print("IP 地址: ");
Serial.println(ip);
// 打印开发板的MAC地址
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC 地址: ");
printMacAddress(mac);
}
// 主循环
void loop() {
// 开始一个新的MQTT消息
mqttClient.beginMessage(topic);
// 向消息中添加内容
mqttClient.print("Hello EEworld and Digikey!");
// 结束并发送消息
mqttClient.endMessage();
// 等待500毫秒,然后重复发送
delay(500);
}
工作流程:
初始化阶段(setup()函数)
串口初始化:
Serial.begin(9600); 初始化串口通信,波特率设为9600,用于调试信息输出。
WiFi模块检查:
通过WiFi.status()检查WiFi模块是否存在。如果不存在,则输出错误信息并停止执行。
WiFi固件版本检查(可选):
获取WiFi固件版本,并与最新版本进行比较(注意:WIFI_FIRMWARE_LATEST_VERSION可能需要自定义或根据实际情况调整)。如果版本过旧,则提示用户升级固件。
连接到WiFi网络:
使用WiFi.begin(ssid, pass);尝试连接到指定的SSID和密码。如果连接失败,则每10秒重试一次,直到成功为止。
打印网络信息:
一旦连接到WiFi网络,使用printCurrentNet()和printWifiData()函数打印当前网络的信息,包括SSID、BSSID(路由器的MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。
连接到MQTT代理:
使用mqttClient.connect(broker, port);尝试连接到MQTT代理。如果连接失败,则输出错误信息并停止执行。
主循环阶段(loop()函数)
发布MQTT消息:
在主循环中,首先使用mqttClient.beginMessage(topic);开始一个新的MQTT消息,其中topic是消息要发布到的主题。
然后,使用mqttClient.print("Hello EEworld and Digikey!");向消息中添加内容。
最后,使用mqttClient.endMessage();结束并发送消息。
延迟:
使用delay(500);等待500毫秒,然后重复上述过程。这意味着每500毫秒,代码将向MQTT代理发布一条包含"Hello EEworld and Digikey!"的消息。
输出结果:
Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示
通过外部LTR-329环境光传感器,将光照度数据上传到HA并在HA面板上显示,所需搭配器件Arduino UNO R4 WiFi、5591(LTR-329光传感器扩展板)、PRT-14426(Qwiic缆线-50mm)。
连接LTR-329光传感器:
使用5591(LTR-329光传感器扩展板)将LTR-329光传感器与Arduino UNO R4 WiFi连接起来,连接的是J2接口。
连接Qwiic缆线:
使用PRT-14426(Qwiic缆线-50mm)将扩展板与Arduino UNO R4 WiFi的Qwiic连接器连接起来。
Qwiic连接器的设计使得连接更加简便和可靠,即插即用。
// 引入必要的库
#include "Adafruit_LTR329_LTR303.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
// 创建LTR-329传感器的实例
Adafruit_LTR329 ltr = Adafruit_LTR329();
// WiFi网络的SSID和密码
char ssid[] = "CMCC-c6tG";
char pass[] = "mei13728232960";
int status = WL_IDLE_STATUS; // WiFi连接状态
// MQTT代理的地址和端口
const char broker[] = "192.168.1.113";
int port = 1883;
const char command_topic[] = "lux"; // MQTT主题
// 创建WiFi和MQTT客户端实例
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
// 用于存储JSON数据的变量
JSONVar dataObj;
void setup() {
// 初始化串口通信
Serial.begin(115200);
Serial.println("Adafruit LTR-329 advanced test");
// 检查WiFi固件版本
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// 尝试连接到WiFi网络
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000); // 等待10秒
}
// 打印连接到的网络信息
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
// 尝试连接到MQTT代理
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1); // 连接失败则停止执行
}
Serial.println("You are connected to MQTT");
// 检查WiFi模块通信
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
while (true); // 停止执行
}
// 初始化LTR-329传感器
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 printCurrentNet() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
// 打印MAC地址
void printMacAddress(byte mac[]) {
for (int i = 0; i < 6; i++) {
if (i > 0) {
Serial.print(":");
}
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
}
Serial.println();
}
// 打印WiFi数据
void printWifiData() {
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
// 主循环
void loop() {
bool valid;
uint16_t visible_plus_ir, infrared;
if (ltr.newDataAvailable()) { // 检查是否有新数据
valid = ltr.readBothChannels(visible_plus_ir, infrared); // 读取可见光和红外数据
if (valid) { // 如果数据有效
dataObj["brightness"] = visible_plus_ir; // 设置JSON对象中的亮度值
dataObj["psData"] = infrared; // 设置JSON对象中的红外数据
String jsonString = JSON.stringify(dataObj); // 将JSON对象转换为字符串
mqttClient.beginMessage(command_topic); // 开始发送MQTT消息
mqttClient.print(jsonString); // 发送JSON字符串
mqttClient.endMessage(); // 结束消息发送
}
}
delay(500); // 等待500毫秒
}
工作流程:
初始化阶段(setup()函数)
串口初始化:
Serial.begin(115200); 设置串口通信波特率为115200,用于调试信息的输出。
WiFi固件版本检查(可选步骤):
获取并检查WiFi模块的固件版本,若版本过旧,则提示用户进行升级。但请注意,WIFI_FIRMWARE_LATEST_VERSION可能需自定义或根据具体情况调整,且此步骤在实际应用中可能并非必需。
WiFi网络连接:
尝试连接到指定的SSID和密码的WiFi网络。若连接失败,则每10秒重试一次,直至成功连接。
网络信息打印:
连接成功后,利用printCurrentNet()和printWifiData()函数打印当前网络信息,涵盖SSID、BSSID(路由器MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。
MQTT代理连接:
尝试连接到MQTT代理,若连接失败,则输出错误信息并停止执行。
WiFi模块通信检查:
此步骤实际上应在尝试连接WiFi网络之前进行,但在此代码中被置于之后。它检查WiFi模块是否存在且通信正常。若模块不存在或通信失败,则停止执行。然而,更合理的做法是在尝试连接网络前进行此检查,以避免不必要的等待。
LTR-329传感器初始化:
初始化LTR-329光照传感器,并检查其是否成功连接。若未找到传感器,则停止执行。
传感器设置:
配置传感器的增益、积分时间和测量速率,并通过串口打印出当前设置。
主循环阶段(loop()函数)
数据读取与验证:
利用ltr.newDataAvailable()检查传感器是否有新数据可读。若有,则通过ltr.readBothChannels()读取可见光和红外数据,并验证数据的有效性。
数据处理与发送:
若数据有效,则创建一个JSON对象dataObj,并分别将可见光数据和红外数据赋值给其brightness和psData字段。
利用JSON.stringify(dataObj)将JSON对象转换为字符串。
通过MQTT客户端发送此JSON字符串到指定的MQTT主题lux。
延迟:
每次循环结束后,程序会等待500毫秒,然后重复上述过程。
Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示
通过外部SHT40温湿度传感器,将温湿度数据上传到Home Assistant(HA)并在HA面板上显示。
连接SHT40温湿度传感器
使用4885(SHT40温湿度传感器扩展板)将SHT40温湿度传感器与Arduino UNO R4 WiFi连接起来。
SHT40传感器通常具有VCC、GND、SCK(时钟线)和SDA(数据线)四个引脚,正确对应连接到扩展板和Arduino J2上。
代码:
#include "Adafruit_SHT4x.h" // 引入Adafruit SHT4x库
#include <ArduinoMqttClient.h> // 引入Arduino MQTT客户端库
#include <WiFiS3.h> // 引入WiFi库(适用于ESP32)
#include <WiFiClient.h> // 引入WiFi客户端库
#include <Arduino_JSON.h> // 引入Arduino JSON库
Adafruit_SHT4x sht4; // 创建SHT4x对象
char ssid[] = "CMCC-c6tG"; // WiFi网络的SSID
char pass[] = "mei13728232960"; // WiFi网络的密码
int status = WL_IDLE_STATUS; // WiFi连接状态
const char broker[] = "192.168.1.113"; // MQTT代理的IP地址
int port = 1883; // MQTT代理的端口号
const char command_topic[] = "office/sensor1"; // MQTT主题
WiFiClient wifiClient; // 创建WiFi客户端对象
MqttClient mqttClient(wifiClient); // 创建MQTT客户端对象
JSONVar dataObj; // 创建JSON对象用于存储数据
void setup() {
Serial.begin(115200); // 初始化串口通信
// 设置SHT4x的精度为高精度
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;
}
// 关闭SHT4x的加热器
sht4.setHeater(SHT4X_NO_HEATER);
// 打印当前加热器的状态
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println(F("SHT40 Heater turned OFF"));
break;
// 其他加热器状态...
}
// 初始化SHT4x传感器
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); // 打印传感器的序列号
}
Serial.println(F("----------------------------------"));
// 检查WiFi固件版本
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// 连接到WiFi网络
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, pass);
delay(10000); // 等待10秒尝试连接
}
Serial.print("You're connected to the network");
printCurrentNet(); // 打印当前网络的信息
printWifiData(); // 打印WiFi数据
// 连接到MQTT代理
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1); // 如果连接失败,则停止程序
}
Serial.println("You are connected to MQTT");
// 检查WiFi模块是否通信正常
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
while (true); // 如果通信失败,则停止程序
}
}
// 打印当前网络的信息
void printCurrentNet() {
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
// 打印MAC地址
void printMacAddress(byte mac[]) {
for (int i = 0; i < 6; i++) {
if (i > 0) {
Serial.print(":");
}
if (mac[i] < 16) {
Serial.print("0");
}
Serial.print(mac[i], HEX);
}
Serial.println();
}
// 打印WiFi数据
void printWifiData() {
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
sensors_event_t humidity, temp; // 创建用于存储温度和湿度数据的结构体
sht4.getEvent(&humidity, &temp); // 从传感器获取最新的温度和湿度数据
float t = temp.temperature; // 获取温度值
Serial.println("Temp *C = " + String(t)); // 打印温度值
float h = humidity.relative_humidity; // 获取湿度值
Serial.println("Hum. % = " + String(h)); // 打印湿度值
// 将温度和湿度数据添加到JSON对象中
dataObj["temperature"] = t;
dataObj["humidity"] = h;
// 将JSON对象转换为字符串
String jsonString = JSON.stringify(dataObj);
// 通过MQTT发送数据
mqttClient.beginMessage(command_topic);
mqttClient.print(jsonString);
mqttClient.endMessage();
delay(500); // 等待500毫秒后再次读取数据
}
初始化设置:
使用#include指令引入必要的库,包括Adafruit_SHT4x库(用于与SHT4x传感器通信)、ArduinoMqttClient库(用于MQTT通信)、WiFiS3和WiFiClient库(用于WiFi连接)、Arduino_JSON库(用于处理JSON数据)。
创建SHT4x对象sht4,用于与传感器通信。
定义WiFi网络的SSID和密码、MQTT代理的IP地址和端口号、MQTT主题等常量。
创建WiFi客户端对象wifiClient和MQTT客户端对象mqttClient。
创建一个JSON对象dataObj,用于存储将要发送的温湿度数据。
启动和配置:
在setup()函数中,首先初始化串口通信,设置波特率为115200。
配置SHT4x传感器,包括设置高精度模式、关闭加热器,并检查传感器是否正确连接。
检查WiFi固件版本,确保其为最新版本。
尝试连接到WiFi网络,如果连接失败,则每隔10秒重试一次,直到成功连接。
一旦连接到WiFi网络,打印当前网络的信息(SSID、BSSID、信号强度、加密类型)和WiFi数据(IP地址、MAC地址)。
尝试连接到MQTT代理,如果连接失败,则停止程序。
检查WiFi模块是否通信正常,如果不正常,则停止程序。
数据读取和发送:
在loop()函数中,程序进入一个无限循环,不断执行以下步骤:
从SHT4x传感器获取最新的温度和湿度数据。
打印温度和湿度值到串口监视器。
将温度和湿度数据添加到JSON对象dataObj中。
将JSON对象转换为字符串。
通过MQTT客户端mqttClient,将JSON字符串发送到指定的MQTT主题(command_topic)。
等待500毫秒,然后重复上述步骤。
实际输出结果:
概括与总结:
Follow me 第二季第2期各个功能的帖子汇总,主要包括了入门任务、基础任务、进阶任务以及两个扩展任务的详细内容:
入门任务:Blink / 串口打印Hello EEWorld
搭建环境:需要安装Arduino IDE并更新到最新版本,添加Arduino UNO R4 WiFi的开发板支持包。
修改Blink示例代码:通过修改代码实现LED灯以1秒为周期闪烁,同时在串口监视器中打印"Hello EEWorld!"信息。
串口监视器设置:上传代码后,在Arduino IDE中选择正确的波特率(115200),打开串口监视器查看打印信息。
基础任务:点阵/DAC/ADC采集
驱动12x8点阵LED:查看点阵的连接方式与具体功能,将点阵LED的行列控制引脚正确连接到开发板的数字I/O接口,实现滚动显示文本。
DAC生成正弦波:配置DAC接口,设置分辨率、输出范围等参数,使用数学函数生成正弦波的数据点,通过DAC输出到模拟引脚。
OPAMP放大DAC信号:将OPAMP的输入端连接到DAC的输出引脚,配置增益以满足信号放大的需求,使用示波器测量放大效果。
ADC采集数据:设置ADC的采样率、分辨率等参数,将模拟信号连接到ADC的输入引脚,使用analogRead函数读取ADC的值,并打印到串口或其他接口。
进阶任务:MQTT平台HA任务
准备阶段:选择并配置MQTT服务器(如EMQX或Mosquitto),记录服务器的地址、端口和认证信息。
配置Arduino代码:在代码中配置WiFi连接,连接到MQTT服务器,设置MQTT客户端的参数。
发送MQTT消息:在主循环中,使用MQTT客户端发送消息到指定的主题,消息内容可以自定义。
测试与调试:上传Arduino代码,通过串口监视器查看输出信息,确保WiFi和MQTT连接正常。
扩展任务一:利用LTR-329环境光传感器,上传光照度到HA并显示
硬件连接:使用LTR-329环境光传感器扩展板和Qwiic缆线将传感器连接到Arduino UNO R4 WiFi。
读取光照数据:使用Adafruit_LTR329_LTR303库与LTR-329光传感器进行交互,读取光照数据。
发送数据到MQTT:将读取到的光照数据转换为JSON格式,通过MQTT协议发送到MQTT代理。
集成到Home Assistant:在Home Assistant中配置接收MQTT消息的设备,将光照数据显示在HA面板上。
扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示
硬件连接:使用SHT40温湿度传感器扩展板将传感器连接到Arduino UNO R4 WiFi,正确对应连接引脚。
读取温湿度数据:安装Adafruit_SHT4x库,使用库中的函数与SHT40传感器通信,读取温度和湿度数据。
发送数据到MQTT:将读取到的温湿度数据添加到JSON对象中,通过MQTT客户端发送到指定的主题。
在Home Assistant中显示:在Home Assistant中配置设备,接收MQTT消息并显示温湿度数据。
总结
从入门到进阶的Arduino编程和硬件连接技能,包括LED闪烁、串口通信、模拟信号采集与处理、MQTT协议应用以及传感器数据上传等。
通过完成这些任务,可以深入了解Arduino UNO R4 WiFi开发板的功能和应用场景,提高编程和硬件连接能力。
这些任务也为进一步学习和应用Arduino技术打下了坚实的基础。
本帖最后由 meiyao 于 2024-10-31 21:37 编辑