[作品提交] 【Follow me第二季第2期】任务提交帖

夷则玖   2024-10-6 12:49 楼主

一 、3-5分钟短视频

        视频连接:Follow me第二季第2期视频

二、任务实现详情

        项目简介:Follow me活动是DigiKey联合EEWorld发起的大型开发板体验活动,每期技术大咖推荐可玩性与可学性较强的开发板/仪器套件,带着大家实际操作,参与者完成任务即返京东卡。本季共四期活动,本次活动为第2期。

 

        全部物料清单:Arduino UNO R4 WiFi

unor4.png
                    Adafruit 8-Channel PWM
8channel.jpg
                    DFRobot analog lightsensor
DFR0026V2.JPG

            各任务实现详情:

                入门任务(必做):搭建环境并开启第一步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);                      // 延时一秒
}
                    软件流程图:
流程1.png
效果:
1_1[00_00_05][20241006-123009].png  

                    串口输出程序代码:

int times = 1;
void setup() {
  // 初始化串口
  Serial.begin(9600);
}
void loop() {
  // 串口输出
  Serial.print(times);
  Serial.println(": Hello EEWorld!");
  // 计次自增
  times ++;
  // 延时1秒
  delay(1000);
}
                    软件流程图:
流程2.png
效果:

1_2[00_00_09][20241006-123110].png  

                基础任务(必做):驱动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());
}

                    软件流程图:

流程3.png
效果:
2_1[00_00_05][20241006-123158].png  
                        用DAC生成正弦波:
#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);
}

            程序下载后,可以用示波器看到波形:

2[00_00_08][20241006-103132].png  

                        也可以用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);
}
wave.png

 

                        用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,符合预期。

放大后电压.jpg

 

                进阶任务(必做):通过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"          #关灯的指令

流程图:

流程4.png
传感器.png

               扩展任务(必做):通过外部环境光传感器,上传光照度到HA,通过HA面板显示数据,并控制电机行为:搭配器件: Arduino UNO R4 WiFiAdafruit 8-Channel PWMDFRobot 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面板看到传感器:

传感器.png
                            然后完成Adafruit 8-Channel PWM的代码,可以用这个控制舵机转动:
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);
  };
}

 

流程图:

                    

流程图.png

 

舵机行为:

4[00_00_05][20241006-123328].png   4[00_00_11][20241006-123334].png   4[00_00_19][20241006-123347].png  

4)对本活动的心得体会

        完整地使用Arduino开发出了一些东西,收获很多。不得不说Arduino真是宇宙级IDE,实在是太方便啦。

 

三、可编译下载的代码

        代码:代码

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复