[经验分享] Follow me 第二季第2期+任务汇总

meiyao   2024-10-30 15:52 楼主

下面是我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

 

视频:

10月30日

39cd4453d43be8d28277cbf94643806a

 

 

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);                       // 等待一秒  
}

image.png  

工作流程:

开始(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个

手持示波器--一台。

 

电阻连接示意图:

  image.png

 

 

用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!"的消息。

 

输出结果:

image.png  

 

 

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连接器的设计使得连接更加简便和可靠,即插即用。

 

image.png  

// 引入必要的库  
#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 UNO R4 WiFi.zip (7.78 KB)
(下载次数: 1, 2024-10-31 20:51 上传)
所用器件与开发板:
4ff0df2865385d04265538f2f47b496.jpg  

总结

从入门到进阶的Arduino编程和硬件连接技能,包括LED闪烁、串口通信、模拟信号采集与处理、MQTT协议应用以及传感器数据上传等。

通过完成这些任务,可以深入了解Arduino UNO R4 WiFi开发板的功能和应用场景,提高编程和硬件连接能力。

这些任务也为进一步学习和应用Arduino技术打下了坚实的基础。

本帖最后由 meiyao 于 2024-10-31 21:37 编辑

回复评论

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