md-llama-com

  • 2024-10-20
  • 加入了学习《【Follow me第二季第2期】Arduino UNO R4 WiFi 任务视频》,观看 【Follow me第二季第2期】Arduino UNO R4 WiFi 任务视频

  • 加入了学习《【Follow me第二季第1期】Adafruit Circuit Playground Express 任务视频》,观看 【Follow me第二季第1期】Adafruit Circuit Playground Express 任务视频

  • 上传了资料: Follow me 第二季第2期任务Arduino UNO R4 WiFi学习源码

  • 2024-10-06
  • 发表了主题帖: 【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,非常值得学习的方案。 # 汇总视频链接 [localvideo]bf33d481ab30092d6d1ba4513cc03fc2[/localvideo] # 全部物料清单(含物料名称、实物图片) 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界面可以看到设备连接数加一 这样EMQX  HA 之间就打通了 接下来要将咱们的主角与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[length];   memcpy(message,payload,length);   message[length]= '\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(state)); } void onButtonCommand(HAButton* sender) {   if(sender ==&buttonON)   {     Serial.print("[dbg]buttonON");// button A was clicked, do your logic hereelse     digitalWrite(LED_BUILTIN, HIGH);    }    else if(sender==&buttonOFF)    {     Serial.print("[dbg]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[length];   memcpy(message,payload,length);   message[length]= '\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(state)); } void onButtonCommand(HAButton* sender) {   if(sender ==&buttonON)   {     Serial.print("[dbg]buttonON");// button A was clicked, do your logic hereelse     digitalWrite(LED_BUILTIN, HIGH);    }    else if(sender==&buttonOFF)    {     Serial.print("[dbg]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); HASensorNumber  humidity2("myhumidity"); HASensorNumber  Temperature2("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[length];   memcpy(message,payload,length);   message[length]= '\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(state)); } void onButtonCommand(HAButton* sender) {   if(sender ==&buttonON)   {     Serial.print("[dbg]buttonON");// button A was clicked, do your logic hereelse     digitalWrite(LED_BUILTIN, HIGH);    }    else if(sender==&buttonOFF)    {     Serial.print("[dbg]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提供的这次学习机会。这次经历不仅丰富了我的技术储备,也为我未来的电子项目和职业生涯打下了坚实的基础。我期待着将这些新学到的技能应用到更多的创新项目中,并且希望能够继续在电子和编程领域不断探索和成长。 # 项目程序 # End

  • 2024-09-02
  • 加入了学习《【Follow me第二季第1期】全部任务演示短视频》,观看 【Follow me第二季第1期】任务演示视频

  • 2024-09-01
  • 上传了资料: 【Follow me第二季第1期】Adafruit Circuit Playground Express 代码

  • 加入了学习《【得捷电子Follow me第2期】+项目汇报视频》,观看 【得捷电子Follow me第2期】+项目汇报视频

  • 加入了学习《【Follow me第二季第1期】全部任务演示》,观看 全部任务演示2.0

  • 加入了学习《FollowMe 第二季: 1 Adafruit Circuit Playground Express及任务讲解》,观看 Adafruit Circuit Playground Express 及任务讲解

  • 发表了主题帖: Follow me第二季第1期】汇总贴:Adafruit Circuit Playground Express学习

    本帖最后由 md-llama-com 于 2024-10-10 11:17 编辑 Follow me 第二季终于来了,又可以白嫖技术白嫖板子了 ~ 闲话少说 ~开启今日份任务汇总 # [汇总视频链接](https://training.eeworld.com.cn/video/40996 "汇总视频链接") # 全部物料清单(含物料名称、实物图片) 1.Adafruit Circuit Playground Express 2.USB线一根 3.杜邦线,跳线若干 4.水果,苹果什么的 # 必做任务 ## 入门任务(必做):开发环境搭建,板载LED点亮 ### 步骤 1.连接到 USB ### 步骤 2.按 RESET 进入 bootloader 模式 一定要绿色才是连上 ### 步骤 3.打开arduino在左侧栏的Boards Manager,安装arduino SAMD 安装好后就能在工具一栏看到这个板子了 ### 步骤 4.点亮LED 想要点亮一个LED,首先你要知道这块板子的引脚布局 D13正是这次要点亮的LED 在Arduino上新建项目并定义13号引脚为输出引脚 设定其高电平2秒低电平1秒 ```cpp void setup() {   pinMode(13, OUTPUT); } void loop() {   digitalWrite(13, HIGH);   delay(2000);   digitalWrite(13, LOW);   delay(1000); } ``` **下面是效果** ## 基础任务一(必做):控制板载炫彩LED,跑马灯点亮和颜色变换 搭配器件: Adafruit Circuit Playground Express 跑马灯要用到彩色LED,与Adafruit_NeoPixel.h库。 其实跑马灯就是让颜色一次更替点亮形成的效果 ```code #include #define PIN 8 // 定义按钮引脚 #define BUTTON_BRIGHTNESS 4 // 调节亮度 #define BUTTON_EFFECT 5     // 切换效果 #define NUM_LEDS 10 //LED灯数量 Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ400); int brightness = 50; void setup() {   strip.begin();   strip.setBrightness(brightness);   strip.show();   Serial.begin(9600); } void loop() {   // 执行当前效果       Cycle(5); } // 使彩虹色均匀分布 void Cycle(uint8_t wait) {   uint16_t i, j;   for (j = 0; j < 256 * 5; j++) {     for (i = 0; i < strip.numPixels(); i++) {       strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));     }     strip.show();     delay(wait);   } } uint32_t Wheel(byte WheelPos) {   WheelPos = 255 - WheelPos;   if (WheelPos < 85) {     return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);   }   if (WheelPos < 170) {     WheelPos -= 85;     return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);   }   WheelPos -= 170;   return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0); } ``` **流程图** **效果如下** ## 基础任务二(必做):监测环境温度和光线,通过板载LED展示舒适程度 搭配器件: Adafruit Circuit Playground Express 这个任务要用到板载传感器,以及Adafruit_CircuitPlayground.h库 搜索库Circuit Playground就可找到,这个库需要安装很多依赖 光照强度传感器在左侧那么就让左侧彩色LED显示光照强度,光照越亮LED点亮的越多,光照强度以50为单位。500为上限。 `map` 函数的工作原理是线性插值。它按照以下公式计算新的值: 这意味着 `brightness` 的值会被线性地缩放到0到100的范围内。例如,如果 `brightness` 是250,那么 `overallBrightness` 将会是50。 温度强度传感器在右侧那么就让右侧彩色LED显示温度强度,温度越高LED点亮的越多,今天天气30多度,那么设定30度亮3个LED ```cpp #include int prevTempLedCount = -1; // 初始化 int prevBrightnessLedCount = -1; // 初始化 void setup() {   CircuitPlayground.begin(); } void loop() {   displayTemperature();   displayBrightness();   delay(1000); // 每秒更新 } void displayTemperature() {   float temperature = CircuitPlayground.temperature() - 6;//校准,板载温度影响6度   int ledCount = 3; // 30-35度时亮三颗   uint32_t color = CircuitPlayground.colorWheel(85); // 绿色   if (temperature < 30) {     ledCount = max(0, 3 - (30 - temperature) / 5);     color = CircuitPlayground.colorWheel(170); // 蓝色   } else if (temperature > 35) {     ledCount = min(5, 3 + (temperature - 35) / 5);     color = CircuitPlayground.colorWheel(0); // 红色   }   // 如果LED数量没有变化,则不更新   if (ledCount != prevTempLedCount) {     for (int i = 0; i < 5; i++) {       if (i < ledCount) {         CircuitPlayground.setPixelColor(5+i, color);       } else {         CircuitPlayground.setPixelColor(5+i, 0); // 关闭LED       }     }     prevTempLedCount = ledCount; // 更新上一次的LED数量   } } void displayBrightness() {   int brightness = CircuitPlayground.lightSensor();   int ledCount = min(5, brightness / 50); // 亮度每增加50 LED增加一颗   uint8_t overallBrightness = map(brightness, 0, 500, 0, 100);   // 如果LED数量没有变化,则不更新   if (ledCount != prevBrightnessLedCount) {     for (int i = 0; i < 5; i++) {       if (i < ledCount) {         CircuitPlayground.setPixelColor(4-i, 255, 255, 255); // 白色       } else {         CircuitPlayground.setPixelColor(4-i, 0); // 关闭LED       }     }     prevBrightnessLedCount = ledCount; // 更新上一次的LED数量   } } ``` **流程图** **下面是温度效果,用的开水壶加热** **下面是光照强度效果** ## 基础任务三(必做):接近检测——设定安全距离并通过板载LED展示,检测到入侵时,发起声音报警 搭配器件: Adafruit Circuit Playground Express 这个任务要用到板载传感器,以及Adafruit_CircuitPlayground.h库,红外发送及红外接收传感器。 定义红外接收和发射的引脚 const int irTransmitterPin = 25; //引脚定义 const int irReceiverPin = A10; analogRead函数读取红外接收的数值 analogRead(irReceiverPin); 用串口输出LED点亮情况和距离情况 下面是程序内容 ```code #include #define SAFE_DISTANCE 450 // 定义安全距离 const int alertTone = 1000; // 警报音调 const int iTPin = 25; //引脚定义 const int iRPin = A10; void setup() {   CircuitPlayground.begin();   Serial.begin(9600); //   pinMode(iRPin, INPUT); // 红外传感器输入    pinMode(iTPin, OUTPUT);// 红外led输出   delay(100); } void loop() {    sendIRPulse();   int distance = analogRead(iRPin); // 读取红外传感器的值   // 打印距离   Serial.print("Distance: ");   Serial.println(distance);   Distance(distance);   checkForIntrusion(distance);   delay(300); } void Distance(int distance) {   int ledCount = map(distance, 290, SAFE_DISTANCE, 1, 10); // 将距离值映射到0-10的LED数量   Serial.print("LED Count: ");   Serial.println(ledCount);   for (int i = 0; i < 10; i++) {     if (i < ledCount) {       CircuitPlayground.setPixelColor(i, 0, 255, 0);     } else {       CircuitPlayground.setPixelColor(i, 0);     }   } } void checkForIntrusion(int distance) {   if (distance > SAFE_DISTANCE) {     Serial.println("Intrusion detected!");     playAlertTone();   } } void sendIRPulse() {   for (int i = 0; i < 32; i++) {     digitalWrite(iTPin, HIGH);     delayMicroseconds(13);     digitalWrite(iTPin, LOW);     delayMicroseconds(13);   } } void playAlertTone() {   CircuitPlayground.playTone(alertTone, 500); // 播放警报音500ms } ``` **流程图** **下面是演示** ## 进阶任务(必做):制作不倒翁——展示不倒翁运动过程中的不同灯光效果 搭配器件: Adafruit Circuit Playground Express、不倒翁 这个任务要用到板载陀螺仪传感器,以及Adafruit_CircuitPlayground.h库和math.h库 不倒翁的制作需要读取加速度传感器的XYZ轴数据,并根据这些数据来控制LED灯的颜色和亮度。 因为加速度传感器给出的数据是非整数,所以定义XYZ为浮点型   float x = CircuitPlayground.motionX();   float y = CircuitPlayground.motionY();   float z = CircuitPlayground.motionZ();    使用 sqrt(Y x Y + Z x Z) 和 sqrt(X x X + Z x Z) 来计算与水平面的夹角,这样可以更准确地反映角度。 然后将角度映射到10个小灯位置上用的是if语句判断 **下面是程序**    ```code #include #include void setup() {   CircuitPlayground.begin();   Serial.begin(9600); } void loop() {   float x = CircuitPlayground.motionX();   float y = CircuitPlayground.motionY();   float z = CircuitPlayground.motionZ();   // 计算与水平面夹角   float angleX = atan2(x, sqrt(y * y + z * z)) * 180 / PI;   float angleY = atan2(y, sqrt(x * x + z * z)) * 180 / PI;   int ledToLight = -1;   // 映射到彩色灯珠   if (angleX > 11) {     if (angleY < -11) ledToLight = 1;     else if (angleY > 11) ledToLight = 3;     else ledToLight = 2;   } else if (angleX < -11) {     if (angleY < -11) ledToLight = 8;     else if (angleY > 11) ledToLight = 6;     else ledToLight = 7;   } else {     if (angleY > 11) {       ledToLight = 4;     } else if (angleY < -11) {       ledToLight = 0;     }   }   if (ledToLight == -1) {     for (int i = 0; i < 10; i++) {       CircuitPlayground.setPixelColor(i, CircuitPlayground.colorWheel(51)); // 水平时都点亮51代表颜色85是绿色0是红色     }   } else {     for (int i = 0; i < 10; i++) {       if (i == ledToLight || (ledToLight == 4 && i == 5) || (ledToLight == 0 && i == 9)) {         CircuitPlayground.setPixelColor(i, CircuitPlayground.colorWheel(32));//32代表颜色       } else {         CircuitPlayground.setPixelColor(i, 0);       }     }   }   delay(100); } ``` **流程图** **效果如下** # 创意任务(选做,选择其中一个或多个都可) ## 创意任务三:水果钢琴——通过触摸水果弹奏音乐,并配合灯光效果 搭配器件: Adafruit Circuit Playground Express、水果我选的是苹果 其实就是把引脚视为电容开关,手触摸水果,引脚电容发生改变,从而被单片机检测到,最终让蜂鸣器发出声音 程序如下图 ```code #include #define CAP_SAMPLES 10 #define TONE_DURATION_MS 100 uint16_t CAP_THRESHOLD = 1000; void setup() {   CircuitPlayground.begin();   Serial.begin(115200); } unsigned long clearTime; void playToneAndLightLEDs(int touchPoint) {   CircuitPlayground.clearPixels();   clearTime = millis();   int tones[] = {261, 293, 329, 349, 392, 440, 494};   int tone = tones[touchPoint - 15];   CircuitPlayground.playTone(tone, TONE_DURATION_MS);   for (int i = 0; i < 10; i++) {     bool light = true;     switch (touchPoint) {       case 15: light = i != 5; break;       case 16: light = i != 5 && i != 6; break;       case 17: light = i != 5 && i != 6 && i != 7; break;       case 18: light = i < 5; break;       case 19: light = i > 0 && i < 5; break;       case 20: light = i > 1 && i < 5; break;       case 21: light = i > 2 && i < 5; break;     }     if (light) {       CircuitPlayground.strip.setPixelColor(i, CircuitPlayground.colorWheel(256 / 10 * (i + 1)));     }   }   CircuitPlayground.strip.show(); } void loop() {   if (millis() - clearTime > 2000) {     CircuitPlayground.clearPixels();   }   for (int i = 15; i CAP_THRESHOLD) {       playToneAndLightLEDs(i);     }   } } ``` **流程图** 下面是手直接触摸的效果 接下来就是把A1,A2,A3,A4,A5,A6,A7接上线插入苹果中啦 # 项目总结 这次Follow me 第二季真的学到好多东西,基于Adafruit Circuit Playground Express 学到了红外测距,学到了触摸控制,温度,光照传感器,也学到了加速度传感器等等。通过这些项目,我不仅增强了自己的实践操作技能,同时也加深了我对硬件编程的认识。特别感谢EEWorld和Digi-Key提供这次宝贵的体验机会。

  • 加入了学习《【Follow me第二季第一期】任务汇总(by cyz6668)》,观看 【Follow me第二季第一期】任务汇总(by cyz6668)

最近访客

< 1/1 >

统计信息

已有14人来访过

  • 芯积分:69
  • 好友:--
  • 主题:5
  • 回复:1

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言