一 、3-5分钟短视频
视频连接:Follow me第二季第2期视频
二、任务实现详情
项目简介:Follow me活动是DigiKey联合EEWorld发起的大型开发板体验活动,每期技术大咖推荐可玩性与可学性较强的开发板/仪器套件,带着大家实际操作,参与者完成任务即返京东卡。本季共四期活动,本次活动为第2期。
全部物料清单:Arduino UNO R4 WiFi:
各任务实现详情:
入门任务(必做):搭建环境并开启第一步Blink / 串口打印Hello EEWorld!搭配器件: Arduino UNO R4 WiFi
环境搭建十分简单:1、安装好Arduino IDE;2、安装板包;3、连接开发板选择端口即可,详细操作参见上面视频,也可参考官方文档。
Blink程序十分简单,只需要这几行代码:
void setup() {
// 初始化数字引脚 LED_BUILTIN 作为输出
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // 打开LED
delay(1000); // 延时一秒
digitalWrite(LED_BUILTIN, LOW); // 关闭LED
delay(1000); // 延时一秒
}
串口输出程序代码:
int times = 1;
void setup() {
// 初始化串口
Serial.begin(9600);
}
void loop() {
// 串口输出
Serial.print(times);
Serial.println(": Hello EEWorld!");
// 计次自增
times ++;
// 延时1秒
delay(1000);
}
基础任务(必做):驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线:搭配器件: Arduino UNO R4 WiFi
驱动12x8点阵LED可以使用内置的示例:
#include "Arduino_LED_Matrix.h"
#include "animation.h"
ArduinoLEDMatrix matrix;
void setup() {
Serial.begin(115200);
matrix.loadSequence(animation);
matrix.begin();
matrix.play(true);
}
void loop() {
delay(500);
Serial.println(millis());
}
软件流程图:
#include "analogWave.h"
analogWave wave(DAC);
int freq = 10;
void setup() {
Serial.begin(115200);
wave.sine(freq);
}
void loop() {
freq = 5000;
Serial.println("Frequent is now " + String(freq) + " Hz");
delay(1000);
wave.freq(freq);
}
程序下载后,可以用示波器看到波形:
也可以用ADC采集并且打印数据到串口,看到正弦波:
#include "analogWave.h"
analogWave wave(DAC);
int freq = 10;
void setup() {
Serial.begin(115200);
wave.sine(freq);
}
void loop() {
// 用ADC采集并且打印数据到串口
freq = 25;
int sensorValue = analogRead(A0);
// 将模拟值转换为电压值(0到5V)
float voltage = sensorValue * (5.0 / 1023.0);
// Print the updated frequency to the serial monitor
Serial.println("voltage is now " + String(voltage) + " v");
wave.freq(freq);
}
用OPAMP放大DAC信号:
#include <OPAMP.h>
void setup () {
Serial.begin(9600);
delay(2000); // serial monitor delay
// activate OPAMP, default channel 0
// Plus: Analog A1
// Minus: Analog A2
// Output: Analog A3
if (!OPAMP.begin(OPAMP_SPEED_HIGHSPEED)) {
Serial.println("Failed to start OPAMP!");
}
bool const isRunning = OPAMP.isRunning(0);
if (isRunning) {
Serial.println("OPAMP running on channel 0!");
} else {
Serial.println("OPAMP channel 0 is not running!");
}
}
void loop() {
delay(10); // do nothing
}
这样就开启了运放,可以当成一个普通的运放使用,视频中可以看到R1阻值为1165Ω,R2阻值为3718欧姆,放大倍数为1.313,实际将3.3v的信号放大为了4.27v,符合预期。
进阶任务(必做):通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant):搭配器件: Arduino UNO R4 WiFi
智能家居平台HA我使用的是自己在树莓派搭建的,具体搭建流程可以参考这篇帖子,当然用docker可能更为方便,docker部署我没有尝试,可以参考网友的。
代码如下:
#include "Arduino_LED_Matrix.h" //Include the LED_Matrix library
#include "animation.h" //Include animation.h header file
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include "mqtt_config.h"
ArduinoLEDMatrix matrix;
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = BROKER;
int port = 1883;
const char pub_topic[] = PUB_TOPIC;
const char sub_topic[] = SUB_TOPIC;
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
//配置led灯模式为输出
pinMode(LED_BUILTIN, OUTPUT);
//初始化串口,并等待串口打开
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
matrix.loadSequence(animation);
matrix.begin();
// turn on autoscroll to avoid calling next() to show the next frame; the paramenter is in milliseconds
// matrix.autoscroll(300);
matrix.play(true);
// 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();
// 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("clientId");
// You can provide a username and password for authentication
// mqttClient.setUsernamePassword("username", "password");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
delay(3000);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
Serial.print("Subscribing to topic: ");
Serial.println(sub_topic);
Serial.println();
// subscribe to a topic
mqttClient.subscribe(sub_topic);
// topics can be unsubscribed using:
// mqttClient.unsubscribe(topic);
pinMode(LED_BUILTIN, OUTPUT);
Serial.print("Waiting for messages on topic: ");
Serial.println(sub_topic);
Serial.println();
//初始化成功提示
Serial.print("INIT success!");
}
void loop() {
int messageSize = mqttClient.parseMessage();
if (messageSize) {
// use the Stream interface to print the contents
while (mqttClient.available()) {
char msg = (char)mqttClient.read();
// Serial.print(msg);
// Serial.println();
led_switch(&msg);
}
//串口输出
Serial.print("Hello EEWorld!"); //串口打印Hello EEWorld
Serial.println(); //换行
}
}
还需要配置 mqtt_config.h文件:
#define SECRET_SSID "wifi名称"
#define SECRET_PASS "WiFi密码"
#define BROKER "192.168.3.49"
#define PUB_TOPIC "arduino/publish"
#define SUB_TOPIC "arduino/publish"
void led_switch(const char *data) {
if (*data == '1') {
Serial.println("Turn the Arduino LED on");
digitalWrite(LED_BUILTIN, HIGH); } // turn the LED on (HIGH is the voltage level)
else if (*data == '0') {
Serial.println("Turn the Arduino LED off");
digitalWrite(LED_BUILTIN, LOW ); } // turn the LED off (LOW is the voltage level)
}
还需要在HA的configuration.yaml文件中添加这段配置,添加教程:
mqtt:
switch:
unique_id: led_1 #设备ID
name: "arduino_led" #设备名称
state_topic: "arduino/publish" #订阅端口
command_topic: "arduino/publish" #同上
payload_on: "1" #开灯的指令
payload_off: "0" #关灯的指令
流程图:
扩展任务(必做):通过外部环境光传感器,上传光照度到HA,通过HA面板显示数据,并控制电机行为:搭配器件: Arduino UNO R4 WiFi、Adafruit 8-Channel PWM、DFRobot analog lightsensor:
首先是将传感器添加到HA面板:
在HA的configuration.yaml文件中添加这段配置:
sensor:
unique_id: arduino_sensor_1 #设备ID
name: "light_sensor" #设备名称
state_topic: "homeassistant/sensor/light" #订阅端口
unit_of_measurement: "%"
value_template: "{{value_json.light}}"
刷新后就可以在HA面板看到传感器:
import time
from adafruit_servokit import ServoKit
kit = ServoKit(channels=8)
kit.servo[0].angle = 180
kit.continuous_servo[1].throttle = 1
time.sleep(1)
kit.continuous_servo[1].throttle = -1
time.sleep(1)
kit.servo[0].angle = 0
kit.continuous_servo[1].throttle = 0
最后是完成Arduino UNO R4 WiF的代码:
#include <ArduinoJson.h>
#include <ArduinoJson.hpp>
#include "Arduino_LED_Matrix.h" //Include the LED_Matrix library
#include "animation.h" //Include animation.h header file
#include <ArduinoMqttClient.h>
#include <WiFiS3.h>
#include "mqtt_config.h"
ArduinoLEDMatrix matrix;
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
const char broker[] = BROKER;
int port = 1883;
const char pub_topic[] = PUB_TOPIC;
const char sub_topic[] = SUB_TOPIC;
const long interval = 1000;
unsigned long previousMillis = 0;
int count = 0;
void setup() {
//配置led灯模式为输出
pinMode(LED_BUILTIN, OUTPUT);
//初始化串口,并等待串口打开
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}
matrix.loadSequence(animation);
matrix.begin();
// turn on autoscroll to avoid calling next() to show the next frame; the paramenter is in milliseconds
// matrix.autoscroll(300);
matrix.play(true);
// 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();
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
delay(3000);
if (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
while (1);
}
Serial.println("You're connected to the MQTT broker!");
Serial.println();
Serial.print("Subscribing to topic: ");
Serial.println(sub_topic);
Serial.println();
// subscribe to a topic
mqttClient.subscribe(sub_topic);
// topics can be unsubscribed using:
// mqttClient.unsubscribe(topic);
pinMode(LED_BUILTIN, OUTPUT);
Serial.print("Waiting for messages on topic: ");
Serial.println(sub_topic);
Serial.println();
//初始化成功提示
Serial.print("INIT success!");
}
void loop() {
int lightsensor = analogRead(0);
int messageSize = mqttClient.parseMessage();
if (messageSize) {
// use the Stream interface to print the contents
while (mqttClient.available()) {
char msg = (char)mqttClient.read();
// Serial.print(msg);
// Serial.println();
led_switch(&msg);
}
//串口输出
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
update_sensor(lightsensor);
Serial.println("updated");
count++;
}
}
void servo(int msg) {
mqttClient.beginMessage("None/f/servo");
mqttClient.print(msg);
mqttClient.print("\0");
mqttClient.endMessage();
}
void update_sensor(int value){
StaticJsonDocument<200> doc;
int a = value*100/1024;
open_window(a);
doc["light"] = a;
String payload;
serializeJson(doc, payload);
mqttClient.beginMessage("homeassistant/sensor/light");
mqttClient.print(payload.c_str());
mqttClient.print("\0");
mqttClient.endMessage();
}
void open_window(int value){
if (value<25){
servo(1);
}
else if (value<50 && value>=25){
servo(2);
}
else if (value<75 && value>=50){
servo(3);
}
else if (value<101 && value>=75){
servo(4);
};
}
流程图:
舵机行为:
4)对本活动的心得体会
完整地使用Arduino开发出了一些东西,收获很多。不得不说Arduino真是宇宙级IDE,实在是太方便啦。
三、可编译下载的代码
代码:代码