meiyao 发表于 2024-10-30 15:52

Follow me 第二季第2期+任务汇总

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

<p>下面是我Follow me 第二季第2期各个功能的贴子,具体的细节可以进行查看。</p>

<p>Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld!</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1294799-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1294799-1-1.html</a></p>

<p>Follow me 第二季第2期任务基础任务点阵/DAC/ADC采集</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1294800-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1294800-1-1.html</a></p>

<p><a href="https://bbs.eeworld.com.cn/thread-1295342-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1295342-1-1.html</a></p>

<p>Follow me 第二季第2期进阶任务MQTT平台HA任务</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1295082-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1295082-1-1.html</a></p>

<p>Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1295431-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1295431-1-1.html</a></p>

<p>Follow me 第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示</p>

<p><a href="https://bbs.eeworld.com.cn/thread-1295434-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-1295434-1-1.html</a></p>

<p>&nbsp;</p>

<p>视频:</p>

<p>fa157f1c900550afff4ee4e473f65689</p>

<p>36e188073c5598033c40e07049ddec06<br />
&nbsp;</p>

<p>&nbsp;</p>

<p><strong>Follow me 第二季第2期任务入门任务+Blink / 串口打印Hello EEWorld!</strong></p>

<p>LED闪烁代码:</p>

<pre>
<code>void setup() {
// 初始化数字引脚LED_BUILTIN为输出状态
pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
digitalWrite(LED_BUILTIN, HIGH);   // 打开LED灯
delay(1000);                     // 等待一秒
digitalWrite(LED_BUILTIN, LOW);    // 关闭LED灯
delay(1000);                     // 等待一秒
}
</code></pre>

<p> &nbsp;</p>

<p>工作流程:</p>

<p>开始(Start)</p>

<p>流程图的起点。</p>

<p>初始化</p>

<p>调用setup()函数。</p>

<p>设置LED_BUILTIN引脚为输出模式(pinMode(LED_BUILTIN, OUTPUT))。</p>

<p>主循环(Loop)</p>

<p>调用loop()函数,这是一个无限循环。</p>

<p>打开LED</p>

<p>在loop()中,首先调用digitalWrite(LED_BUILTIN, HIGH)将LED灯打开。</p>

<p>等待一秒</p>

<p>调用delay(1000),等待1000毫秒(即1秒)。</p>

<p>关闭LED</p>

<p>调用digitalWrite(LED_BUILTIN, LOW)将LED灯关闭。</p>

<p>再次等待一秒</p>

<p>再次调用delay(1000),等待1000毫秒(即1秒)。</p>

<p>回到主循环</p>

<p>流程回到loop()的开始,重复步骤4到7。</p>

<p>结束(End)</p>

<p>理论上,由于这是一个无限循环,流程不会真正结束,但在流程图中可以用一个圆形结束符号表示流程图的视觉结束点。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>串口打印Hello EEWorld!</p>

<pre>
<code>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!");
}
</code></pre>

<p>输出结果:</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202409/25/233427azw999co879d8wds.png" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong>Follow me 第二季第2期任务基础任务DAC/ADC采集 &nbsp;</strong></p>

<p>&nbsp;</p>

<p>驱动12x8点阵LED</p>

<p dir="ltr">Arduino UNO R4 WiFi开发板上点阵LED的行列控制引脚正确连接到开发板的数字I/O接口。</p>

<p dir="ltr">在Arduino IDE中编写代码,使用digitalWrite或shiftOut等函数控制点阵LED的行列,实现显示功能。</p>

<p dir="ltr">通过循环或数组来控制LED的亮灭,形成图案或文字。</p>

<p dir="ltr">&nbsp;</p>

<p dir="ltr">下面代码中,显示&lsquo;MY&rsquo;。</p>

<pre>
<code>#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"

ArduinoLEDMatrix matrix;


