前言
Hello,大家好,我是Wang Chong 非常高兴也非常荣幸能够参加电子工程世界和得捷电子举办得Follow me 第二期得活动。
物料展示
本次拿到得开发板是Arduino uno R4 wifi 以及 LTR-329 光照传感器,SHT40湿温度传感器, 和QWIIC连接线。
设计思路
入门任务(任务1) :
任务一的主要点在于如何在原理图中确认IO的端口,从而使用GPIO控制闪烁
基础任务(任务2) :
任务2的主要点在于如何读懂Arduino官方文档中对LED矩阵和ADC,运算放大器的使用(和电路搭建)
进阶任务(任务3) :
任务三的主要点在于ESP32S3wifi库和MQTT库的使用,以及如何在HA中配置HA实体
拓展任务一:
拓展任务一的主要点在于如何使用QWIIC和正确的库来连接读取光照传感器, 由于在进阶任务中已经连接了MQTT和WIFI,可以代码复用
拓展任务二:
同拓展任务一,不过传感器驱动变成了SHT40
视频如下:
任务实现详情
入门任务一:搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
帖子地址:【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】 https://bbs.eeworld.com.cn/thread-1293048-1-1.html
流程图如下
任务一的主要点在于如何在原理图中确认R4 IO的端口,从而使用GPIO控制闪烁
代码展示
void setup() {
// sets the digital pin 13 as output
// 设置GPIO13 为输出模式
pinMode(13, OUTPUT);
}
void loop() {
// sets the digital pin 13 on
// 输出高电平
digitalWrite(13, HIGH);
// waits for a second
// 延时一秒
delay(1000);
// sets the digital pin 13 off
// 输出低电平
digitalWrite(13, LOW);
// 延时一秒
delay(1000); /
}
功能展示
二、串口打印HelloWorld
根据官方文档和用户手册得知,D0 和D1 被用于USB的串口输入和输出, 因此只需要在程序中配置即可。
代码如下
void setup() {
// sets the digital pin 13 as output
// 设置GPIO13 为输出模式
pinMode(13, OUTPUT);
// 设置波特率
Serial.begin(115200);
Serial.println("Hello World!");
Serial.println("Hello DigiKey and EEWorld!");
}
void loop() {
// sets the digital pin 13 on
// 输出高电平
digitalWrite(13, HIGH);
// waits for a second
// 延时一秒
delay(1000);
// sets the digital pin 13 off
// 输出低电平
digitalWrite(13, LOW);
// 延时一秒
delay(1000);
}
实验现象如下:
基础任务:驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线
帖子地址:【Follow me第二季第2期】+ 基础任务【驱动LED矩阵+DAC正弦波+放大信号+ADC数据采集] https://bbs.eeworld.com.cn/thread-1293064-1-1.html
流程图如下:
实现思路:任务2的主要点在于如何读懂Arduino官方文档中对LED矩阵和ADC,运算放大器的使用(和电路搭建)
如下有三种点亮LED矩阵的方法
1- 使用帧的方式
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
byte frame[8][12] = {
{ 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },
{ 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 1, 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() {
}
实验现象:
2- 同样使用帧,不过是十六进制(官方推荐)
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
const uint32_t heart[] = {
0x3184a444,
0x44042081,
0x100a0040
};
void setup() {
Serial.begin(115200);
matrix.begin();
matrix.loadFrame(heart);
}
void loop() {
}
实验现象
3- 使用官方代码滚屏
// To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix
#include "ArduinoGraphics.h"
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.begin();
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
// add some static text
// will only show "UNO" (not enough space on the display)
const char text[] = "UNO r4";
matrix.textFont(Font_4x6);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText();
matrix.endDraw();
delay(2000);
}
void loop() {
// Make it scroll!
matrix.beginDraw();
matrix.stroke(0xFFFFFFFF);
matrix.textScrollSpeed(50);
// add the text
const char text[] = " Hello EEWorld and DigiKey! ";
matrix.textFont(Font_5x7);
matrix.beginText(0, 1, 0xFFFFFF);
matrix.println(text);
matrix.endText(SCROLL_LEFT);
matrix.endDraw();
}
实验现象
4 - 使用工具进行动画效果的制作
#include "Arduino_LED_Matrix.h" //Include the LED_Matrix library
#include "animation2.h"
// Create an instance of the ArduinoLEDMatrix class
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
// you can also load frames at runtime, without stopping the refresh
matrix.loadSequence(animation2);
matrix.begin();
matrix.play(true);
}
void loop() {
}
二、DAC 输出正弦波,放大信号,并且使用ADC采集显示在串口绘图中
流程图如下:
实现思路:这个任务主要分为三个部分, 分别是使用DAC输出正弦波, 然后使用信号放大器放大DAC输出,然后使用ADC采集输入.
1- 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
}
电路如下:
示波器输出如下
2- 使用信号放大器放大DAC输出
接线图如下:
电路如下:
代码如下(此时我们已经完成了正弦波和放大信号,那么现在我们将使用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
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
}
示波器输出如下所示(4V左右,滑动变阻器仍然可以调整输出频率):
参考官方文档, 我们可以使用如下API来配置ADC功能
2- analogRead()
如果不需要修改分辨率的话, 可以不使用第一个API。我们在我们的代码上稍微修改下,使其可以把输出被串口绘图正确解析,同时可以获取A4的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
}
串口绘图工具输出如下(蓝色的为ADC读取的值,黄色的为当前的频率)
进阶任务:通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
帖子地址:【Follow me第二季第2期】+ 进阶任务 :通过Wi-Fi,利用MQTT协议接入HA https://bbs.eeworld.com.cn/thread-1293101-1-1.html
流程图如下:
任务三的主要点在于ESP32S3wifi库和MQTT库的使用,以及如何在HA中配置HA实体
本地部署的镜像展示(HA 和 MQTT)
进行MQTT测试
前置工作已经准备好了,那么现在我们就可以开始我们的任务了。 那么这个任务一共分为以下两点
1- 连接WIFI
2- 连接MQTT并且发送消息
对于WIFI的连接比较简单, 我们可以参考S3的wifi连接示例,如下所示
代码如下
#include <WiFiS3.h>
char ssid[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
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();
}
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() {
}
实验现象如下(成功连接上WIFI 获取到了IP地址)
现在我们便开始处理我们的第二个任务, 使用MQTT连接到HA(也就是MQTT服务器,使其HA中集成的MQTT自动发现我们的配置服务)。
参考Arduino的官方文档,我们得知,可以使用ArduinoMqttClient的库来连接MQTT。 我们在上述的代码上稍作修改。
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
char ssid[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
const char broker[] = "192.168.1.113";
int port = 1883;
const char topic[] = "/aht10/test";
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
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();
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("Hello EEworld and Digikey!");
mqttClient.endMessage();
delay(500);
}
将程序烧录到开发板上后,我们打开MQTTX, 查看我们MQTT的目标主题.
配置HA实体
根据上述配置文件得知,我们可以往两个主题内发送消息,从而控制HA的中实体的状态
1- home/bedroom/switch1 状态主题
2- home/bedroom/switch1/set 命令主题
当我们想要关闭灯的时候,只需要向命令主题中发送OFF即可, 如果想要开灯则发送ON. 但是尽管它已经可以正常的控制灯的开关。但是HA中实体的状态并不会发生变化。 如果想要实体的状态也发送变化的话,则需要向状态主题中也发送一个OFF
我们简单的修改一下代码,使其每秒切换灯的状态。
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
char ssid[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
const char broker[] = "192.168.1.113";
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();
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();
}else {
mqttClient.beginMessage(command_topic);
mqttClient.print("OFF");
mqttClient.endMessage();
mqttClient.beginMessage(state_topic);
mqttClient.print("OFF");
mqttClient.endMessage();
}
index = !index;
delay(1000);
}
拓展任务一:扩展任务一 使用LTR-329 环境光传感器,上传到HA并显示
帖子地址:【Follow me第二季第2期】+ 扩展任务一 使用LTR-329 环境光传感器,上传到HA并显示 https://bbs.eeworld.com.cn/thread-1293104-1-1.html
流程图如下:
拓展任务一的主要点在于如何使用QWIIC和正确的库来连接读取光照传感器, 由于在进阶任务中已经连接了MQTT和WIFI,可以代码复用
这个任务主要分为三个方面
1- 使用R4读取LTR-329传感器数据
2- 配置HA实体
3- 将数据上传到HA
步骤一代码如下:
/***************************************************
This is an example for the LTR329 light sensor that reads both channels
and demonstrates how to set gain and check data validity
Designed specifically to work with the LTR-329 light sensor from Adafruit
----> https://www.adafruit.com/product/5591
These sensors use I2C to communicate, 2 pins are required to
interface
****************************************************/
#include "Adafruit_LTR329_LTR303.h"
Adafruit_LTR329 ltr = Adafruit_LTR329();
void setup() {
Serial.begin(115200);
Serial.println("Adafruit LTR-329 advanced test");
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 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);
}
串口数据打印如下:
2- 配置HA实体
HA实体的配置主要是涉及到HA容器内的configuration.yml 根据官方文档得知我们可以配置一个如下的光照和举例的传感器
然后我们在HA的Web页面中重新加载一下配置信息
此时我们只需要向名称为 lux的主题内发送json数据即可
如下消息格式
{"psData":143,"brightness":117.2}
此时我们第二部分完成
步骤三: 上传数据到HA
由于我们上一个章节已经成功的连接到了WIFI 并且使用MQTT发送了数据,我们可以整合上一节的代码。 主要的逻辑就是初始化WIFI连接并且连接到MQTT服务器。 当获取到光照数据的时候结合Arduino的json库将数据序列化成JSON数据然后发送的MQTT服务器
代码如下:
/***************************************************
This is an example for the LTR329 light sensor that reads both channels
and demonstrates how to set gain and check data validity
Designed specifically to work with the LTR-329 light sensor from Adafruit
----> https://www.adafruit.com/product/5591
These sensors use I2C to communicate, 2 pins are required to
interface
****************************************************/
#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[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
const char broker[] = "192.168.1.113";
int port = 1883;
const char command_topic[] = "lux";
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();
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["psData"] = infrared;
String jsonString = JSON.stringify(dataObj);
mqttClient.beginMessage(command_topic);
mqttClient.print(jsonString);
mqttClient.endMessage();
}
}
delay(500);
}
此时便可以在HA的主界面中编辑Dashboard 在实体中搜索配置的实体的名称,如下图所示(成功的配置了光照传感器)
当点击传感器名称的时候还可以查看到历史数据
拓展任务一:扩展任务二 通过外部SHT40温湿度传感器,上传温湿度到HA
帖子地址:【Follow me第二季第2期】扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA. https://bbs.eeworld.com.cn/thread-1293108-1-1.html
流程图如下:
实现思路:同拓展任务一,只不过传感器驱动变成了SHT40
通过上一章的练习我们已经学会了如何使用R4来读取传感器的数据并且上传到HA由HA进行显示(手机端或者Web端)。 那么本章节也是同样的道理,只不过传感器换成了SHT40. 我们可以直接使用上一个章节的代码, 不过需要替换掉原本的驱动函数以及对应的消息主题
代码如下
/***************************************************
This is an example for the LTR329 light sensor that reads both channels
and demonstrates how to set gain and check data validity
Designed specifically to work with the LTR-329 light sensor from Adafruit
----> https://www.adafruit.com/product/5591
These sensors use I2C to communicate, 2 pins are required to
interface
****************************************************/
#include "Adafruit_SHT4x.h"
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include <WiFiClient.h>
#include <Arduino_JSON.h>
Adafruit_SHT4x sht4;
char ssid[] = "ImmortalWrt";
char pass[] = "mazha1997";
int status = WL_IDLE_STATUS;
const char broker[] = "192.168.1.113";
int port = 1883;
const char command_topic[] = "office/sensor1";
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();
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);
}
实验现象如下:
项目完整源码如下:
活动总结体会
非常感谢电子工程世界和得捷电子提供了这次宝贵的活动机会,使我受益匪浅。在活动中,我学到了很多新知识,例如如何使用 ESP32 S3 和 ESP8266 连接 Wi-Fi,以及相关 Arduino API 和库的使用。这次活动让我对 Arduino 的操作更加得心应手。
由于之前较少接触 Arduino IDE,本次活动中所有的代码都是参考并学习了 Arduino 官方文档后实现的,这不仅提升了我的技术水平,还增强了我的英文阅读能力。此外,我还学会了如何使用运算放大器来生成模拟信号等相关技巧。
再次感谢主办方的支持,这次活动给了我宝贵的学习机会!
本帖最后由 御坂10032号 于 2024-9-13 14:29 编辑