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

留言

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


现在还没有留言