byte frame = {
{ 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() {

}</code></pre>

<p>&nbsp;</p>

<p>输出结果:</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202409/26/000458l7yyuuuoouu9zbyy.png.thumb.jpg" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>用DAC生成正弦波:</p>

<p dir="ltr">Arduino UNO R4 WiFi开发板上的DAC接口需要被正确配置。根据开发板的文档,设置DAC的分辨率、输出范围等参数。</p>

<p dir="ltr">生成正弦波:编写代码,使用数学函数(如sin)生成正弦波的数据点。将数据点通过DAC输出到模拟引脚。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<pre>
<code>#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);
}
</code></pre>

<p>#include &quot;analogWave.h&quot;:这行代码包含了一个名为analogWave的头文件,这个头文件中可能定义了用于生成模拟波形的类和相关函数。<br />
analogWave wave(DAC);:使用DAC引脚实例化一个名为wave的analogWave对象。这意味着这个对象将使用指定的DAC引脚来输出模拟波形。<br />
float freq = 0.5;:设置一个初始频率为0.5的浮点数变量freq。这个频率可能用于控制生成的正弦波的周期。<br />
void setup() {... }:<br />
Serial.begin(115200);:初始化串口通信,设置波特率为 115200。<br />
wave.sine(freq);:使用wave对象调用sine函数,传入初始频率freq,以生成正弦波。<br />
wave.amplitude(0.5);:设置生成的正弦波的幅度为 0.5。<br />
void loop() {... }:<br />
printf(&quot;%d\n&quot;,analogRead(A4));:读取A4引脚的模拟值,并通过串口打印出来。<br />
delay(100);:延迟 100 毫秒,以控制程序的执行速度。</p>

<p>主要功能是使用一个名为analogWave的类来生成正弦波,并通过DAC引脚输出。代码在主循环中不断读取A4引脚的模拟值并通过串口打印出来。</p>

<p>&nbsp;</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202409/27/234841niodo170kwtih911.jpg" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>用OPAMP放大DAC信号</p>

<p>&nbsp;</p>

<p>生成一个正弦波,并可以通过读取模拟输入引脚&nbsp;A5&nbsp;的值来动态调整正弦波的频率,然后将更新后的频率信息打印到串口监视器上。</p>

<p>&nbsp;</p>

<pre>
<code>#include "analogWave.h" // Include the library for analog waveform generation
#include &lt;OPAMP.h&gt;
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
}

</code></pre>

<p>使用的工具与器件有:</p>

<p>电阻10K--1个</p>

<p>电阻30K--1个</p>

<p>手持示波器--一台。</p>

<p>&nbsp;</p>

<p>电阻连接示意图:</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线</p>

<p>代码的主要功能是通过读取模拟输入引脚 A5 的值来动态调整正弦波的频率,并将该频率信息打印到串口监视器上。代码使用 analogWave 类在指定的 DAC 引脚上生成正弦波,并通过读取 A4 引脚的模拟值进行一些可能的后续处理(这里只是将其打印出来)。</p>

<pre>
<code>#include "analogWave.h" // Include the library for analog waveform generation
#include &lt;OPAMP.h&gt;
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
}

</code></pre>

<p>程序工作流程:</p>

<p>开始</p>

<p>标记为&ldquo;开始&rdquo;的圆形节点。</p>

<p>初始化</p>

<p>包含库:analogWave.h 和 &lt;OPAMP.h&gt;</p>

<p>创建实例:analogWave wave(DAC);</p>

<p>设置变量:int freq = 10; 和 int reading = 0;</p>

<p>设置OPAMP:OPAMP.begin(OPAMP_SPEED_HIGHSPEED);</p>

<p>初始化串口:Serial.begin(115200);</p>

<p>设置DAC分辨率:analogWriteResolution(14);</p>

<p>生成初始波形:wave.sine(freq);</p>

<p>标记为&ldquo;处理框&rdquo;或&ldquo;步骤&rdquo;的矩形节点,包含上述初始化步骤。</p>

<p>主循环</p>

<p>标记为&ldquo;循环开始&rdquo;的圆形节点(通常有一个小箭头指向它,表示循环)。</p>

<p>读取A5引脚</p>

<p>读取模拟值:freq = map(analogRead(A5), 0, 1024, 0, 10000);</p>

<p>标记为&ldquo;处理框&rdquo;的矩形节点,显示读取和映射操作。</p>

<p>打印频率</p>

<p>输出到串口:Serial.println(&quot;Frequency is now &quot; + String(freq) + &quot; hz&quot;);</p>

