ctrlshift12138

  • 2024-11-08
  • 回复了主题帖: 【Follow me第二季第2期】(Arduino Uno R4)作品提交汇总

    ctrlshift12138 发表于 2024-11-8 23:54 在旧版种,代码缩进是正常的;新版界面,代码缩进有问题的。       ... 好像是 Tab 缩进无法识别

  • 回复了主题帖: 【Follow me第二季第2期】(Arduino Uno R4)作品提交汇总

    nmg 发表于 2024-11-2 19:36 可以具体说说嘛,看我们这边能否改进 在旧版种,代码缩进是正常的;新版界面,代码缩进有问题的。          

  • 2024-10-11
  • 回复了主题帖: 【Follow me第二季第2期】(Arduino Uno R4)作品提交汇总

    文章中嵌入的代码缩进有些问题,大家可以下载源代码自行查看

  • 回复了主题帖: 【Follow me第二季第2期】(Arduino Uno R4)作品提交汇总

    文章最后2张图是显示BUG,我在编辑页面是没有这2张图的,浏览时请大家忽略

  • 2024-10-08
  • 发表了主题帖: 【Follow me第二季第2期】(Arduino Uno R4)作品提交汇总

    # 【Follow me第二季第2期】任务提交 ## 一、前置准备: 硬件:无 软件:VSCode、科学上网工具 ### 1、设置代理 打开VSCode,进入设置 搜索“代理”,在1和2中填写代理服务器的地址和端口,并取消勾选3 ### 2、安装PlatformIO IDE扩展 选择扩展,搜索“PlatformIO”,安装扩展插件 ### 4、升级WiFi模块固件(非必须步骤,可跳过) 下载下面代码到arduino Uno R4 WiFi开发板,检查的WiFi模块(ESP32-S3)的固件。如果WiFi模块固件不是最新版本,建议升级固件。 ```cpp #include #include void setup() {         Serial.begin(115200);         BaseType_t xReturn;         // 检查WiFi模组         if (WiFi.status() == WL_NO_MODULE)         {                 Serial.println("Communication with WiFi module failed!");                 while (true);         }         String fv = WiFi.firmwareVersion();         Serial.print("Current WiFi firmware version:");         Serial.println(fv);         Serial.print("Laste WiFi firmware version:");         Serial.println(WIFI_FIRMWARE_LATEST_VERSION);         if (fv < WIFI_FIRMWARE_LATEST_VERSION)         {                 Serial.println("Please upgrade the firmware");         } } void loop() { } ``` [官方更新WiFi模块固件教程和资源链接](https://support.arduino.cc/hc/en-us/articles/9670986058780-Update-the-connectivity-module-firmware-on-UNO-R4-WiFi#espflash) 1、下载并解压官方资源 2、使用跳线帽(或金属镊子)短接图中突出显示的引脚: ![The GND and Download ESP32 pins.](/data/attachment/forum/202410/08/020439n8seso30j6f2sosn.png.thumb.jpg?rand=7115.516748703152) 3、使用 USB 线将 UNO R4 WiFi 板连接到电脑 4、运行`update.bat`脚本 5、选择正确的串口,并等待固件更新完成 ## 二、入门任务 **Blink&串口打印Hello EEWorld!** 硬件:Arduino UNO R4 WiFi、USB-C to A线 软件:VSCode ### 1、操作步骤 打开PlatformIO的“home”主页,选择“New Project” 填写“Name”,“Board”选择“Arduino Uno R4 WiFi”,“Framework”选择“Arduino”,“Location”为项目存放位置,自行设置。 点击“FInish”,等待相关资源下载完成(如果卡在下载资源,请设置代理)。 ### 2、代码 ```cpp #include #include void blink(void * para); void printHelloWorld(void * para); // 任务句柄 TaskHandle_t blink_task_handle = NULL; TaskHandle_t print_hello_world_task_handle = NULL; void setup() {         pinMode(LED_BUILTIN, OUTPUT);                // LED管脚设置为输出模式         Serial.begin(115200);                                // 串口设置波特率115200         // 创建Blink任务         xTaskCreate((TaskFunction_t)blink,                                 (const char*)"blink",                                 100,                                 NULL,                                 1,                                 &blink_task_handle);         configASSERT( blink_task_handle );         // 创建串口打印任务         xTaskCreate((TaskFunction_t)printHelloWorld,                                 (const char *)"printHelloWord",                                 100,                                 NULL,                                 2,                                 &print_hello_world_task_handle);         configASSERT(print_hello_world_task_handle);         vTaskStartScheduler();                                // 启动任务调度 } void blink(void * para) {         while (1)         {                 digitalWrite(LED_BUILTIN, HIGH);                // 点亮LED                 vTaskDelay(500 * portTICK_PERIOD_MS);        // 延时500ms                 digitalWrite(LED_BUILTIN, LOW);                        // 关闭LED                 vTaskDelay(500 * portTICK_PERIOD_MS);        // 延时500ms         } } void printHelloWorld(void * para) {         while (1)         {                 Serial.println("Hello EEWorld !");                // 串口打印                 vTaskDelay(1000 * portTICK_PERIOD_MS);        // 延时1000ms         } } void loop() { } ``` ### 3、说明 软件流程图: 使用FreeRTOS创建了“blink”和“printHelloWord”两个任务,分别实现了LED指示灯每隔0.5秒闪烁一次,串口每隔1秒发送一次“Hello EEWorld!”。 ```cpp pinMode(LED_BUILTIN, OUTPUT);                // LED管脚设置为输出模式 ``` `LED_BUILTIN`为板上的黄色LED灯对应的管脚,见下图,`OUTPUT`表示将该管脚设置为输出模式。 ### 4、效果展示 LED灯闪烁 串口打印 ## 三、基础任务 **驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线** 硬件:Arduino UNO R4 WiFi、USB-C to A线、10K插件电阻、公对公杜邦线 软件:VSCode、Arduino IDE ### 1、代码:驱动12x8点阵LED ```cpp #include #include #include #include void blink(void * para); void ledMatrix(void * para); // 任务句柄 TaskHandle_t blink_task_handle = NULL; TaskHandle_t led_matrix_task_handle = NULL; ArduinoLEDMatrix matrix; void setup() {         pinMode(LED_BUILTIN, OUTPUT);         matrix.begin();         // 创建Blink任务         xTaskCreate((TaskFunction_t)blink,                                 (const char*)"blink",                                 100,                                 NULL,                                 1,                                 &blink_task_handle);         configASSERT( blink_task_handle );         // 创建点阵LED任务         xTaskCreate((TaskFunction_t)ledMatrix,                                 (const char *)"ledMatrix",                                 100,                                 NULL,                                 2,                                 &led_matrix_task_handle);         configASSERT(led_matrix_task_handle);         vTaskStartScheduler();                                // 启动任务调度 } void loop() { } void blink(void * para) {         while (1)         {                 digitalWrite(LED_BUILTIN, HIGH);                // 点亮LED                 vTaskDelay(500 * portTICK_PERIOD_MS);        // 延时500ms                 digitalWrite(LED_BUILTIN, LOW);                        // 关闭LED                 vTaskDelay(500 * portTICK_PERIOD_MS);        // 延时500ms         } } void ledMatrix(void *para) {         while (1)         {                 uint16_t length = sizeof(frames)/sizeof(frames[0]);                 for ( uint16_t i = 0; i < length; i++)                 {                         matrix.loadFrame(&frames[0]);                         vTaskDelay(33 * portTICK_PERIOD_MS);                 }         } } ``` ### 2、说明 软件流程图: 使用FreeRTOS创建了“blink”和“led_matrix”两个任务,分别实现了LED指示灯每隔0.5秒闪烁一次;使用LED矩阵播放动画。动画的数据在.h文件中,在代码合集中给出。 因为动画的30fps,每帧约33.3ms,所以使用了`vTaskDelay(33 * portTICK_PERIOD_MS);`来设置固定的延时。 关于如何生成动画的文件: 1、使用ffmpeg,将视频中的每一帧输出为12*8大小的bmp文件; ```ba ffmpeg -i video.m4s -vf scale=12:8 output_frame_%04d.bmp ``` 2、将bmp文件转换为hex格式的文件,以下是python转换脚本 ```python from PIL import Image import os def convert_image_to_led_matrix(input_image):     # 打开图片并将其转换为灰度模式     image = Image.open(input_image).convert('1')  # '1'模式表示黑白模式     # 缩放图片到12x8分辨率     image = image.resize((12, 8))         # 创建一个96位的数组来存储整个LED矩阵     led_matrix_full = [0] * 96         # 遍历每个像素,将其转换为1或0并存储到led_matrix_full中     for y in range(8):         for x in range(12):             pixel = image.getpixel((x, y))             if pixel == 0:  # 黑色像素表示LED点亮                 led_matrix_full[y * 12 + x] = 1         # 将96位数据分割成3个32位的uint32数组     led_matrix_32 = [0, 0, 0]         for i in range(3):         for bit in range(32):             led_matrix_32 |= (led_matrix_full[i * 32 + bit] 1000)         {                 if (digitalRead(LED_BUILTIN) == HIGH)                         led_switch.setState(true);                 else                         led_switch.setState(false);                 last_update_time = millis();         } } /** * @brief MQTT接收到数据后的回调函数 * * @param topic * @param payload * @param length */ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) {         char message[length];         memcpy(message, payload, length);         message[length] = '\0';         // 打印接收的数据         Serial.print("{dbg}New message on topic: ");         Serial.println(topic);         Serial.print("Data: ");         Serial.println((const char *)message);         if (strstr(message, "ON") != NULL) // 在字符串中查找另一个子字符串         {                 // uint8_t dutyCyclt = 0;                 // if (sscanf(message, "on#%d", &dutyCyclt) == 1) // 从一个字符串中读取数据,并按照指定的格式存储到变量中                 // {                 //         /* code */                 // }                 digitalWrite(LED_BUILTIN, HIGH);                 Serial.println("LED ON");         }         else if (strstr(message, "OFF") != NULL)         {                 /* code */                 digitalWrite(LED_BUILTIN, LOW);                 Serial.println("LED OFF");         }         else         {                 Serial.println("Unrecongnized meaasge");         }         memset(message, 0, length); } /** * @brief 连接MQTT服务器后的回调函数 * */ void onMqttConnected() {         Serial.println("Connected to the broker!");         mqtt.subscribe(topic_subscribe);         Serial.println("Subscribe to topic: ");         Serial.print(topic_subscribe);         // mqtt.publish(topic_subscribe, "Hello, MQTT!"); } /** * @brief 断开 MQTT broker后的回调函数 * */ void onMqttDisconneted() {         Serial.println("Disconnected from the broker!"); } /** * @brief MQTT连接状态改变后的回调函数 * * @param state */ void onMqttStateChanged(HAMqtt::ConnectionState state) {         Serial.print("MQTT state changed to: ");         Serial.println(static_cast(state)); } /** * @brief 连接WiFI和MQTT服务器 * */ void wifiAndMqttInit() {         // 检查WiFi模组         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");         }         // 连接WiFi         WiFi.begin(ssid, password); // Connect to WPA/WPA2 network:         Serial.print("Attempting to connect to WPA SSID: ");         Serial.println(ssid);         while (WiFi.status() != WL_CONNECTED)         {                 WiFi.begin(ssid, password);                 delay(1000);         }         printWifiStatus();         // 配置MQTT         Serial.println("Starting connect to MQTT server");         mqtt.onMessage(onMqttMessage);                         // 当设备接收到 MQTT 消息时调用         mqtt.onConnected(onMqttConnected);                 // 每次获取与 MQTT 代理的连接时调用         mqtt.onDisconnected(onMqttDisconneted);         // 每次与 MQTT 代理的连接丢失时调用         mqtt.onStateChanged(onMqttStateChanged); // 每次连接状态改变时调用         mqtt.setDataPrefix("homeassistant/sensor"); // 设置数据主题的前缀         // 连接MQTT服务器         if (!mqtt.begin(mqtt_server, mqtt_port, mqtt_user, mqtt_password))         {                 Serial.print("Failed, rc = ");                 Serial.print(mqtt.getState());                 Serial.println(", try again in 5 seconds");                 delay(5000);         } } /** * @brief 打印WiFi信息 * */ 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"); } ``` ### 2、说明 软件流程图: 关于Homeassistant的搭建,9月的技术直播中已经详细说明了,可以观看我的[录播回顾](https://www.bilibili.com/video/BV1884seCEAA)。 我的Homeassistant安装在Linux的docker容器中,EMQX没有使用docker,直接安装在Linux上。 **注意:在MQTT集成中,需要勾选“启用自动发现”,发现前缀配置为“homeassistant”,否则无法自动发现arduno开发板。** 调用`dawidchyrzynski/home-assistant-integration`库,实现HA联动功能。 ```cpp HASwitch led_switch("ledSwitch");                  // 开关实体 ``` 创建了1个HA开关实体,开发板连接到MQTT Broker后,HA自动发现,会在主页面上显示一个LED灯开关,开关可以控制开发板上的LED灯。 ```cpp if (digitalRead(LED_BUILTIN) == HIGH)     led_switch.setState(true);        // 反馈开关状态到MQTT Broker else     led_switch.setState(false);        // 反馈开关状态到MQTT Broker ``` 需要调用`led_switch.setState()`来将开关状态反馈到HA,如果HA获取不到开关状态,会默认开关状态是关。 ### 3、效果展示 关灯状态 开灯状态 ## 五、扩展任务 硬件:Arduino UNO R4 WiFi、USB-C to A线、SHT40温湿度传感器扩展板、Qwiic缆线 软件:VSCode ### 1、代码 ```cpp #include #include #include #include #include #include // macro definitions // make sure that we use the proper definition of NO_ERROR #ifdef NO_ERROR #undef NO_ERROR #endif #define NO_ERROR 0 // WiFi 设置 const char *ssid = "1708";                         // WiFi名称 const char *password = "tsl199725?"; // WiFi密码 // MQTT 设置 const char *mqtt_server = "192.168.31.46";                                          // MQTT服务器IP uint16_t mqtt_port = 1883;                                                                          // MQTT端口 const char *mqtt_user = "arduino_uno_r4";                                          // 用户名 const char *mqtt_password = "arduino_uno_r4";                                  // 密码 const char *mqtt_client_id = "arduino";                                                  // 客户id const char *topic_subscribe = "homeassistant/sensor/arduino"; // 订阅主题 WiFiClient client; HADevice device(mqtt_client_id); // 创建一个HA设备 HAMqtt mqtt(client, device); HASensor sht4x_temp_sensor("sht4x_temp"); // 温度传感器实体 HASensor sht4x_humi_sensor("sht4x_humi"); // 湿度传感器实体 HASwitch led_switch("ledSwitch");                  // 开关实体 SensirionI2cSht4x sensor;                                        // SHT40 static char errorMessage[64]; static int16_t error; uint32_t last_update_time; void wifiAndMqttInit(); void printWifiStatus(); void setup() {         Serial.begin(115200);         pinMode(LED_BUILTIN, OUTPUT);         Wire1.begin();         sensor.begin(Wire1, SHT40_I2C_ADDR_44);         sensor.softReset();         delay(10);         // 读取SHT40序列号         uint32_t serial_number;         error = sensor.serialNumber(serial_number);         if (NO_ERROR != error)         {                 Serial.print("Error trying to execute serialNumber(): ");                 errorToString(error, errorMessage, sizeof(errorMessage));                 Serial.println(errorMessage);                 return;         }         Serial.print("serialNumber: ");     Serial.println(serial_number);         wifiAndMqttInit(); // 初始化         device.setName("Arduino");                        // 设备名称         device.setSoftwareVersion("1.0.0"); // 设备软件版本         led_switch.setIcon("mdi:led-outline");         led_switch.setName("arduino LED");         // led_switch.onCommand(onSwitchCommand);         sht4x_temp_sensor.setIcon("mdi:coolant-temperature");         sht4x_temp_sensor.setName("温度传感器");         sht4x_humi_sensor.setIcon("mdi:water-percent");         sht4x_humi_sensor.setName("湿度传感器"); } void loop() {         mqtt.loop();         if ((millis() - last_update_time) > 1000)         {                 if (digitalRead(LED_BUILTIN) == HIGH)                         led_switch.setState(true);        // 反馈开关状态到MQTT Broker                 else                         led_switch.setState(false);        // 反馈开关状态到MQTT Broker                 // 读取SHT40温湿度数据                 float a_temperature;                 float a_humidity;                 error = sensor.measureHighPrecision(a_temperature, a_humidity);                 if (NO_ERROR != error)                 {                         Serial.print("Error trying to execute measureHighPrecision(): ");                         errorToString(error, errorMessage, sizeof(errorMessage));                         Serial.println(errorMessage);                         return;                 }                 Serial.print("aTemperature: ");                 Serial.println(a_temperature);                 Serial.print("aHumidity: ");                 Serial.println(a_humidity);                 // 发送数据到MQTT Broker                 String str = String(a_temperature, 2);                 sht4x_temp_sensor.setValue(str.c_str());                 sht4x_temp_sensor.setUnitOfMeasurement("℃");                 str = String(a_humidity, 2);                 sht4x_humi_sensor.setValue(str.c_str());                 sht4x_humi_sensor.setUnitOfMeasurement("%");                 last_update_time = millis();         } } /** * @brief MQTT接收到数据后的回调函数 * * @param topic * @param payload * @param length */ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length) {         char message[length];         memcpy(message, payload, length);         message[length] = '\0';         // 打印接收的数据         Serial.print("{dbg}New message on topic: ");         Serial.println(topic);         Serial.print("Data: ");         Serial.println((const char *)message);         if (strstr(message, "ON") != NULL) // strstr()在字符串中查找另一个子字符串         {                 // uint8_t dutyCyclt = 0;                 // if (sscanf(message, "on#%d", &dutyCyclt) == 1) // 从一个字符串中读取数据,并按照指定的格式存储到变量中                 // {                 //         /* code */                 // }                 digitalWrite(LED_BUILTIN, HIGH);                 Serial.println("LED ON");         }         else if (strstr(message, "OFF") != NULL)         {                 /* code */                 digitalWrite(LED_BUILTIN, LOW);                 Serial.println("LED OFF");         }         else         {                 Serial.println("Unrecongnized meaasge");         }         memset(message, 0, length); } /** * @brief 连接MQTT服务器后的回调函数 * */ void onMqttConnected() {         Serial.println("Connected to the broker!");         mqtt.subscribe(topic_subscribe);         Serial.println("Subscribe to topic: ");         Serial.print(topic_subscribe);         // mqtt.publish(topic_subscribe, "Hello, MQTT!"); } /** * @brief 断开 MQTT broker后的回调函数 * */ void onMqttDisconneted() {         Serial.println("Disconnected from the broker!"); } /** * @brief MQTT连接状态改变后的回调函数 * * @param state */ void onMqttStateChanged(HAMqtt::ConnectionState state) {         Serial.print("MQTT state changed to: ");         Serial.println(static_cast(state)); } /** * @brief 连接WiFI和MQTT服务器 * */ void wifiAndMqttInit() {         // 检查WiFi模组         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");         }         // 连接WiFi         WiFi.begin(ssid, password); // Connect to WPA/WPA2 network:         Serial.print("Attempting to connect to WPA SSID: ");         Serial.println(ssid);         while (WiFi.status() != WL_CONNECTED)         {                 WiFi.begin(ssid, password);                 delay(1000);         }         printWifiStatus();         // 配置MQTT         Serial.println("Starting connect to MQTT server");         mqtt.onMessage(onMqttMessage);                         // 当设备接收到 MQTT 消息时调用         mqtt.onConnected(onMqttConnected);                 // 每次获取与 MQTT 代理的连接时调用         mqtt.onDisconnected(onMqttDisconneted);         // 每次与 MQTT 代理的连接丢失时调用         mqtt.onStateChanged(onMqttStateChanged); // 每次连接状态改变时调用         mqtt.setDataPrefix("homeassistant/sensor"); // 设置数据主题的前缀         // 连接MQTT服务器         if (!mqtt.begin(mqtt_server, mqtt_port, mqtt_user, mqtt_password))         {                 Serial.print("Failed, rc = ");                 Serial.print(mqtt.getState());                 Serial.println(", try again in 5 seconds");                 delay(5000);         } } /** * @brief 打印WiFi信息 * */ 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"); } ``` ### 2、说明 软件流程图: 调用`sensirion/Sensirion I2C SHT4x`的库,来读取STH40的温湿度数据。 **注意:开发板有2个IIC端口,QWIC接口使用的是WIRE1,所以使用`Wire1.begin();`来使能IIC端口。** ```cpp HASensor sht4x_temp_sensor("sht4x_temp"); // 温度传感器实体 HASensor sht4x_humi_sensor("sht4x_humi"); // 湿度传感器实体 ``` 创建了2个HA传感器实体,分别显示温度和湿度。 ```cpp sensor.measureHighPrecision(a_temperature, a_humidity); ``` 使用`measureHighPrecision()`函数,来获取温度和湿度数据。 ```cpp sht4x_temp_sensor.setValue(); sht4x_humi_sensor.setValue(); ``` 通过`setValue()`函数,将温度和湿度数据发送到MQTT Broker。 ### 3、效果展示 HA中显示的温湿度数据: 家里的小米温湿度传感器 ## 六、源代码 ## 七、展示视频 [大学堂视频链接](https://training.eeworld.com.cn/video/41270)

  • 2024-09-12
  • 加入了学习《直播回放: TI 德州仪器基于 Arm 的 AM62 处理器简介》,观看 德州仪器基于 Arm 的 AM62 处理器简介

最近访客

现在还没有访客

< 1/0 >

统计信息

已有--人来访过

  • 芯积分:62
  • 好友:--
  • 主题:3
  • 回复:4

留言

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


现在还没有留言