本次活动的板卡实物照片:
任务1:搭建环境并开启第一步Blink / 串口打印Hello EEWorld!
板载LED小灯连接到MCU P102引脚。
软件流程图:
接下来在Arduino环境里控制LED与串口打印:
// the setup function runs once when you press reset or power the board
void setup() {
Serial.begin(115200); // Initialize serial communication at a baud rate of 115200
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
Serial.println("Hello EEWorld!");
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
}
实物展示:
任务2-1 驱动12*8 LED矩阵
软件流程图:
UNO R4开发板提供了一个12*8矩阵的LED灯,这是非常奢侈的!以往开发板提供4个小灯不错了,哈哈。
其实驱动起来是非常简单的事情。只需要仔细阅读Arduino官方文档:Using the Arduino UNO R4 WiFi LED Matrix https://docs.arduino.cc/tutorials/uno-r4-wifi/led-matrix/#
然后使用官方提供的工具生成字模即可。
点击右上角的下载,可以保存到本地。
#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() {
matrix.loadFrame(dian);
delay(500); // Pause for 500 milliseconds (half a second)
matrix.loadFrame(zi);
delay(500);
matrix.loadFrame(gong);
delay(500);
matrix.loadFrame(cheng);
delay(500);
matrix.loadFrame(shi);
delay(500);
matrix.loadFrame(jie);
delay(500);
matrix.loadFrame(LEDMATRIX_HEART_BIG);
delay(500);
matrix.clear();
delay(1000);
Serial.println(millis());
}
实物展示:
任务2-2 利用DAC生成正弦波
根据电路原理图,板载A0接口即为DAC输出接口。
使用analogWave库,快速生成正弦波:
#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 = 1000; // 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() {
wave.freq(freq); // Set the frequency of the waveform generator to the updated value
}
实物展示:
任务2-3: 用OPAMP放大DAC信号
软件流程图:
运算放大器,模电的精髓,自从离开校园后没有再计算过运放增益!依稀记得虚短,虚断!
至于放大倍数如何计算:
手头刚好有两个10k电阻,这就搭建一个放大倍数为2的运放电路!
在代码编写方面,简单的就是只有一行语句:
#include <OPAMP.h>
void setup () {
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
}
void loop() {}
这里有个不错的地方,就是可以利用前置任务DAC生成的sine信号作为输入,然后经过运放放大后,接入示波器。
#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 = 1000; // 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
wave.amplitude(0.25);
OPAMP.begin(OPAMP_SPEED_HIGHSPEED);
}
void loop() {
//wave.freq(freq); // Set the frequency of the waveform generator to the updated value
}
实物展示:
任务2-4:使用ADC获取数据并波形展示
软件流程图:
在Arduino中使用ADC接口获取数据:
Serial.println(analogRead(A5));
放大前的信号:
放大后的信号:
为了把两个波形展示在一个图框里,可以采用下面的代码:
Serial.print("Variable_1:");
Serial.print(analogRead(A4));
Serial.print(",");
Serial.print("Variable_2:");
Serial.println(analogRead(A5));
效果:
进阶任务(必做):通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
HomeAssistant是非常知名的智能家居平台,早有耳闻,但是一直没有尝试过。这也是参加本期FM活动的动力!
安装HA有很多种方式,可以参考官网链接:https://www.home-assistant.io/installation/windows/。本文选择的是去下载官网提供的VMware文件,然后直接使用VMWare Workstation来加载这个虚拟机。
安装过程有很多参考文章,在此不再赘述。
看到上面的标志性界面后,就可以打开主机上的浏览器,然后输入http://homeassistant.local:8123/ 来进入到HA Os里面。之后就是漫长的等待,真的是漫长。
添加EMQX,目的是在HA里面搭建一个MQTT服务器或者BROKER代理。
稍后进入到EMQX平台,需要用户名和密码:
接着配置认证方式:
EMQX里面创建一个用户名和密码,稍后在HA设备与服务->MQTT配置参数的时候可用到。后续还可以添加更多的用户:
接着配置一个MQTT应用。这个应用会连接到上一步中创建的MQTT BROKER。
在HA->Settings->Device and Service->Add Integration ->MQTT->Manually add MQTT
完整的测试代码:
/*
ArduinoMqttClient - WiFi Simple Sender
This example connects to a MQTT broker and publishes a message to
a topic once a second.
The circuit:
- Arduino MKR 1000, MKR 1010 or Uno WiFi Rev2 board
This example code is in the public domain.
*/
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
// flashed in the WiFi module.
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = "192.168.0.102";
int port = 1883;
const char topic[] = "mqttx2emqx";
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
// attempt to connect to WiFi network:
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.println(ssid);
printWifiStatus();
Serial.println();
// You can provide a unique client ID, if not set the library uses Arduino-millis()
// Each client must have a unique client ID
mqttClient.setId("clientIdmurong");
// You can provide a username and password for authentication
// mqttClient.setUsernamePassword("arduinoUnoBoard", "arduinoUnoBoard");
mqttClient.setUsernamePassword("Sensorhub", "sensorhub");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
delay(100);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
}
void loop() {
// call poll() regularly to allow the library to send MQTT keep alives which
// avoids being disconnected by the broker
mqttClient.poll();
// to avoid having delays in loop, we'll use the strategy from BlinkWithoutDelay
// see: File -> Examples -> 02.Digital -> BlinkWithoutDelay for more info
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
// save the last time a message was sent
previousMillis = currentMillis;
Serial.print("Sending message to topic: ");
Serial.println(topic);
Serial.print("hello ");
Serial.println(count);
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic);
mqttClient.print("hello ");
mqttClient.print(count);
mqttClient.endMessage();
Serial.println();
count++;
}
}
/* -------------------------------------------------------------------------- */
void printWifiStatus() {
/* -------------------------------------------------------------------------- */
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);
// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
实物展示:
扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA,通过HA面板显示数据
上面已经在HA里面把MQTT给调通了,接下来增加温湿度数据给HA。
添加HA实体,通过在MQTTX里面发送如下内容至topic:
温度topic:
homeassistant/sensor/SHT40_TEMP/config
温度内容:
{
"device_class":"temperature",
"name":"Temperature",
"state_topic":"homeassistant/SHT40/state",
"unit_of_measurement":"°C",
"value_template":"{{ value_json.temperature}}",
"unique_id":"temp_HA101",
"device":{
"identifiers":[
"SHT40"
],
"name":"SHT40-TEMP_HUMI"
}
}
湿度topic:
homeassistant/sensor/SHT40_HUMI/config
湿度内容:
{
"device_class":"humidity",
"name":"Humidity",
"state_topic":"homeassistant/SHT40/state",
"unit_of_measurement":"rH%",
"value_template":"{{ value_json.humidity}}",
"unique_id":"hum_HA101",
"device":{
"identifiers":[
"SHT40"
],
"name":"SHT40-TEMP_HUMI"
}
}
刷新HA:
接下来添加SHT40的库,这里选择Adafruit家的:
#include "Adafruit_SHT4x.h"
接着初始化SHT40设备:
Serial.println("Adafruit SHT4x Init");
if (! sht4.begin(&Wire1)) {
Serial.println("Couldn't find SHT4x");
while (1) delay(1);
}
Serial.println("Found SHT4x sensor");
Serial.print("Serial number 0x");
Serial.println(sht4.readSerial(), HEX);
// You can have 3 different precisions, higher precision takes longer
sht4.setPrecision(SHT4X_HIGH_PRECISION);
switch (sht4.getPrecision()) {
case SHT4X_HIGH_PRECISION:
Serial.println("High precision");
break;
case SHT4X_MED_PRECISION:
Serial.println("Med precision");
break;
case SHT4X_LOW_PRECISION:
Serial.println("Low precision");
break;
}
// 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);
switch (sht4.getHeater()) {
case SHT4X_NO_HEATER:
Serial.println("No heater");
break;
case SHT4X_HIGH_HEATER_1S:
Serial.println("High heat for 1 second");
break;
case SHT4X_HIGH_HEATER_100MS:
Serial.println("High heat for 0.1 second");
break;
case SHT4X_MED_HEATER_1S:
Serial.println("Medium heat for 1 second");
break;
case SHT4X_MED_HEATER_100MS:
Serial.println("Medium heat for 0.1 second");
break;
case SHT4X_LOW_HEATER_1S:
Serial.println("Low heat for 1 second");
break;
case SHT4X_LOW_HEATER_100MS:
Serial.println("Low heat for 0.1 second");
break;
}
在MQTT发布数据包里面,把温湿度数据添加进去:
// send message, the Print interface can be used to set the message contents
mqttClient.beginMessage(topic);
mqttClient.print("{\"humidity\": ");
mqttClient.print(humidity.relative_humidity);
mqttClient.print(", \"temperature\": ");
mqttClient.print(temp.temperature);
mqttClient.print("}");
mqttClient.endMessage();
实物展示:
总结:
这次参加FOLLOW ME活动,体验了HA与MQTT,把SHT40温湿度数据成功上传到了云端。收获很大。期待能够把HA再玩的熟练些,控制小灯,开关等。
代码汇总:
https://download.eeworld.com.cn/detail/%E6%85%95%E5%AE%B9%E9%9B%AA%E8%8A%B1/634522
引用: Jacktang 发表于 2024-9-28 07:56 这些任务完成真是不错,还有自己的讲解,赞 期待楼主能够把HA再玩的熟练些,控制小灯,开关等,再来继续 ...
感谢坛友分享,第一次用HA,网段与UNO不在一起,折腾了半天,掉了2跟头发