<p>标记为&ldquo;输出&rdquo;的菱形节点,显示串口输出。</p>

<p>读取A4引脚</p>

<p>读取模拟值:reading = analogRead(A4);</p>

<p>输出到串口:Serial.print(reading);</p>

<p>标记为&ldquo;处理框&rdquo;的矩形节点,显示读取和输出操作。</p>

<p>设置波形频率</p>

<p>更新波形频率:wave.freq(freq);</p>

<p>标记为&ldquo;处理框&rdquo;的矩形节点,显示频率更新操作。</p>

<p>延迟</p>

<p>延时:delay(50);</p>

<p>标记为&ldquo;延迟&rdquo;的菱形节点,显示延迟时间。</p>

<p>循环结束</p>

<p>回到&ldquo;主循环&rdquo;的圆形节点,形成闭环。</p>

<p>结束</p>

<p>标记为&ldquo;结束&rdquo;的圆形节点。</p>

<p>输出效果图:</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202410/03/221523mpuzva287mvswpwm.png.thumb.jpg" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong>Follow me 第二季第2期进阶任务MQTT平台HA任务 &nbsp;</strong></p>

<p>&nbsp;</p>

<p>MQTT服务器:EMQX或Mosquitto,可以选择安装一个MQTT服务器,或者在云服务上使用一个现有的MQTT服务。</p>

<p>配置MQTT服务器:根据MQTT服务器的文档,配置必要的参数,。记录MQTT服务器的地址、端口和认证信息(用户名和密码)。</p>

<pre>
<code>// 引入必要的库
#include &lt;ArduinoMqttClient.h&gt;// 注意:这个库可能不是标准的Arduino库,需要确认其来源和兼容性
#include &lt;WiFiS3.h&gt;             // 这个库可能也不是标准的,通常我们使用&lt;WiFi.h&gt;
#include &lt;WiFiClient.h&gt;         // 用于创建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 &lt; 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;
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 &lt; 6; i++) {
    if (i &gt; 0) {
      Serial.print(":");// 在MAC地址的每个字节之间打印冒号
    }
    // 如果MAC地址的某个字节小于16,则在前面打印0
    if (mac &lt; 16) {
      Serial.print("0");
    }
    Serial.print(mac, HEX);// 以十六进制格式打印MAC地址的每个字节
}
Serial.println();
}

// 打印WiFi数据(IP地址和MAC地址)
void printWifiData() {
// 打印开发板的IP地址
IPAddress ip = WiFi.localIP();
Serial.print("IP 地址: ");
Serial.println(ip);

// 打印开发板的MAC地址
byte mac;
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);
}
</code></pre>

<p>工作流程:</p>

<p>初始化阶段(setup()函数)</p>

<p>串口初始化:</p>

<p>Serial.begin(9600); 初始化串口通信,波特率设为9600,用于调试信息输出。</p>

<p>WiFi模块检查:</p>

<p>通过WiFi.status()检查WiFi模块是否存在。如果不存在,则输出错误信息并停止执行。</p>

<p>WiFi固件版本检查(可选):</p>

<p>获取WiFi固件版本,并与最新版本进行比较(注意:WIFI_FIRMWARE_LATEST_VERSION可能需要自定义或根据实际情况调整)。如果版本过旧,则提示用户升级固件。</p>

<p>连接到WiFi网络:</p>

<p>使用WiFi.begin(ssid, pass);尝试连接到指定的SSID和密码。如果连接失败,则每10秒重试一次,直到成功为止。</p>

<p>打印网络信息:</p>

