【Follow me第二季第2期】学习Arduino UNO R4 WiFi 之任务汇总
本帖最后由 md-llama-com 于 2024-10-20 22:28 编辑# 学习Arduino UNO R4 WiFi任务汇总
Follow me 第二季第二期来了,又又又可以白嫖技术白嫖板子了 ~ 闲话少说 ~开启今日份任务汇总,这次是一份Arduino UNO R4 WiFi的板子,用的是日本瑞萨电子的RA4M1芯片,wifi用的是乐鑫ESP32,非常值得学习的方案。
# 汇总视频链接
bf33d481ab30092d6d1ba4513cc03fc2<br/>
# 全部物料清单(含物料名称、实物图片)
1.最主要的控制板
Arduino UNO R4 WiFi
2.LTR-329 环境光传感器与SHT40温湿度传感器
3.跳线
4.示波器
# 入门任务(必做):搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
搭配器件: Arduino UNO R4 WiFi
这就是今天的主角,这个项目一是为了确定板子的好坏,二是为了测试与电脑是否可以通讯。
## 搭建环境:
在arduino官网下载Arduino IDE
点击微软下载或者MAC下载
仅下载 JUST DOWNLOAD
下载好后点击安装包安装
同意,下一步,安装,三步走,尽量装在D盘
完成安装后在打开arduino IDE并授权一大堆权限后,我们进入了界面,开始获取Arduino UNO R4 WiFi 包
注意这里arduino IDE会要求安装一堆东西
安装这块板子的支持包后即可完成环境搭建
整个步骤就是:上官网->下载软件->安装arduino->配置Arduino UNO R4 WiFi板子扩展包
## Blink
写程序的第一句话是打印hello world
而玩儿开发板的第一步是点灯
在打开IDE后找到文件file->示例Exmples->基础Basics->BLink
用Type-C线连好板子与电脑
点击编译即可
效果如下:
代码如下:
```
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH);// turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
```
## 串口打印Hello EEWorld!
串口打印是很多交互的基础
我们在刚刚的点灯程序下加入这一行:波特率设定为9600,波特率是电脑与单片机之间的通讯频率
```
Serial.println("Hello EEWorld!");
```
打开串口调试器,下载程序
效果如下:
代码如下:
```
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(9600);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH);// turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
Serial.println("Hello EEWorld!");
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
```
## 程序流程图
# 基础任务(必做):驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
搭配器件: Arduino UNO R4 WiFi
## 驱动12x8点阵LED
12X8点阵LED这是之前没遇到过的,通过查看原理图,原理图如下
至于怎么驱动这块LED屏幕,我们可以在示例里找到LED_Matrix,打开DisplaySingleFrame示例查看
代码如下
```
#include "Arduino_LED_Matrix.h" // Include the LED_Matrix library
#include "frames.h" // Include a header file containing some custom icons
ArduinoLEDMatrix matrix; // Create an instance of the ArduinoLEDMatrix class
void setup() {
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
matrix.begin(); // Initialize the LED matrix
}
void loop() {
// Load and display the "chip" frame on the LED matrix
matrix.loadFrame(chip);
delay(500);// Pause for 500 milliseconds (half a second)
// Load and display the "danger" frame on the LED matrix
matrix.loadFrame(danger);
delay(500);
// Load and display the "happy" frame on the LED matrix
matrix.loadFrame(happy);
delay(500);
// Load and display the "big heart" frame provided by the library
matrix.loadFrame(LEDMATRIX_HEART_BIG);
delay(500);
// Turn off the display
matrix.clear();
delay(1000);
// Print the current value of millis() to the serial monitor
Serial.println(millis());
}
```
效果如下:
## 程序流程图如下:
## 用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口
这三个任务可以一起做
### 用DAC生成正弦波
打开案例库SineWave
其代码如下:
```
#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);
wave.sine(freq);
wave.amplitude(0.5);//幅值倍数
}
void loop(){
Serial.println(analogRead(A5));
delay(10);
}
```
### 用OPAMP放大DAC信号
使用运算放大器(OP-AMP)放大数字到模拟转换器(DAC)的信号是一种常见的电子电路设计实践。这种配置可以增加信号的幅度,以满足特定的应用需求,例如驱动更大的负载或提供足够的信号强度以进行测量。
以下是电路图
代码如下:
```
#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 = 200;// in hertz, change accordingly
void setup() {
Serial.begin(2000000);// Initialize serial communication at a baud rate of 115200
analogReadResolution(14);
wave.sine(freq); // Generate a sine wave with the initial frequency
wave.amplitude(0.5);//幅值倍数
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
}
void loop() {
delayMicroseconds(100);
}
```
### 用ADC采集并且打印数据到串口
只需要将输出分别导入A4,A5端口即可,循环loop如下
```
void loop() {
Serial.print(analogRead(A4));
Serial.print(",");
Serial.println(analogRead(A5));
delayMicroseconds(100);
}
```
用示波器显示如下
## 流程图
# 进阶任务(必做):通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
搭配器件: Arduino UNO R4 WiFi
要接入到平台HA(HomeAssistant)平台,首先要有一个HA平台,常规做法是搭建一个服务器,在服务器中用docker容器安装HA,我们作为初学者,自己用的电脑直接安装HA
pip3 install homeassistant
在powershell中输入命令下载安装HA,时间会比较久
打开 127.0.0.1:8123 注册HA
接下来要搭建MQTT服务器,这里用的是Docker容器下的EMQX镜像
众所周知Docker安装是真的烦,我这里就遇到了Docker Engine stopped
**我是怎么解决的呢**
### 1.首先检查一下CPU是否开启虚拟化
如果虚拟化是禁用的,要进入BIOS打开虚拟化。我这里是没有问题的。
### 2.启动Docker Desktop Service服务
在windows powershell中(管理员运行),输入 **net start com.docker.service** 启动Docker Desktop Service服务
### 3.wsl安装
在windows powershell中输入**wsl --update**,开始安装wsl或者更新版本。
### 4.启动docker daemon
在windows powershell中输入 ** cd "C:\Program Files\Docker\Docker" ** 跳转到Docker Desktop安装路径
运行命令 **.\DockerCli.exe -SwitchDaemon** 把docker daemon启动
### 5.重启电脑
重启电脑非常重要,网上的步骤都没写这步,导致我一直失败,重启电脑后再运行docker desktop,就可以正常进入了。
正常进入docker后找到Docker Engine
将其中内容改为
```
{
"builder": {
"gc": {
"defaultKeepStorage": "20GB",
"enabled": true
}
},
"debug": true,
"experimental": false,
"insecure-registries":[],
"registry-mirrors":[
"https://docker.m.daocloud.io"
]
}
```
重启docker。
## 然后就可以在docker中拉取emqx
### 1.在windows命令行中输入以下命令搜索镜像,
```c
docker search emqx
```
### 2.回车后可以看到排名第一的 emqx 并且是official; 输入以下命令拉取最新版本镜像
```c
docker pull emqx
```
## 然后创建EMQX容器
```
docker run -d --name="EMQX_container" -v D:/HassWP_2024.4.3/EMQX -p 1883:1883 -p 8083:8083 -p 8883:8883 -p 8084:8084 -p 18083:18083 emqx
```
-v 后面接着的是容器保存路径
## 启动emqx
回到docker点击图示网址即可启动
http://localhost:18083/
默认账号:admin 默认密码:public
## EMQX的一些设置
进入EMQX后会让我们重新设置密码
访问控制 -> 客户端认证 -> 选 **创建** -> 选择 **Password-Based** ->**内置数据库** -> **下一步** -> 3个都默认 -> 点 **创建**
点击 **用户管理** -> 点 +(右侧)-> 填入新的用户名和密码
## EMQX 与 HA相连接
首先要找到EMQX服务器在docker内的地址,按照图片所示寻找即可
在HA中打开设置如下图
设备与服务
添加新设备
输入刚刚的地址与EMQX上新增的用户名与密码
完成后回到EMQX界面可以看到设备连接数加一
这样EMQXHA 之间就打通了
接下来要将咱们的主角与EMQX之间的连接打通。
## Arduino UNO R4 WiFi与EMQX连接
程序如下:
参数定义如下
```c
#define MQTT_SERVER "192.168.3.28"// 电脑无线网卡IP地址"xxx.xxx.xxx.xxX
#define MQTT_PORT 1883 //定义MQTT服务器的端口
#define MQTT_CLIENT_ID "arduino"// 定义客户端的ID'arduino'
#define MQTT_USERNAME "sdfa" // 定义用户名,EMQX定义"admin'
#define MQTT_PASSWORD "sdfda" // 定义密码,EMQX定义"admin"
#define TOPIC_SUBSCRIBE "UNO/arduino/switch/cmd_t"//定义订阅的主题
#define SECRET_SSID "dsdfai" // 路由器WiFi名称 也可使用win移动热点"xxXXX
#define SECRET_PASS "sfdfsf" // 路由器WiFi密码”xxxXX
```
主程序是HA网站上设定按钮,然后控制Arduino UNO R4 WiFi上14号引脚小灯亮灭。
主程序如下
```c
#include "ArduinoHA.h"
#include "OPAMP.h"
#include "Wire.h"
#include "WiFiS3.h"
#include "arduino_secrets.h"
#include "analogWave.h"
analogWave wave(DAC);
int status= WL_IDLE_STATUS;
unsigned long lastUpdateAt=0;
int freg=1;//max200 Hz limit by serial print
WiFiClient client;
HADevice device(MQTT_CLIENT_ID);//HADevice device (mac, sizeof(mac));
HAMqtt mqtt(client,device);
HAButton buttonON("myButtonON");
HAButton buttonOFF("myButtonOFF");
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
wifi_and_mqtt_init();
analogReadResolution(14);//change to 14-bit resolution
wave.sine(freg);//wave.saw(freg);
wave.amplitude(0.5);
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");
buttonON.setIcon("mdi:fire");
buttonON.setName("Click me ON");
buttonOFF.setIcon("mdi:home");
buttonOFF.setName("click me OFF");
buttonON.onCommand(onButtonCommand);//press callbacks
buttonOFF.onCommand(onButtonCommand);
}
void loop()
{
mqtt.loop();
if((millis() - lastUpdateAt) > 1000)
{//update in 1s interval
unsigned long uptimeValue=millis()/1000;
lastUpdateAt =millis();
}
}
void onMqttMessage(const char* topic, const uint8_t* payload, uint16_t length)
{
char message;
memcpy(message,payload,length);
message= '\0';
Serial.print("dbglNew message on topic:");
Serial.println(topic);
Serial.print("Data:");
Serial.println((const char*)message);
if(strstr(message,"on")!=NULL)
{
int dutyCycle=0;
if (sscanf(message,"on#%d",&dutyCycle)==1)
{
}
}
else if(strstr(message,"off")!=NULL)
{
}
else
{
Serial.println("Unrecognized message");
}
memset(message,0, length);
}
void onMqttConnected()
{
Serial.println("Connected to the broker!");
//You can subscribe to custom topic if you need
mqtt.subscribe(TOPIC_SUBSCRIBE);//command
//mqtt.subscribe(TOPIC SUBSCRIBE2)://status
Serial.println("subscribed to topic:" TOPIC_SUBSCRIBE);
mqtt.publish(TOPIC_SUBSCRIBE,"Hi EMOX I'mArdinO UNO R4 WIFI^^");
}
void onMqttDisconnected()
{
Serial.println("Disconnected from the broker!");
}
void onMqttStateChanged(HAMqtt::ConnectionState state)
{
Serial.print("MoTT state changed to:");
Serial.println(static_cast<int8_t>(state));
}
void onButtonCommand(HAButton* sender)
{
if(sender ==&buttonON)
{
Serial.print("buttonON");// button A was clicked, do your logic hereelse
digitalWrite(LED_BUILTIN, HIGH);
}
else if(sender==&buttonOFF)
{
Serial.print("buttonOFF");// button B was clicked, do your logic here
digitalWrite(LED_BUILTIN, LOW);
}
}
void wifi_and_mqtt_init()
{
//check for the WiFi module:
if(WiFi.status()==WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
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 SSID:");
Serial.println(SECRET_SSID);
//Connect to WPA/WPA2 network, Change this line if using open or WEP network;
status=WiFi.begin(SECRET_SSID,SECRET_PASS);
delay(10000);
}
Serial.println("\nStarting connection to MoTT server...");
mqtt.onMessage(onMqttMessage);
mqtt.onConnected(onMqttConnected);
mqtt.onDisconnected(onMqttDisconnected);
mqtt.onStateChanged(onMqttStateChanged);
//If you want to change prefix only for non-discovery prefix:
mqtt.setDataPrefix("UNO");
if(!mqtt.begin(MQTT_SERVER,MQTT_PORT,MQTT_USERNAME,MQTT_PASSWORD))
{
Serial.print("Failed, rC=");
Serial.print(mqtt.getState());//0btaining state of the MoTr connection:
Serial.println("tryagain in 5 seconds");
delay(5000);
}
}
```
效果如下
## 流程图
# 扩展任务(必做,二选一,或根据自己的兴趣,自定义类似难度或更高难度的任务并完成)我选择两个都做
## ■扩展任务一:通过外部LTR-329 环境光传感器,上传光照度到HA,通过HA面板显示数据
搭配器件: Arduino UNO R4 WiFi、5591(LTR-329光传感器扩展板)、跳线
首先要处理一下接线问题,因为没有购买官方的跳线,我们需要自己把插针焊上
如下图
然后按照IIC的要求把时钟线 数据线接上,注意电源线要接3.3V的。
安装Adafruit LTR329 and LTR303 库
打开示例,将没用的语句简化,先测试一下模块是否正常使用,然后再与HA连接:
```
#include "Adafruit_LTR329_LTR303.h"
Adafruit_LTR303 ltr = Adafruit_LTR303();
void setup() {
Serial.begin(115200);
if ( ! ltr.begin() ) {
Serial.println("Couldn't find LTR sensor!");
while (1) delay(10);
}
//初始化传感器,如果没找到持续刷新,直到找到
Serial.println("Found LTR sensor!");
ltr.setGain(LTR3XX_GAIN_96);//设置传感器灵敏度
ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);//设置传感器的积分时间ms
ltr.setMeasurementRate(LTR3XX_MEASRATE_200);//设置测量速率ms
// The LTR-303 has interrupt output support, we can enable the pin output!
ltr.enableInterrupt(true);
// The INT pin also has a polarity setting. For active LOW set to 'false',
// for active HIGH set to 'true'
ltr.setInterruptPolarity(false);
//设置低阈值和高阈值
// Then set the low threshold (values BELOW this trigger an interrupt)
ltr.setLowThreshold(2000);
// and set the high threshold (values ABOVE this trigger an interrupt)
ltr.setHighThreshold(30000);
Serial.print("Thresholds: ");Serial.print(ltr.getLowThreshold());
Serial.print(" & ");Serial.println(ltr.getHighThreshold());
// Finally, default is an interrupt on every value that is under/over the
// threshold ranges. However, you're more likely to get spurious IRQs, so
// we can set it to require "N counts in a row" before an IRQ. 1 count is
// IRQ for each reading, 2 count means we need two outside readings in a row, etc
// up to 16.
//设置中断的持续计数,连续4次超出阈值则中断
ltr.setIntPersistance(4);
Serial.print("Consecutive counts for IRQ: ");Serial.println(ltr.getIntPersistance());
}
void loop() {
bool valid;
uint16_t visible_plus_ir, infrared;
//检查是否有新的数据可用
if (ltr.newDataAvailable()) {
valid = ltr.readBothChannels(visible_plus_ir, infrared);
//如果数据有效,将可见光+红外和红外的光强度值打印到串行监视器。
if (valid) {
Serial.print("CH0 Visible + IR: ");
Serial.print(visible_plus_ir);
Serial.print("\t\tCH1 Infrared: ");
Serial.println(infrared);
}
}
delay(100);
}
```
运行效果如下
与HA结合程序如下
```
#include "ArduinoHA.h"
#include "OPAMP.h"
#include "Wire.h"
#include "WiFiS3.h"
#include "arduino_secrets.h"
#include "analogWave.h"
#include "Adafruit_LTR329_LTR303.h"
analogWave wave(DAC);
Adafruit_LTR303 ltr = Adafruit_LTR303();
int status= WL_IDLE_STATUS;
unsigned long lastUpdateAt=0;
int freg=1;//max200 Hz limit by serial print
WiFiClient client;
HADevice device(MQTT_CLIENT_ID);//HADevice device (mac, sizeof(mac));
HAMqtt mqtt(client,device);
HASensorNumber analogSensor("myAnalogInput", HASensorNumber::PrecisionP1);
HASensorNumber uptimeSensor("myUptime");
HAButton buttonON("myButtonON");
HAButton buttonOFF("myButtonOFF");
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
wifi_and_mqtt_init();
analogReadResolution(14);//change to 14-bit resolution
wave.sine(freg);//wave.saw(freg);
wave.amplitude(0.5);
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");
buttonON.setIcon("mdi:fire");
buttonON.setName("Click me ON");
buttonOFF.setIcon("mdi:home");
buttonOFF.setName("click me OFF");
buttonON.onCommand(onButtonCommand);//press callbacks
buttonOFF.onCommand(onButtonCommand);
if ( ! ltr.begin() ) {
Serial.println("Couldn't find LTR sensor!");
while (1) delay(10);
}
//初始化传感器,如果没找到持续刷新,直到找到
Serial.println("Found LTR sensor!");
ltr.setGain(LTR3XX_GAIN_96);//设置传感器灵敏度
ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);//设置传感器的积分时间ms
ltr.setMeasurementRate(LTR3XX_MEASRATE_200);//设置测量速率ms
// The LTR-303 has interrupt output support, we can enable the pin output!
ltr.enableInterrupt(true);
// The INT pin also has a polarity setting. For active LOW set to 'false',
// for active HIGH set to 'true'
ltr.setInterruptPolarity(false);
//设置低阈值和高阈值
// Then set the low threshold (values BELOW this trigger an interrupt)
ltr.setLowThreshold(2000);
// and set the high threshold (values ABOVE this trigger an interrupt)
ltr.setHighThreshold(30000);
}
void loop()
{
bool valid;
uint16_t visible_plus_ir, infrared;
mqtt.loop();
//检查是否有新的数据可用
if (ltr.newDataAvailable()) {
valid = ltr.readBothChannels(visible_plus_ir, infrared);
//如果数据有效,将可见光+红外和红外的光强度值打印到串行监视器。
if (valid) {
if((millis() - lastUpdateAt) > 1000)
{//update in 1s interval
Serial.print("CH0 Visible + IR: ");
Serial.print(visible_plus_ir);
uptimeSensor.setValue(visible_plus_ir);
Serial.print("\t\tCH1 Infrared: ");
Serial.println(infrared);
analogSensor.setValue(infrared);
lastUpdateAt =millis();
}
}
}
}
void onMqttMessage(const char* topic, const uint8_t* payload, uint16_t length)
{
char message;
memcpy(message,payload,length);
message= '\0';
Serial.print("dbglNew message on topic:");
Serial.println(topic);
Serial.print("Data:");
Serial.println((const char*)message);
void onMqttConnected()
{
Serial.println("Connected to the broker!");
//You can subscribe to custom topic if you need
mqtt.subscribe(TOPIC_SUBSCRIBE);//command
//mqtt.subscribe(TOPIC SUBSCRIBE2)://status
Serial.println("subscribed to topic:" TOPIC_SUBSCRIBE);
mqtt.publish(TOPIC_SUBSCRIBE,"Hi EMOX I'mArdinO UNO R4 WIFI^^");
}
void onMqttDisconnected()
{
Serial.println("Disconnected from the broker!");
}
void onMqttStateChanged(HAMqtt::ConnectionState state)
{
Serial.print("MoTT state changed to:");
Serial.println(static_cast<int8_t>(state));
}
void onButtonCommand(HAButton* sender)
{
if(sender ==&buttonON)
{
Serial.print("buttonON");// button A was clicked, do your logic hereelse
digitalWrite(LED_BUILTIN, HIGH);
}
else if(sender==&buttonOFF)
{
Serial.print("buttonOFF");// button B was clicked, do your logic here
digitalWrite(LED_BUILTIN, LOW);
}
}
void wifi_and_mqtt_init()
{
//check for the WiFi module:
if(WiFi.status()==WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
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 SSID:");
Serial.println(SECRET_SSID);
//Connect to WPA/WPA2 network, Change this line if using open or WEP network;
status=WiFi.begin(SECRET_SSID,SECRET_PASS);
delay(10000);
}
Serial.println("\nStarting connection to MoTT server...");
mqtt.onMessage(onMqttMessage);
mqtt.onConnected(onMqttConnected);
mqtt.onDisconnected(onMqttDisconnected);
mqtt.onStateChanged(onMqttStateChanged);
//If you want to change prefix only for non-discovery prefix:
mqtt.setDataPrefix("UNO");
if(!mqtt.begin(MQTT_SERVER,MQTT_PORT,MQTT_USERNAME,MQTT_PASSWORD))
{
Serial.print("Failed, rC=");
Serial.print(mqtt.getState());//0btaining state of the MoTr connection:
Serial.println("tryagain in 5 seconds");
delay(5000);
}
}
```
运行效果如下
### 流程图
## ■扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA,通过HA面板显示数据
搭配器件: Arduino UNO R4 WiFi、4885(SHT40温湿度传感器扩展板)、跳线
安装Adafruit SHT4X库
与光照传感器一样,焊接引脚,用例程测试温湿度传感器好坏
与HA结合程序如下
```
#include "ArduinoHA.h"
#include "OPAMP.h"
#include "Wire.h"
#include "WiFiS3.h"
#include "arduino_secrets.h"
#include "analogWave.h"
#include "Adafruit_LTR329_LTR303.h"
#include "Adafruit_SHT4x.h"
Adafruit_SHT4x sht4 = Adafruit_SHT4x();
analogWave wave(DAC);
Adafruit_LTR303 ltr = Adafruit_LTR303();
int status= WL_IDLE_STATUS;
unsigned long lastUpdateAt=0;
int freg=1;//max200 Hz limit by serial print
WiFiClient client;
HADevice device(MQTT_CLIENT_ID);//HADevice device (mac, sizeof(mac));
HAMqtt mqtt(client,device);
HASensorNumberhumidity2("myhumidity");
HASensorNumberTemperature2("Temperature");
HAButton buttonON("myButtonON");
HAButton buttonOFF("myButtonOFF");
void setup()
{
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
wifi_and_mqtt_init();
analogReadResolution(14);//change to 14-bit resolution
wave.sine(freg);//wave.saw(freg);
wave.amplitude(0.5);
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
device.setName("Arduino");
device.setSoftwareVersion("1.0.0");
buttonON.setIcon("mdi:fire");
buttonON.setName("Click me ON");
buttonOFF.setIcon("mdi:home");
buttonOFF.setName("click me OFF");
buttonON.onCommand(onButtonCommand);//press callbacks
buttonOFF.onCommand(onButtonCommand);
while (!Serial)
delay(10); // will pause Zero, Leonardo, etc until serial console opens
if (! sht4.begin()) {
Serial.println("Couldn't find SHT4x");
while (1) delay(1);
}
Serial.println(sht4.readSerial(), HEX);
// You can have 3 different precisions, higher precision takes longer
sht4.setPrecision(SHT4X_HIGH_PRECISION); //精度
// You can have 6 different heater settings
// higher heat and longer times uses more power
// and reads will take longer too!
sht4.setHeater(SHT4X_NO_HEATER);//加热传感器
}
void loop()
{
bool valid;
uint16_t visible_plus_ir, infrared;
sensors_event_t humidity, temp;
sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degrees C");
Serial.print("Humidity: "); Serial.print(humidity.relative_humidity); Serial.println("% rH");
mqtt.loop();
//检查是否有新的数据可用
if (sht4.getEvent(&humidity, &temp)) {
if((millis() - lastUpdateAt) > 1000)
{//update in 1s interval
Temperature2.setValue(temp.temperature);
humidity2.setValue(humidity.relative_humidity);
lastUpdateAt =millis();
}
}
}
void onMqttMessage(const char* topic, const uint8_t* payload, uint16_t length)
{
char message;
memcpy(message,payload,length);
message= '\0';
Serial.print("dbglNew message on topic:");
Serial.println(topic);
Serial.print("Data:");
Serial.println((const char*)message);
if(strstr(message,"on")!=NULL)
{
int dutyCycle=0;
if (sscanf(message,"on#%d",&dutyCycle)==1) { }
}
else if(strstr(message,"off")!=NULL) { }
else
{
Serial.println("Unrecognized message");
}
memset(message,0, length);
}
void onMqttConnected()
{
Serial.println("Connected to the broker!");
//You can subscribe to custom topic if you need
mqtt.subscribe(TOPIC_SUBSCRIBE);//command
//mqtt.subscribe(TOPIC SUBSCRIBE2)://status
Serial.println("subscribed to topic:" TOPIC_SUBSCRIBE);
mqtt.publish(TOPIC_SUBSCRIBE,"Hi EMOX I'mArdinO UNO R4 WIFI^^");
}
void onMqttDisconnected()
{
Serial.println("Disconnected from the broker!");
}
void onMqttStateChanged(HAMqtt::ConnectionState state)
{
Serial.print("MoTT state changed to:");
Serial.println(static_cast<int8_t>(state));
}
void onButtonCommand(HAButton* sender)
{
if(sender ==&buttonON)
{
Serial.print("buttonON");// button A was clicked, do your logic hereelse
digitalWrite(LED_BUILTIN, HIGH);
}
else if(sender==&buttonOFF)
{
Serial.print("buttonOFF");// button B was clicked, do your logic here
digitalWrite(LED_BUILTIN, LOW);
}
}
void wifi_and_mqtt_init()
{
//check for the WiFi module:
if(WiFi.status()==WL_NO_MODULE)
{
Serial.println("Communication with WiFi module failed!");
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 SSID:");
Serial.println(SECRET_SSID);
//Connect to WPA/WPA2 network, Change this line if using open or WEP network;
status=WiFi.begin(SECRET_SSID,SECRET_PASS);
delay(10000);
}
Serial.println("\nStarting connection to MoTT server...");
mqtt.onMessage(onMqttMessage);
mqtt.onConnected(onMqttConnected);
mqtt.onDisconnected(onMqttDisconnected);
mqtt.onStateChanged(onMqttStateChanged);
//If you want to change prefix only for non-discovery prefix:
mqtt.setDataPrefix("UNO");
if(!mqtt.begin(MQTT_SERVER,MQTT_PORT,MQTT_USERNAME,MQTT_PASSWORD))
{
Serial.print("Failed, rC=");
Serial.print(mqtt.getState());//0btaining state of the MoTr connection:
Serial.println("tryagain in 5 seconds");
delay(5000);
}
}
```
运行效果如下
对着传感器哈气后温度湿度都有所上升,温度从30度上升至35度。湿度由60%上升到90%
### 流程图
# 项目总结
在这个精彩纷呈的“Follow me”第二季项目中,我有幸深入探索了Arduino UNO R4 WiF这一功能强大的开发板,并从中获得了许多宝贵的知识和技能。通过这个项目,我掌握了如何自己搭建物联网服务器,花了我具多时间,一度想要放弃,感谢小助手从中的鼓励。同时也掌握了本地传感器数据上传。
在温度和光照传感器的学习过程中,我了解到了环境监测的重要性,并且学会了如何通过编程来收集和分析这些数据。这些技能在物联网(IoT)和智能家居项目中尤为重要,为我打开了一扇通往未来技术的大门。
这些项目的实践操作不仅锻炼了我的动手能力,更重要的是,它们加深了我对硬件编程的理解。我学会了如何将抽象的编程概念应用到具体的硬件设备上,并且能够解决实际问题。
我非常感激EEWorld和Digi-Key提供的这次学习机会。这次经历不仅丰富了我的技术储备,也为我未来的电子项目和职业生涯打下了坚实的基础。我期待着将这些新学到的技能应用到更多的创新项目中,并且希望能够继续在电子和编程领域不断探索和成长。
# 项目程序
<br/><br/>
# End <p>恭喜顺利完成 </p>
页:
[1]