- 2024-11-04
-
加入了学习《Follow me 第二季第2期汇总的视频》,观看 Follow me 第二季第2期汇总的视频
-
上传了资料:
Arduino UNO R4 WiFi工程代码代码
- 2024-11-01
-
加入了学习《Follow me 第二季第2期汇总的视频》,观看 Follow me 第二季第2期汇总的视频
- 2024-10-23
-
发表了主题帖:
【Follow me第二季第2期】+ 作品提交整合贴
本帖最后由 LTLyaoni 于 2024-11-4 00:14 编辑
大家好,我是LTLyaoni非常荣幸能参与到电子工程世界和得捷电子联合举办的“Follow me”第二期活动中来。今天,我将和大家分享我的项目进展和心得体会。
物料展示
这次我拿到的开发板是Arduino Uno R4 WiFi,还有LTR-329光照传感器、SHT40温湿度传感器。
视频如下:
设计思路
入门任务(任务1)
目标:在原理图中确认IO端口,使用GPIO控制LED闪烁。
基础任务(任务2)
目标:读懂Arduino官方文档,掌握LED矩阵、ADC和运算放大器的使用。
进阶任务(任务3)
目标:掌握ESP32S3 WiFi库和MQTT库的使用,配置HA实体。
任务实现详情
入门任务一:搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
帖子地址:【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】
物料:
Arduino Uno R4 WiFi。后面的所有的任务都用到Arduino Uno R4 WiFi,实物上图有
流程图
代码如下
// 定义LED连接的引脚
int ledPin = 13;
void setup() {
Serial.begin(9600); // 初始化串口通信
pinMode(ledPin, OUTPUT);
}
void loop() {
Serial.println("LED状态: ON");
digitalWrite(ledPin, HIGH);
Serial.println("Hello World!");
Serial.println("Hello DigiKey and EEWorld!");
delay(500);
Serial.println("LED状态: OFF");
digitalWrite(ledPin, LOW);
Serial.println("Hello World!");
Serial.println("Hello DigiKey and EEWorld!");
delay(500);
}
串口打印HelloWorld
上述代码同时做了串口打印功能,以便我们可以看到LED灯的状态和Hello world的输出:
代码编译烧录后,打开IDE自带的串口监视器,设置和代码相同的波特率,即可看到相应的串口输出
基础任务:
驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
帖子地址:【Follow me第二季第2期】+ 基础任务【点亮LED矩阵, 使用运算放大器放大DAC信号】
流程图:
Task 1 : 点亮板载Led matrix
Step 1 : 打开Arduino 的 demo, 选择LED matrix.
第一个代码是使用LED的frame的方式进行点亮的, 即在数组中定义每一个LED灯的状态, 通过加载帧的方式实现的. 相关的数组在frames.h 里
const uint32_t chip[] = {
0x1503f811,
0x3181103,
0xf8150000
};
const uint32_t danger[] = {
0x400a015,
0x1502082,
0x484047fc
};
const uint32_t happy[] = {
0x19819,
0x80000001,
0x81f8000
};
const uint32_t heart[] = {
0x3184a444,
0x44042081,
0x100a0040
};
Task 2: 使用 DAC 输出正弦波
Step 1 : 在Arduino IDE中并没有发现,关于DAC输出的Demo程序, 因此我们需要查询一下官方文档看下如何使用Arduino 的DAC功能, 根据官方文档提供的代码,我们可以很快的实现DAC输出的功能
流程图:
/*
SineWave
Generates a pre-generated sawtooth-waveform.
See the full documentation here:
https://docs.arduino.cc/tutorials/uno-r4-wifi/dac
*/
#include "analogWave.h" // Include the library for analog waveform generation
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
void setup() {
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
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");
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(1000); // Delay for one second before repeating
}
由于DAC的输出是A0 端口, 我们可以手动调整A5的ADC电压来动态调整A0的DAC输出频率. 如果使用示波器连接A0的话, 那么A0的输出将会是如下图所示
Task 3 : 对DAC信号使用运算放大器进行放大, 然后使用ADC进行采集并且展示.
Arduino uno 4的官方文档写的比较详细, 如果想使用运算放大器对信号进行放大的话只需要构建好以下的电路.
我们在官方的代码上稍微做一点修改(仅仅是在代码的第八行开启了运算放大器)
#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
void setup() {
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
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");
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(50); // Delay for one second before repeating
}
之后我们讲代码烧录到系统中之后再使用示波器进行电压的采集的时候发现现在的平均电压已经被运算放大器放大到了之前的两倍左右
Task 3 : 使用ADC 采集DAC输出,并且显示.
我们可以在上述代码上做一点简单的修改使其DAC的输出作为ADC的输入(电路), 这样的话,当我们打印出数据的时候, 串口绘图功能则会自动绘制ADC的采集曲线,代码如下所示
#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
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
}
进阶任务:通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
帖子地址:【Follow me第二季第2期】+ 进阶任务 :使用Arduino uno r4 接入Home assistant
Task 1 : 使用Uno r4 连接Wifi
Arduino IDE 提供了Arduino uno r4 的wifi连接的example, 我们可以根据下面的截图进行查找
在上述的提供的代码中我们只需要修改wifi的 ssid 和 pass 即可连接到WIFI上, 我这里连接的是2.4G的wifi
当我们把代码烧录到开发版中之后,我们会发现串口控制台已经可以正确的获取到IP地址.
当你控制台出现IP地址的时候即为连接WIFI成功.
Task 2 : 使用MQTT连接到HA
由于MQTT的便携性和容易集成等优点,因为我们可以在HA中集成MQTT服务,使其监视某一个主题从而实现消息的上报和下发. 因为我们本章节的任务非常简单, 即使用UNO r4 连接到MQTT的某个Topic 然后在HA中监视这个主题就算成功.
我们只需要在配置集成中, 监视这个test的主题,然后使用Uno r4 向这个主题发送消息即可.
Task 3 : 使用UNO R4 ,连接MQTT发送消息.
但是很不巧Arduino uno r4 并没有提供MQTT的Demo, 所以我们需要看看官方有没有什么推荐的. 好巧不巧, 我在https://docs.arduino.cc/tutorials/uno-wifi-rev2/uno-wifi-r2-mqtt-device-to-device/上找到了如何使用MQTT的方式, 即使用Mqtt Client.
虽然它代码写的比较长,但是其核心的逻辑还是使用ArduinoMqttClientt对象使用WIFI client 对象来连接MQTT. 那么我们便可以在上述的代码中做出以下的修改
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
char ssid[] = "你的Wi-Fi名称";
char pass[] = "你的wifi密码";
int status = WL_IDLE_STATUS;
const char broker[] = "你的MQTT地址";
int port = 端口;
const char topic[] = "主题";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
void setup() {
Serial.begin(115200);
while (!Serial) {
}
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
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");
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
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();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
mqttClient.beginMessage(topic);
mqttClient.print("Message from UNO R4");
mqttClient.endMessage();
delay(500);
}
注意上述的代码是在匿名的情况下连接到MQTT服务器的,如果你的MQTT服务器不支持匿名连接的话你需要自己调用mqttclinen的设置用户名和密码的function来认证你的连接. 此时我们打开HA的话我们开启监听即可收到来自Uno r4的消息 (注意HA中MQTT监视的topic是test主题,但是上述代码中我并没有写, 方便大家复用我的代码)
我们有一个智能灯,我们可以通过发送命令来控制它。如果我们想让灯关掉,我们就发送一个“OFF”的指令;如果我们想让灯打开,我们就发送一个“ON”的指令。
现在,虽然我们可以通过这些指令来控制灯的开关,但是家里的智能家居系统(我们称之为HA)并不知道灯的状态已经改变了。为了让HA知道灯的状态,我们还需要发送一个额外的指令,告诉它灯现在是关着的(“OFF”)。
为了解决这个问题,我们可以稍微调整一下代码,让它每隔一秒钟就自动切换灯的状态。这样,灯就会自动地一会儿开,一会儿关,同时HA也会实时更新灯的状态,知道灯现在是开着还是关着。这样,我们就可以确保灯的状态和HA中的显示是一致的。
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
char ssid[] = "ssid";
char pass[] = "pass";
int status = WL_IDLE_STATUS;
const char broker[] = "broker";
int port = 1883;
const char command_topic[] = "home/bedroom/switch1/set";
const char state_topic[] = "home/bedroom/switch1";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
bool index = true;
void setup() {
Serial.begin(9600);
while (!Serial) {
}
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
mqttClient.setUsernamePassword("","");
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");
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
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();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
if(index)
{
mqttClient.beginMessage(command_topic);
mqttClient.print("ON");
mqttClient.endMessage();
mqttClient.beginMessage(state_topic);
mqttClient.print("ON");
mqttClient.endMessage();
Serial.print("ON\n");
}else {
mqttClient.beginMessage(command_topic);
mqttClient.print("OFF");
mqttClient.endMessage();
mqttClient.beginMessage(state_topic);
mqttClient.print("OFF");
mqttClient.endMessage();
Serial.print("OFF\n");
}
index = !index;
delay(1000);
}
拓展任务一:扩展任务一 使用LTR-329 环境光传感器,上传到HA并显示
流程图如下:
这个拓展任务听起来挺有意思的,我们可以一步步来搞定。这个任务主要就是三件事:
读取LTR-329传感器数据:首先,我们要用我们的Arduino R4来读取LTR-329光照传感器的数据。这个传感器能帮我们测量环境光和红外光,我们需要用到专门的库来和它通信,获取数据。
配置HA实体:然后,我们要在Home Assistant(HA)里设置实体。实体就是HA用来识别和控制设备的一种方式。我们需要告诉HA,我们有一个光照传感器,并且告诉它这个传感器的数据要怎么显示。
上传数据到HA:最后,我们要做的是把从LTR-329传感器读取到的数据上传到HA。这样,我们就可以在HA的界面上实时看到光照数据,还可以用这些数据来控制家里的其他智能设备。
既然我们已经在进阶任务里搞定了MQTT和WIFI,这次我们可以直接用那些代码,不用再从头开始。这样我们就可以更高效地完成任务了。
读取LTR-329传感器数据和上传数据到HA的代码如下
#include "Adafruit_LTR329_LTR303.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
Adafruit_LTR329 ltr = Adafruit_LTR329();
char ssid[] = "ssid";
char pass[] = "pass";
int status = WL_IDLE_STATUS;
const char broker[] = "broker";
int port = 1883;
const char command_topic[] = "LTR303";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
JSONVar dataObj;
void setup() {
Serial.begin(115200);
Serial.println("Adafruit LTR-329 advanced test");
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
mqttClient.setUsernamePassword("","");
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");
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
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() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
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();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
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;
dataObj["ir_data"] = infrared;
Serial.print("brightness: ");
Serial.print(infrared);
Serial.print("\n");
Serial.print("ir_data: ");
Serial.print(visible_plus_ir);
Serial.print("\n");
String jsonString = JSON.stringify(dataObj);
mqttClient.beginMessage(command_topic);
mqttClient.print(jsonString);
mqttClient.endMessage();
}
}
delay(500);
}
而配置HA实体的,有些版本不一样,我是如下们可以作为参考
sensor:
- platform: mqtt
name: "光传感器IR"
value_template: "{{ value_json.ir_data }}"
state_topic: "LTR303"
unit_of_measurement: "LTR303"
unique_id: "LTR303_IR"
- platform: mqtt
name: "光传感器brightness"
value_template: "{{ value_json.brightness }}"
state_topic: "LTR303"
unit_of_measurement: "LTR303"
unique_id: "LTR303_brightness"
效果
拓展任务一:扩展任务二 通过外部SHT40温湿度传感器,上传温湿度到HA
流程图如下:
这个流程就和弄光传感器的一样,只是换成了温湿度传感器和HA实体配置中MQTT主题
HA实体
sensor:
- platform: mqtt
name: "光传感器IR"
value_template: "{{ value_json.ir_data }}"
state_topic: "LTR303"
unit_of_measurement: "LTR303"
unique_id: "LTR303_IR"
- platform: mqtt
name: "光传感器brightness"
value_template: "{{ value_json.brightness }}"
state_topic: "LTR303"
unit_of_measurement: "LTR303"
unique_id: "LTR303_brightness"
- platform: mqtt
name: "温湿度传感器-温度"
value_template: "{{ value_json.temperature }}"
state_topic: "SHT4"
unit_of_measurement: "°C"
unique_id: "SHT4_temperature"
- platform: mqtt
name: "温湿度传感器-湿度"
value_template: "{{ value_json.humidity }}"
state_topic: "SHT4"
unit_of_measurement: "%"
unique_id: "SHT4_humidity"
代码如下
#include "Adafruit_SHT4x.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
Adafruit_SHT4x sht4;
char ssid[] = "ssid";
char pass[] = "pass";
int status = WL_IDLE_STATUS;
const char broker[] = "ip";
int port = 1883;
const char command_topic[] = "SHT4";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
JSONVar dataObj;
void setup() {
Serial.begin(115200);
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;
}
//*********************************************************************
//*************ADVANCED SETUP - SAFE TO IGNORE!************************
// The SHT40 has a built-in heater, which can be used for self-decontamination.
// The heater can be used for periodic creep compensation in prolongued high humidity exposure.
// For normal operation, leave the heater turned off.
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;
}
//*********************************************************************
//*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!*******
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("----------------------------------"));
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
mqttClient.setUsernamePassword("","");
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");
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
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();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
float t = temp.temperature;
Serial.println("Temp *C = " + String(t));
float h = humidity.relative_humidity;
Serial.println("Hum. % = " + String(h));
dataObj["temperature"] = t;
dataObj["humidity"] = h;
String jsonString = JSON.stringify(dataObj);
mqttClient.beginMessage(command_topic);
mqttClient.print(jsonString);
mqttClient.endMessage();
delay(500);
}
任务效果:
代码下载:https://download.eeworld.com.cn/detail/LTLyaoni/634885
心得体会:
这次活动我主要是抱着学习的心态去的。不得不说,Arduino的那些固件真的超级丰富,特别适合用来验证各种功能。我得说,论坛上那些大佬们和网友们的分享真的是太精彩了,给了我好多灵感和帮助。真的很感谢他们!
希望能有更多不同使用R4板子项目的帖子,可以加深学习Arduino
- 2024-10-22
-
上传了资料:
Follow me 第二季第2期代码汇总
-
加入了学习《Follow me第二季第2期视频演示》,观看 演示视频
- 2024-10-21
-
加入了学习《【Follow me第二季第1期】全部任务演示》,观看 全部任务演示2.0
- 2024-10-20
-
加入了学习《Follow Me 第二季第二期总结视频》,观看 follow me 集合
- 2024-10-03
-
发表了主题帖:
【Follow me第二季第2期】+ 进阶任务 :使用Arduino uno r4 接入Home assistant
本帖最后由 LTLyaoni 于 2024-10-3 02:20 编辑
简介
在本章节中我将使用Arduino uno r4 自带的Wifi功能将 Arduino uno 4 通过MQTT服务器连接到Home assistant
Task 1 : 使用Uno r4 连接Wifi
Arduino IDE 提供了Arduino uno r4 的wifi连接的example, 我们可以根据下面的截图进行查找
在上述的提供的代码中我们只需要修改wifi的 ssid 和 pass 即可连接到WIFI上, 我这里连接的是2.4G的wifi
当我们把代码烧录到开发版中之后,我们会发现串口控制台已经可以正确的获取到IP地址.
当你控制台出现IP地址的时候即为连接WIFI成功.
Task 2 : 使用MQTT连接到HA
由于MQTT的便携性和容易集成等优点,因为我们可以在HA中集成MQTT服务,使其监视某一个主题从而实现消息的上报和下发. 因为我们本章节的任务非常简单, 即使用UNO r4 连接到MQTT的某个Topic 然后在HA中监视这个主题就算成功.
我们只需要在配置集成中, 监视这个test的主题,然后使用Uno r4 向这个主题发送消息即可.
Task 3 : 使用UNO R4 ,连接MQTT发送消息.
但是很不巧Arduino uno r4 并没有提供MQTT的Demo, 所以我们需要看看官方有没有什么推荐的. 好巧不巧, 我在https://docs.arduino.cc/tutorials/uno-wifi-rev2/uno-wifi-r2-mqtt-device-to-device/上找到了如何使用MQTT的方式, 即使用Mqtt Client.
虽然它代码写的比较长,但是其核心的逻辑还是使用ArduinoMqttClientt对象使用WIFI client 对象来连接MQTT. 那么我们便可以在上述的代码中做出以下的修改
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
char ssid[] = "你的Wi-Fi名称";
char pass[] = "你的wifi密码";
int status = WL_IDLE_STATUS;
const char broker[] = "你的MQTT地址";
int port = 端口;
const char topic[] = "主题";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
void setup() {
Serial.begin(115200);
while (!Serial) {
}
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}
String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}
// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network:
status = WiFi.begin(ssid, pass);
// wait 10 seconds for connection:
delay(10000);
}
Serial.print("You're connected to the network");
printCurrentNet();
printWifiData();
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");
}
void printCurrentNet() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print the MAC address of the router you're attached to:
byte bssid[6];
WiFi.BSSID(bssid);
Serial.print("BSSID: ");
printMacAddress(bssid);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.println(rssi);
// print the encryption type:
byte encryption = WiFi.encryptionType();
Serial.print("Encryption Type:");
Serial.println(encryption, HEX);
Serial.println();
}
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();
}
void printWifiData() {
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print your MAC address:
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC address: ");
printMacAddress(mac);
}
void loop() {
mqttClient.beginMessage(topic);
mqttClient.print("Message from UNO R4");
mqttClient.endMessage();
delay(500);
}
注意上述的代码是在匿名的情况下连接到MQTT服务器的,如果你的MQTT服务器不支持匿名连接的话你需要自己调用mqttclinen的设置用户名和密码的function来认证你的连接. 此时我们打开HA的话我们开启监听即可收到来自Uno r4的消息 (注意HA中MQTT监视的topic是test主题,但是上述代码中我并没有写, 方便大家复用我的代码)
现象如下:
-
发表了主题帖:
【Follow me第二季第2期】+ 基础任务【点亮LED矩阵, 使用运算放大器放大DAC信号】
概述
在基础任务中我将使用Arduino uno 4 wifi 来点亮板载的LED矩阵,并且使用DAC输出信号同时使用运算放大器进行信号的放大.
Task 1 : 点亮板载Led matrix
Step 1 : 打开Arduino 的 demo, 选择LED matrix.
第一个代码是使用LED的frame的方式进行点亮的, 即在数组中定义每一个LED灯的状态, 通过加载帧的方式实现的. 相关的数组在frames.h 里
const uint32_t chip[] = {
0x1503f811,
0x3181103,
0xf8150000
};
const uint32_t danger[] = {
0x400a015,
0x1502082,
0x484047fc
};
const uint32_t happy[] = {
0x19819,
0x80000001,
0x81f8000
};
const uint32_t heart[] = {
0x3184a444,
0x44042081,
0x100a0040
};
效果如下:
[localvideo]f0694a4961b869223cd3b369fafac7fa[/localvideo]
Task 2: 使用 DAC 输出正弦波
Step 1 : 在Arduino IDE中并没有发现,关于DAC输出的Demo程序, 因此我们需要查询一下官方文档看下如何使用Arduino 的DAC功能, 根据官方文档提供的代码,我们可以很快的实现DAC输出的功能
/*
SineWave
Generates a pre-generated sawtooth-waveform.
See the full documentation here:
https://docs.arduino.cc/tutorials/uno-r4-wifi/dac
*/
#include "analogWave.h" // Include the library for analog waveform generation
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
void setup() {
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
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");
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(1000); // Delay for one second before repeating
}
由于DAC的输出是A0 端口, 我们可以手动调整A5的ADC电压来动态调整A0的DAC输出频率. 如果使用示波器连接A0的话, 那么A0的输出将会是如下图所示
Task 3 : 对DAC信号使用运算放大器进行放大, 然后使用ADC进行采集并且展示.
Arduino uno 4的官方文档写的比较详细, 如果想使用运算放大器对信号进行放大的话只需要构建好以下的电路.
我们在官方的代码上稍微做一点修改(仅仅是在代码的第八行开启了运算放大器)
#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
void setup() {
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
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");
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
delay(50); // Delay for one second before repeating
}
之后我们讲代码烧录到系统中之后再使用示波器进行电压的采集的时候发现现在的平均电压已经被运算放大器放大到了之前的两倍左右
Task 3 : 使用ADC 采集DAC输出,并且显示.
我们可以在上述代码上做一点简单的修改使其DAC的输出作为ADC的输入(电路), 这样的话,当我们打印出数据的时候, 串口绘图功能则会自动绘制ADC的采集曲线,代码如下所示
#include "analogWave.h" // Include the library for analog waveform generation
#include <OPAMP.h>
analogWave wave(DAC); // Create an instance of the analogWave class, using the DAC pin
int freq = 10; // in hertz, change accordingly
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
}
- 2024-10-02
-
发表了主题帖:
【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】
前言
大家好,我是一名电子爱好者,也是【Follow me】第二季的参与者。在这一期,我将和大家一起探索如何搭建嵌入式开发环境,并通过一个简单的Blink(闪烁LED)实验和串口日志打印来开启我们的学习之旅。这不仅是一个学习过程,更是一段充满乐趣的探索之旅。让我们一起动手,点亮我们的第一颗LED灯吧!
1. 准备阶段
在开始之前,我们需要准备以下工具和设备:
一台电脑(Windows, macOS, 或 Linux都可以)
一块微控制器开发板:Arduino UNO R4 WiFi
一根数据线 type-c的
必要的软件,Arduino IDE
2. 开发板介绍:Arduino UNO R4 WiFi
在我们开始搭建环境之前,先让我们来了解一下今天的主角——Arduino UNO R4 WiFi。这款开发板是Arduino系列中的最新成员,它不仅继承了UNO系列的经典设计,还增加了WiFi功能,使得远程控制和数据传输变得更加便捷。
规格参数
• 处理器:Arm cortex M4
• 存储:256KB Flash/32KB SRAM
• 工作电压:5V
• 输入电压:6~24V
• 时钟频率:48MHz
• 编程端口:USB-C
• WiFi/蓝牙:ESP32-S3-MINI
• 发光二极管矩阵:12x8(96 red LEDs)
• 额外的连接
• Qwiic连接器
• OFF引脚
• VRTC引脚
• 数字I/O接口数: 14
• PWM接口数:6
• ADC接口数:6
• DAC接口数:1(12bit)
• SPI接口数:1
• I2C接口数:2
• CAN接口数:1
技术资料
• Arduino UNO R4 WiFi数据手册
• Arduino UNO R4 WiFi原理图
• Arduino UNO R4 WiFi引脚图
• Arduino UNO R4 WiFi CAD文件
• LTR-329数据手册
• RA4M1数据手册
• RA4M1硬件用户手册
• SHT40数据手册
上述资料来自 Follow me 第二季,需要查看更多,请前往查看
3. 安装IDE
首先,我们需要一个集成开发环境(IDE)来编写和上传代码。以Arduino IDE为例,我们可以从Arduino官网下载并安装它。
Arduino下载
官网下载
官网链接---------> Arduino - Home
Arduino安装
直接下一步下一步就行(如果不想放在C盘,那就改成自己的路径)这里就不截图了
Arduino配置
第一次进来需要保证网络通常,让他自己下载几个文件
修改为中文
配置使其下载的Arduino支持最新的Arduino uno R4
此时基于Arduino uno R4 的开发环境已经搭建完成, 我们可以通过选择R4主板后。在文件选项那里查看的官方examples
4. Blink实验
4.1 编写代码
根据下载的原理图看到
R4上面有四个小灯灯,除了那个LED矩阵不算。其中两个小灯是串口显示的,一个绿色的小灯是告诉我们电源开了,还有一个黄色的小灯是我们可以自己控制的,比如在开机的时候让它闪一闪。
P102 就是 13引脚
现在,让我们打开IDE,创建一个新项目,并编写以下代码来控制LED DL4闪烁:
// 定义LED连接的引脚
int ledPin = 13;
void setup() {
// 设置引脚模式为输出
pinMode(ledPin, OUTPUT);
}
void loop() {
digitalWrite(ledPin, HIGH); // 打开LED
delay(500); // 等待0.5秒
digitalWrite(ledPin, LOW); // 关闭LED
delay(500); // 等待0.5秒
}
4.2 上传代码
将代码上传到开发板上。如果一切顺利,应该能看到LED灯开始闪烁了。
5. 串口日志打印
5.1 编写代码
接下来,让我们在代码中添加串口打印功能,以便我们可以看到LED灯的状态和Hello world的输出:
// 定义LED连接的引脚
int ledPin = 13;
void setup() {
Serial.begin(9600); // 初始化串口通信
pinMode(ledPin, OUTPUT);
}
void loop() {
Serial.println("LED状态: ON");
digitalWrite(ledPin, HIGH);
Serial.println("Hello World!");
Serial.println("Hello DigiKey and EEWorld!");
delay(500);
Serial.println("LED状态: OFF");
digitalWrite(ledPin, LOW);
Serial.println("Hello World!");
Serial.println("Hello DigiKey and EEWorld!");
delay(500);
}
代码编译烧录后,打开IDE自带的串口监视器,设置和代码相同的波特率,即可看到相应的串口输出