<p>一旦连接到WiFi网络,使用printCurrentNet()和printWifiData()函数打印当前网络的信息,包括SSID、BSSID(路由器的MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。</p>

<p>连接到MQTT代理:</p>

<p>使用mqttClient.connect(broker, port);尝试连接到MQTT代理。如果连接失败,则输出错误信息并停止执行。</p>

<p>主循环阶段(loop()函数)</p>

<p>发布MQTT消息:</p>

<p>在主循环中,首先使用mqttClient.beginMessage(topic);开始一个新的MQTT消息,其中topic是消息要发布到的主题。</p>

<p>然后,使用mqttClient.print(&quot;Hello EEworld and Digikey!&quot;);向消息中添加内容。</p>

<p>最后,使用mqttClient.endMessage();结束并发送消息。</p>

<p>延迟:</p>

<p>使用delay(500);等待500毫秒,然后重复上述过程。这意味着每500毫秒,代码将向MQTT代理发布一条包含&quot;Hello EEworld and Digikey!&quot;的消息。</p>

<p>&nbsp;</p>

<p>输出结果:</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong>Follow me 第二季第2期+ 扩展任务一利用LTR-329 环境光传感器,上传光照度到HA并显示</strong></p>

<p>&nbsp;</p>

<p>通过外部LTR-329环境光传感器,将光照度数据上传到HA并在HA面板上显示,所需搭配器件Arduino UNO R4 WiFi、5591(LTR-329光传感器扩展板)、PRT-14426(Qwiic缆线-50mm)。</p>

<p dir="ltr">连接LTR-329光传感器:</p>

<p dir="ltr">使用5591(LTR-329光传感器扩展板)将LTR-329光传感器与Arduino UNO R4 WiFi连接起来,连接的是J2接口。</p>

<p dir="ltr">连接Qwiic缆线:</p>

<p dir="ltr">使用PRT-14426(Qwiic缆线-50mm)将扩展板与Arduino UNO R4 WiFi的Qwiic连接器连接起来。</p>

<p dir="ltr">Qwiic连接器的设计使得连接更加简便和可靠,即插即用。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<pre>
<code>// 引入必要的库
#include "Adafruit_LTR329_LTR303.h"
#include &lt;ArduinoMqttClient.h&gt;
#include &lt;WiFiS3.h&gt;
#include &lt;WiFiClient.h&gt;
#include &lt;Arduino_JSON.h&gt;

// 创建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 &lt; 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(&amp;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;
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 &lt; 6; i++) {
    if (i &gt; 0) {
      Serial.print(":");
    }
    if (mac &lt; 16) {
      Serial.print("0");
    }
    Serial.print(mac, HEX);
}
Serial.println();
}

// 打印WiFi数据
void printWifiData() {
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
byte mac;
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毫秒
}
</code></pre>

<p>工作流程:</p>

<p>初始化阶段(setup()函数)</p>

<p>串口初始化:</p>

<p>Serial.begin(115200); 设置串口通信波特率为115200,用于调试信息的输出。</p>

<p>WiFi固件版本检查(可选步骤):</p>

<p>获取并检查WiFi模块的固件版本,若版本过旧,则提示用户进行升级。但请注意,WIFI_FIRMWARE_LATEST_VERSION可能需自定义或根据具体情况调整,且此步骤在实际应用中可能并非必需。</p>

<p>WiFi网络连接:</p>

<p>尝试连接到指定的SSID和密码的WiFi网络。若连接失败,则每10秒重试一次,直至成功连接。</p>

<p>网络信息打印:</p>

<p>连接成功后,利用printCurrentNet()和printWifiData()函数打印当前网络信息,涵盖SSID、BSSID(路由器MAC地址)、信号强度(RSSI)、加密类型,以及开发板的IP地址和MAC地址。</p>

<p>MQTT代理连接:</p>

<p>尝试连接到MQTT代理,若连接失败,则输出错误信息并停止执行。</p>

<p>WiFi模块通信检查:</p>

<p>此步骤实际上应在尝试连接WiFi网络之前进行,但在此代码中被置于之后。它检查WiFi模块是否存在且通信正常。若模块不存在或通信失败,则停止执行。然而,更合理的做法是在尝试连接网络前进行此检查,以避免不必要的等待。</p>

<p>LTR-329传感器初始化:</p>

<p>初始化LTR-329光照传感器,并检查其是否成功连接。若未找到传感器,则停止执行。</p>

<p>传感器设置:</p>

<p>配置传感器的增益、积分时间和测量速率,并通过串口打印出当前设置。</p>

<p>主循环阶段(loop()函数)</p>

<p>数据读取与验证:</p>

<p>利用ltr.newDataAvailable()检查传感器是否有新数据可读。若有,则通过ltr.readBothChannels()读取可见光和红外数据,并验证数据的有效性。</p>

<p>数据处理与发送:</p>

<p>若数据有效,则创建一个JSON对象dataObj,并分别将可见光数据和红外数据赋值给其brightness和psData字段。</p>

<p>利用JSON.stringify(dataObj)将JSON对象转换为字符串。</p>

<p>通过MQTT客户端发送此JSON字符串到指定的MQTT主题lux。</p>

<p>延迟:</p>

<p>每次循环结束后,程序会等待500毫秒,然后重复上述过程。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><br />
<strong>Follow&nbsp;me&nbsp;第二季第2期+扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示</strong></p>

<p>通过外部SHT40温湿度传感器,将温湿度数据上传到Home Assistant(HA)并在HA面板上显示。</p>

<p dir="ltr">连接SHT40温湿度传感器</p>

<p dir="ltr">使用4885(SHT40温湿度传感器扩展板)将SHT40温湿度传感器与Arduino UNO R4 WiFi连接起来。</p>

<p dir="ltr">SHT40传感器通常具有VCC、GND、SCK(时钟线)和SDA(数据线)四个引脚,正确对应连接到扩展板和Arduino J2上。</p>

<p>代码:</p>

<pre>
<code>#include "Adafruit_SHT4x.h" // 引入Adafruit SHT4x库
#include &lt;ArduinoMqttClient.h&gt; // 引入Arduino MQTT客户端库
#include &lt;WiFiS3.h&gt; // 引入WiFi库(适用于ESP32)
#include &lt;WiFiClient.h&gt; // 引入WiFi客户端库
#include &lt;Arduino_JSON.h&gt; // 引入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(&amp;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 &lt; 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;
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 &lt; 6; i++) {
    if (i &gt; 0) {
      Serial.print(":");
    }
    if (mac &lt; 16) {
      Serial.print("0");
    }
    Serial.print(mac, HEX);
}
Serial.println();
}

// 打印WiFi数据
void printWifiData() {
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
byte mac;
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}

void loop() {
sensors_event_t humidity, temp; // 创建用于存储温度和湿度数据的结构体
sht4.getEvent(&amp;humidity, &amp;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毫秒后再次读取数据
}
</code></pre>

<p>&nbsp;</p>

<p>初始化设置:</p>

<p>使用#include指令引入必要的库,包括Adafruit_SHT4x库(用于与SHT4x传感器通信)、ArduinoMqttClient库(用于MQTT通信)、WiFiS3和WiFiClient库(用于WiFi连接)、Arduino_JSON库(用于处理JSON数据)。</p>

<p>创建SHT4x对象sht4,用于与传感器通信。</p>

<p>定义WiFi网络的SSID和密码、MQTT代理的IP地址和端口号、MQTT主题等常量。</p>

<p>创建WiFi客户端对象wifiClient和MQTT客户端对象mqttClient。</p>

<p>创建一个JSON对象dataObj,用于存储将要发送的温湿度数据。</p>

<p>启动和配置:</p>

<p>在setup()函数中,首先初始化串口通信,设置波特率为115200。</p>

<p>配置SHT4x传感器,包括设置高精度模式、关闭加热器,并检查传感器是否正确连接。</p>

<p>检查WiFi固件版本,确保其为最新版本。</p>

<p>尝试连接到WiFi网络,如果连接失败,则每隔10秒重试一次,直到成功连接。</p>

<p>一旦连接到WiFi网络,打印当前网络的信息(SSID、BSSID、信号强度、加密类型)和WiFi数据(IP地址、MAC地址)。</p>

<p>尝试连接到MQTT代理,如果连接失败,则停止程序。</p>

<p>检查WiFi模块是否通信正常,如果不正常,则停止程序。</p>

<p>数据读取和发送:</p>

<p>在loop()函数中,程序进入一个无限循环,不断执行以下步骤:</p>

<p>从SHT4x传感器获取最新的温度和湿度数据。</p>

<p>打印温度和湿度值到串口监视器。</p>

<p>将温度和湿度数据添加到JSON对象dataObj中。</p>

<p>将JSON对象转换为字符串。</p>

<p>通过MQTT客户端mqttClient,将JSON字符串发送到指定的MQTT主题(command_topic)。</p>

<p>等待500毫秒,然后重复上述步骤。</p>

<p>&nbsp;</p>

<p>实际输出结果:</p>

<p><img src="https://bbs.eeworld.com.cn/data/attachment/forum/202410/07/235122iaswawlwwwdhme63.png.thumb.jpg" /></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>概括与总结:</p>

<p>Follow me 第二季第2期各个功能的帖子汇总,主要包括了入门任务、基础任务、进阶任务以及两个扩展任务的详细内容:</p>

<p>入门任务:Blink / 串口打印Hello EEWorld</p>

<p>搭建环境:需要安装Arduino IDE并更新到最新版本,添加Arduino UNO R4 WiFi的开发板支持包。</p>

<p>修改Blink示例代码:通过修改代码实现LED灯以1秒为周期闪烁,同时在串口监视器中打印&quot;Hello EEWorld!&quot;信息。</p>

<p>串口监视器设置:上传代码后,在Arduino IDE中选择正确的波特率(115200),打开串口监视器查看打印信息。</p>

<p>基础任务:点阵/DAC/ADC采集</p>

<p>驱动12x8点阵LED:查看点阵的连接方式与具体功能,将点阵LED的行列控制引脚正确连接到开发板的数字I/O接口,实现滚动显示文本。</p>

<p>DAC生成正弦波:配置DAC接口,设置分辨率、输出范围等参数,使用数学函数生成正弦波的数据点,通过DAC输出到模拟引脚。</p>

<p>OPAMP放大DAC信号:将OPAMP的输入端连接到DAC的输出引脚,配置增益以满足信号放大的需求,使用示波器测量放大效果。</p>

<p>ADC采集数据:设置ADC的采样率、分辨率等参数,将模拟信号连接到ADC的输入引脚,使用analogRead函数读取ADC的值,并打印到串口或其他接口。</p>

<p>进阶任务:MQTT平台HA任务</p>

<p>准备阶段:选择并配置MQTT服务器(如EMQX或Mosquitto),记录服务器的地址、端口和认证信息。</p>

<p>配置Arduino代码:在代码中配置WiFi连接,连接到MQTT服务器,设置MQTT客户端的参数。</p>

<p>发送MQTT消息:在主循环中,使用MQTT客户端发送消息到指定的主题,消息内容可以自定义。</p>

<p>测试与调试:上传Arduino代码,通过串口监视器查看输出信息,确保WiFi和MQTT连接正常。</p>

<p>扩展任务一:利用LTR-329环境光传感器,上传光照度到HA并显示</p>

<p>硬件连接:使用LTR-329环境光传感器扩展板和Qwiic缆线将传感器连接到Arduino UNO R4 WiFi。</p>

<p>读取光照数据:使用Adafruit_LTR329_LTR303库与LTR-329光传感器进行交互,读取光照数据。</p>

<p>发送数据到MQTT:将读取到的光照数据转换为JSON格式,通过MQTT协议发送到MQTT代理。</p>

<p>集成到Home Assistant:在Home Assistant中配置接收MQTT消息的设备,将光照数据显示在HA面板上。</p>

<p>扩展任务二:通过外部SHT40温湿度传感器,上传HA并显示</p>

<p>硬件连接:使用SHT40温湿度传感器扩展板将传感器连接到Arduino UNO R4 WiFi,正确对应连接引脚。</p>

<p>读取温湿度数据:安装Adafruit_SHT4x库,使用库中的函数与SHT40传感器通信,读取温度和湿度数据。</p>

<p>发送数据到MQTT:将读取到的温湿度数据添加到JSON对象中,通过MQTT客户端发送到指定的主题。</p>

<p>在Home Assistant中显示:在Home Assistant中配置设备,接收MQTT消息并显示温湿度数据。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<div></div>

<div>所用器件与开发板:</div>

<div> &nbsp;</div>

<p>总结</p>

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

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

<p>这些任务也为进一步学习和应用Arduino技术打下了坚实的基础。</p>
页: [1]
查看完整版本: Follow me 第二季第2期+任务汇总