御坂10032号

  • 2024-09-13
  • 加入了学习《Follow me第二季第2期视频演示》,观看 演示视频

  • 上传了资料: Follow me 第二季第2期任务所有代码

  • 2024-09-12
  • 发表了主题帖: 【Follow me第二季第2期】+ 作品提交整合贴

    本帖最后由 御坂10032号 于 2024-9-13 14:29 编辑 前言   Hello,大家好,我是Wang Chong 非常高兴也非常荣幸能够参加电子工程世界和得捷电子举办得Follow me 第二期得活动。   物料展示   本次拿到得开发板是Arduino uno R4 wifi 以及 LTR-329 光照传感器,SHT40湿温度传感器, 和QWIIC连接线。     设计思路   入门任务(任务1) :         任务一的主要点在于如何在原理图中确认IO的端口,从而使用GPIO控制闪烁   基础任务(任务2) :         任务2的主要点在于如何读懂Arduino官方文档中对LED矩阵和ADC,运算放大器的使用(和电路搭建)   进阶任务(任务3) :         任务三的主要点在于ESP32S3wifi库和MQTT库的使用,以及如何在HA中配置HA实体   拓展任务一:         拓展任务一的主要点在于如何使用QWIIC和正确的库来连接读取光照传感器, 由于在进阶任务中已经连接了MQTT和WIFI,可以代码复用   拓展任务二:         同拓展任务一,不过传感器驱动变成了SHT40     视频如下:       任务实现详情   入门任务一:搭建环境并开启第一步Blink / 串口打印Hello EEWorld! 帖子地址:【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】 https://bbs.eeworld.com.cn/thread-1293048-1-1.html   流程图如下         任务一的主要点在于如何在原理图中确认R4 IO的端口,从而使用GPIO控制闪烁       代码展示   void setup() { // sets the digital pin 13 as output // 设置GPIO13 为输出模式 pinMode(13, OUTPUT); } void loop() { // sets the digital pin 13 on // 输出高电平 digitalWrite(13, HIGH); // waits for a second // 延时一秒 delay(1000); // sets the digital pin 13 off // 输出低电平 digitalWrite(13, LOW); // 延时一秒 delay(1000); / }   功能展示 [localvideo]751dc261384d9dc8fc4dce0d1583b76e[/localvideo]   二、串口打印HelloWorld   根据官方文档和用户手册得知,D0 和D1 被用于USB的串口输入和输出, 因此只需要在程序中配置即可。     代码如下   void setup() { // sets the digital pin 13 as output // 设置GPIO13 为输出模式 pinMode(13, OUTPUT); // 设置波特率 Serial.begin(115200); Serial.println("Hello World!"); Serial.println("Hello DigiKey and EEWorld!"); } void loop() { // sets the digital pin 13 on // 输出高电平 digitalWrite(13, HIGH); // waits for a second // 延时一秒 delay(1000); // sets the digital pin 13 off // 输出低电平 digitalWrite(13, LOW); // 延时一秒 delay(1000); }   实验现象如下:       基础任务:驱动12x8点阵LED;用DAC生成正弦波;用OPAMP放大DAC信号;用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线 帖子地址:【Follow me第二季第2期】+ 基础任务【驱动LED矩阵+DAC正弦波+放大信号+ADC数据采集] https://bbs.eeworld.com.cn/thread-1293064-1-1.html   流程图如下:           实现思路:任务2的主要点在于如何读懂Arduino官方文档中对LED矩阵和ADC,运算放大器的使用(和电路搭建)   如下有三种点亮LED矩阵的方法   1- 使用帧的方式   // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; byte frame[8][12] = { { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; void setup() { Serial.begin(115200); matrix.begin(); matrix.renderBitmap(frame, 8, 12); } void loop() { } 实验现象:       2- 同样使用帧,不过是十六进制(官方推荐) // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; const uint32_t heart[] = { 0x3184a444, 0x44042081, 0x100a0040 }; void setup() { Serial.begin(115200); matrix.begin(); matrix.loadFrame(heart); } void loop() { }   实验现象       3- 使用官方代码滚屏   // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; void setup() { Serial.begin(115200); matrix.begin(); matrix.beginDraw(); matrix.stroke(0xFFFFFFFF); // add some static text // will only show "UNO" (not enough space on the display) const char text[] = "UNO r4"; matrix.textFont(Font_4x6); matrix.beginText(0, 1, 0xFFFFFF); matrix.println(text); matrix.endText(); matrix.endDraw(); delay(2000); } void loop() { // Make it scroll! matrix.beginDraw(); matrix.stroke(0xFFFFFFFF); matrix.textScrollSpeed(50); // add the text const char text[] = " Hello EEWorld and DigiKey! "; matrix.textFont(Font_5x7); matrix.beginText(0, 1, 0xFFFFFF); matrix.println(text); matrix.endText(SCROLL_LEFT); matrix.endDraw(); }   实验现象 [localvideo]93b103dc46de1767ee77e6b689e5776e[/localvideo]       4 - 使用工具进行动画效果的制作   #include "Arduino_LED_Matrix.h" //Include the LED_Matrix library #include "animation2.h" // Create an instance of the ArduinoLEDMatrix class ArduinoLEDMatrix matrix; void setup() { Serial.begin(115200); // you can also load frames at runtime, without stopping the refresh matrix.loadSequence(animation2); matrix.begin(); matrix.play(true); } void loop() { }   [localvideo]78cb19c3d53b66cccab2618ce4024a46[/localvideo]   二、DAC 输出正弦波,放大信号,并且使用ADC采集显示在串口绘图中   流程图如下:         实现思路:这个任务主要分为三个部分, 分别是使用DAC输出正弦波, 然后使用信号放大器放大DAC输出,然后使用ADC采集输入.   1- DAC 输出   /* SineWave Generates a pre-generated sawtooth-waveform. See the full documentation here: https://docs.arduino.cc/tutorials/uno-r4-wifi/dac */ #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); // Initialize serial communication at a baud rate of 115200 wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(1000); // Delay for one second before repeating }   电路如下:   示波器输出如下     2- 使用信号放大器放大DAC输出   接线图如下:       电路如下:     代码如下(此时我们已经完成了正弦波和放大信号,那么现在我们将使用ADC来读取放大后的信号)   #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 = 10; // in hertz, change accordingly void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating } 示波器输出如下所示(4V左右,滑动变阻器仍然可以调整输出频率):     参考官方文档, 我们可以使用如下API来配置ADC功能 1- analogReadResolution() 2- analogRead() 如果不需要修改分辨率的话, 可以不使用第一个API。我们在我们的代码上稍微修改下,使其可以把输出被串口绘图正确解析,同时可以获取A4的ADC输入     #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 = 10; // in hertz, change accordingly int reading = 0; void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 analogWriteResolution(14); wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); reading = analogRead(A4); Serial.print(reading); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating }     串口绘图工具输出如下(蓝色的为ADC读取的值,黄色的为当前的频率)         进阶任务:通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant) 帖子地址:【Follow me第二季第2期】+ 进阶任务 :通过Wi-Fi,利用MQTT协议接入HA https://bbs.eeworld.com.cn/thread-1293101-1-1.html   流程图如下:       任务三的主要点在于ESP32S3wifi库和MQTT库的使用,以及如何在HA中配置HA实体   本地部署的镜像展示(HA 和 MQTT)     进行MQTT测试     前置工作已经准备好了,那么现在我们就可以开始我们的任务了。 那么这个任务一共分为以下两点         1- 连接WIFI         2- 连接MQTT并且发送消息   对于WIFI的连接比较简单, 我们可以参考S3的wifi连接示例,如下所示     代码如下   #include <WiFiS3.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { } 实验现象如下(成功连接上WIFI 获取到了IP地址)       现在我们便开始处理我们的第二个任务, 使用MQTT连接到HA(也就是MQTT服务器,使其HA中集成的MQTT自动发现我们的配置服务)。   参考Arduino的官方文档,我们得知,可以使用ArduinoMqttClient的库来连接MQTT。 我们在上述的代码上稍作修改。   #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char topic[] = "/aht10/test"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { mqttClient.beginMessage(topic); mqttClient.print("Hello EEworld and Digikey!"); mqttClient.endMessage(); delay(500); }   将程序烧录到开发板上后,我们打开MQTTX, 查看我们MQTT的目标主题.     配置HA实体     根据上述配置文件得知,我们可以往两个主题内发送消息,从而控制HA的中实体的状态   1- home/bedroom/switch1 状态主题 2- home/bedroom/switch1/set 命令主题   当我们想要关闭灯的时候,只需要向命令主题中发送OFF即可, 如果想要开灯则发送ON. 但是尽管它已经可以正常的控制灯的开关。但是HA中实体的状态并不会发生变化。 如果想要实体的状态也发送变化的话,则需要向状态主题中也发送一个OFF   我们简单的修改一下代码,使其每秒切换灯的状态。     #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "home/bedroom/switch1/set"; const char state_topic[] = "home/bedroom/switch1"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); bool index = true; void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { if(index) { mqttClient.beginMessage(command_topic); mqttClient.print("ON"); mqttClient.endMessage(); mqttClient.beginMessage(state_topic); mqttClient.print("ON"); mqttClient.endMessage(); }else { mqttClient.beginMessage(command_topic); mqttClient.print("OFF"); mqttClient.endMessage(); mqttClient.beginMessage(state_topic); mqttClient.print("OFF"); mqttClient.endMessage(); } index = !index; delay(1000); }   [localvideo]41047ac6b4c9feb59584c18842684b1f[/localvideo]     拓展任务一:扩展任务一  使用LTR-329 环境光传感器,上传到HA并显示   帖子地址:【Follow me第二季第2期】+ 扩展任务一  使用LTR-329 环境光传感器,上传到HA并显示 https://bbs.eeworld.com.cn/thread-1293104-1-1.html   流程图如下:           拓展任务一的主要点在于如何使用QWIIC和正确的库来连接读取光照传感器, 由于在进阶任务中已经连接了MQTT和WIFI,可以代码复用      这个任务主要分为三个方面         1- 使用R4读取LTR-329传感器数据         2- 配置HA实体         3- 将数据上传到HA     步骤一代码如下:   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_LTR329_LTR303.h" Adafruit_LTR329 ltr = Adafruit_LTR329(); void setup() { Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); if ( ! ltr.begin(&Wire1) ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } 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); }   串口数据打印如下:     2- 配置HA实体       HA实体的配置主要是涉及到HA容器内的configuration.yml 根据官方文档得知我们可以配置一个如下的光照和举例的传感器     然后我们在HA的Web页面中重新加载一下配置信息     此时我们只需要向名称为 lux的主题内发送json数据即可   如下消息格式   {"psData":143,"brightness":117.2}   此时我们第二部分完成     步骤三: 上传数据到HA   由于我们上一个章节已经成功的连接到了WIFI 并且使用MQTT发送了数据,我们可以整合上一节的代码。 主要的逻辑就是初始化WIFI连接并且连接到MQTT服务器。 当获取到光照数据的时候结合Arduino的json库将数据序列化成JSON数据然后发送的MQTT服务器   代码如下: /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_LTR329_LTR303.h" #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> Adafruit_LTR329 ltr = Adafruit_LTR329(); char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "lux"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; void setup() { Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } if ( ! ltr.begin(&Wire1) ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { bool valid; uint16_t visible_plus_ir, infrared; if (ltr.newDataAvailable()) { valid = ltr.readBothChannels(visible_plus_ir, infrared); if (valid) { dataObj["brightness"] = visible_plus_ir; dataObj["psData"] = infrared; String jsonString = JSON.stringify(dataObj); mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); } } delay(500); }   此时便可以在HA的主界面中编辑Dashboard 在实体中搜索配置的实体的名称,如下图所示(成功的配置了光照传感器)     当点击传感器名称的时候还可以查看到历史数据         拓展任务一:扩展任务二  通过外部SHT40温湿度传感器,上传温湿度到HA   帖子地址:【Follow me第二季第2期】扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA. https://bbs.eeworld.com.cn/thread-1293108-1-1.html   流程图如下:           实现思路:同拓展任务一,只不过传感器驱动变成了SHT40   通过上一章的练习我们已经学会了如何使用R4来读取传感器的数据并且上传到HA由HA进行显示(手机端或者Web端)。 那么本章节也是同样的道理,只不过传感器换成了SHT40. 我们可以直接使用上一个章节的代码, 不过需要替换掉原本的驱动函数以及对应的消息主题     代码如下   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_SHT4x.h" #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> Adafruit_SHT4x sht4; char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "office/sensor1"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; void setup() { Serial.begin(115200); sht4.setPrecision(SHT4X_HIGH_PRECISION); switch (sht4.getPrecision()) { case SHT4X_HIGH_PRECISION: Serial.println(F("SHT40 set to High precision")); break; case SHT4X_MED_PRECISION: Serial.println(F("SHT40 set to Medium precision")); break; case SHT4X_LOW_PRECISION: Serial.println(F("SHT40 set to Low precision")); break; } //********************************************************************* //*************ADVANCED SETUP - SAFE TO IGNORE!************************ // The SHT40 has a built-in heater, which can be used for self-decontamination. // The heater can be used for periodic creep compensation in prolongued high humidity exposure. // For normal operation, leave the heater turned off. sht4.setHeater(SHT4X_NO_HEATER); switch (sht4.getHeater()) { case SHT4X_NO_HEATER: Serial.println(F("SHT40 Heater turned OFF")); break; case SHT4X_HIGH_HEATER_1S: Serial.println(F("SHT40 Heater: High heat for 1 second")); break; case SHT4X_HIGH_HEATER_100MS: Serial.println(F("SHT40 Heater: High heat for 0.1 second")); break; case SHT4X_MED_HEATER_1S: Serial.println(F("SHT40 Heater: Medium heat for 1 second")); break; case SHT4X_MED_HEATER_100MS: Serial.println(F("SHT40 Heater: Medium heat for 0.1 second")); break; case SHT4X_LOW_HEATER_1S: Serial.println(F("SHT40 Heater: Low heat for 1 second")); break; case SHT4X_LOW_HEATER_100MS: Serial.println(F("SHT40 Heater: Low heat for 0.1 second")); break; } //********************************************************************* //*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!******* if (! sht4.begin(&Wire1)) { Serial.println(F("SHT40 sensor not found!")); while (1) ; } else { Serial.print(F("SHT40 detected!\t")); Serial.print(F("Serial number:\t")); Serial.println(sht4.readSerial(), HEX); } Serial.println(F("----------------------------------")); 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { sensors_event_t humidity, temp; sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data float t = temp.temperature; Serial.println("Temp *C = " + String(t)); float h = humidity.relative_humidity; Serial.println("Hum. % = " + String(h)); dataObj["temperature"] = t; dataObj["humidity"] = h; String jsonString = JSON.stringify(dataObj); mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); delay(500); }   实验现象如下:       项目完整源码如下:   直链下载 官方下载     活动总结体会   非常感谢电子工程世界和得捷电子提供了这次宝贵的活动机会,使我受益匪浅。在活动中,我学到了很多新知识,例如如何使用 ESP32 S3 和 ESP8266 连接 Wi-Fi,以及相关 Arduino API 和库的使用。这次活动让我对 Arduino 的操作更加得心应手。   由于之前较少接触 Arduino IDE,本次活动中所有的代码都是参考并学习了 Arduino 官方文档后实现的,这不仅提升了我的技术水平,还增强了我的英文阅读能力。此外,我还学会了如何使用运算放大器来生成模拟信号等相关技巧。   再次感谢主办方的支持,这次活动给了我宝贵的学习机会!

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

  • 加入了学习《【Follow me第二季第1期】+ 任务汇总提交-章鱼哥 》,观看 【Follow me第二季第1期】+ 任务汇总提交-章鱼哥

  • 回复了主题帖: 【Follow me第二季第2期】+ 基础任务【驱动LED矩阵+DAC正弦波+放大信号+ADC数据采集】

    genvex 发表于 2024-9-12 14:59 服气,没有点动手能力还完成不了这个任务 哈哈, 是稍微有一点麻烦

  • 回复了主题帖: 免费尝鲜:热气体式加速度传感器来啦,拍摄冲击对比实验有好礼

    秦天qintian0303 发表于 2024-9-12 15:57 传感器没有摔坏,板子摔坏了,上哪里看数据啊 SD卡 或者flash里。 下面搞个缓冲的丢上去摔不坏

  • 回复了主题帖: [工业级智能控制MCU 匠芯创D133CBS] 8 - Audio Codec 测试

    勘误: 不是正好有一个麦克风,而是正好有一个扬声器

  • 2024-09-11
  • 发表了主题帖: [工业级智能控制MCU 匠芯创D133CBS] 8 - Audio Codec 测试

    本帖最后由 御坂10032号 于 2024-9-12 02:21 编辑 前言   前两天买了一个板载的Wifi和蓝牙芯片,也就是开发板原理图上指定的, 自己焊接的一团糟糕,然后本来这次打算出WIFI和蓝牙的测评的。根据官方文档进行操作的时候发现栈内存溢出太多了。 自己目前没有找到解决的办法。 等到我找到解决办法的时候我来继续出WIFI和蓝牙的测评。 那么本期我们将测评的是板载的Audio CODEC 模块。   正文   Audio Codec 模块内置 Sigma-Delta ADC、 DMIC 接口和 PWM 音频输出模块,经过数字信号的处理,实现音频信号的录入以及播放功能。   我们可以根据官方文档推荐的步骤来手动的配置Aduio codec的功能, 但是如果你使用的是出厂的Helloword(Lunch 11) 的话, 默认的menuconfig中已经配置好了。Audio codec的功能。 由于我们要使用它来播放音乐。 那么系统的Flash空间肯定是不够我们使用的, 因此我们还需要初始化文件系统。 但是更巧的是,默认的menuconfig中也已经配置好了。 所以我们要做的其实非常简单     1- 把音频文件存到内存卡中     我从网上下载了一个我心永恒.wav , 然后把它放到了u盘里,重命名一个方便打出来的名称    2- 在系统启动的时候检查内存卡是否正常挂载     可以在上图看到内存卡成功挂载   3- 找到文件的路径     使用LS 命令找到文件位置   4- 开始播放     执行aplay [文件路径] 来播放音乐。   实验现象:   [localvideo]96cd639c8713a8d8036b0a70790ac8db[/localvideo]     历史测评:   [工业级智能控制MCU 匠芯创D133CBS] 1 - 开箱及其环境搭建 https://bbs.eeworld.com.cn/thread-1290588-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 2 - 创建项目及其注意事项 https://bbs.eeworld.com.cn/thread-1290861-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 3 - GPIO-IO中断 https://bbs.eeworld.com.cn/thread-1290902-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 4-  BUG 反馈 (SDK lunch11 包更新错误) https://bbs.eeworld.com.cn/thread-1290904-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 5- 使用RTT-软件包结合IIC读取BH1750 https://bbs.eeworld.com.cn/thread-1291002-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 6 - PWM 输出 https://bbs.eeworld.com.cn/thread-1291463-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 7 - RTC 时钟测试 https://bbs.eeworld.com.cn/thread-1292697-1-1.html     结语   下期的测评,我这两天研究一下怎么使用匠芯创SDK实现 LVGL的音乐播放器来加载SD卡中保存的音乐数据,使其可以在屏幕上显示和播放音乐。   

  • 2024-09-08
  • 发表了主题帖: 【Follow me第二季第2期】扩展任务二:通过外部SHT40温湿度传感器,上传温湿度到HA.

    本帖最后由 御坂10032号 于 2024-9-8 23:56 编辑 前言           通过上一章的练习我们已经学会了如何使用R4来读取传感器的数据并且上传到HA由HA进行显示(手机端或者Web端)。 那么本章节也是同样的道理,只不过传感器换成了SHT40. 我们可以直接使用上一个章节的代码, 不过需要替换掉原本的驱动函数以及对应的消息主题       正文     1- 驱动SHT40           同样得益于强大的开源生态,我们可以使用别人已经写好的SHT40 库来读取湿温度传感器的数据           在Arduino 库管理器中搜索SHT40 并且安装                                 打开示例程序,删除无关的传感器初始化代码, 如下所示            /*************************************************************************** Example for the SGP40+SHT40 board written by Thiago Barros for BlueDot UG (haftungsbeschränkt) BSD License Version 1.0.0 (2023-04-22) This sketch was written for the sensors SGP40 and SHT40 from Sensirion and is based on the Adafruit libraries for these sensors. The SGP40 is a device for measuring volatile organic compounds (VOC) and for evaluating indoor air quality. The SHT40 is a digital temperature and relative humidity sensor. The VOC Algorithm from Sensirion integrates the output values from the SHT40 to improve the calculation of the VOC index. For more technical information on the SGP40 and on the SHT40, go to ------> http://www.bluedot.space ***************************************************************************/ #include "Adafruit_SHT4x.h" Adafruit_SHT4x sht4; void setup() { Serial.begin(115200); Serial.println(); Serial.println(); Serial.println(F("##################################")); Serial.println(F("SGP40 test with SHT40 compensation")); //********************************************************************* //*************ADVANCED SETUP - SAFE TO IGNORE!************************ //Here we can configure the SHT40 Temperature and Humidity Sensor //First we set the measurement precision //There are three precision levels: High, Medium and Low //The precision levels direclty affect the measurement duration, noise level and energy consumption //On doubt, just leave it on default (High precision) sht4.setPrecision(SHT4X_HIGH_PRECISION); switch (sht4.getPrecision()) { case SHT4X_HIGH_PRECISION: Serial.println(F("SHT40 set to High precision")); break; case SHT4X_MED_PRECISION: Serial.println(F("SHT40 set to Medium precision")); break; case SHT4X_LOW_PRECISION: Serial.println(F("SHT40 set to Low precision")); break; } //********************************************************************* //*************ADVANCED SETUP - SAFE TO IGNORE!************************ // The SHT40 has a built-in heater, which can be used for self-decontamination. // The heater can be used for periodic creep compensation in prolongued high humidity exposure. // For normal operation, leave the heater turned off. sht4.setHeater(SHT4X_NO_HEATER); switch (sht4.getHeater()) { case SHT4X_NO_HEATER: Serial.println(F("SHT40 Heater turned OFF")); break; case SHT4X_HIGH_HEATER_1S: Serial.println(F("SHT40 Heater: High heat for 1 second")); break; case SHT4X_HIGH_HEATER_100MS: Serial.println(F("SHT40 Heater: High heat for 0.1 second")); break; case SHT4X_MED_HEATER_1S: Serial.println(F("SHT40 Heater: Medium heat for 1 second")); break; case SHT4X_MED_HEATER_100MS: Serial.println(F("SHT40 Heater: Medium heat for 0.1 second")); break; case SHT4X_LOW_HEATER_1S: Serial.println(F("SHT40 Heater: Low heat for 1 second")); break; case SHT4X_LOW_HEATER_100MS: Serial.println(F("SHT40 Heater: Low heat for 0.1 second")); break; } //********************************************************************* //*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!******* if (! sht4.begin(&Wire1)) { Serial.println(F("SHT40 sensor not found!")); while (1) ; } else { Serial.print(F("SHT40 detected!\t")); Serial.print(F("Serial number:\t")); Serial.println(sht4.readSerial(), HEX); } Serial.println(F("----------------------------------")); } //********************************************************************* //*************NOW LET'S START MEASURING******************************* void loop() { sensors_event_t humidity, temp; sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data float t = temp.temperature; Serial.println("Temp *C = " + String(t)); float h = humidity.relative_humidity; Serial.println("Hum. % = " + String(h)); delay(1000); }     此时将程序烧录到开发板上之后,便可以通过串口助手查看室内的温度和湿度。       2- 配置HA实体   同样是配置configuration.yml , 根据官方文档得知我们可以加入以下的参数   sensor: - name: "Temperature" unique_id: temperature state_topic: "office/sensor1" suggested_display_precision: 1 unit_of_measurement: "°C" value_template: "{{ value_json.temperature }}" - name: "Humidity" unique_id: humidity state_topic: "office/sensor1" unit_of_measurement: "%" value_template: "{{ value_json.humidity }}"     注意: 修改完configuration.yml 后需要在HA的web界面重载配置。到此HA的配置完成   3- 发送数据到MQTT服务器(整合HA)   我们可以直接使用上一个章节的代码,只是替换驱动函数即可。 修改后的代码如下所示   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_SHT4x.h" #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> Adafruit_SHT4x sht4; char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "office/sensor1"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; void setup() { Serial.begin(115200); sht4.setPrecision(SHT4X_HIGH_PRECISION); switch (sht4.getPrecision()) { case SHT4X_HIGH_PRECISION: Serial.println(F("SHT40 set to High precision")); break; case SHT4X_MED_PRECISION: Serial.println(F("SHT40 set to Medium precision")); break; case SHT4X_LOW_PRECISION: Serial.println(F("SHT40 set to Low precision")); break; } //********************************************************************* //*************ADVANCED SETUP - SAFE TO IGNORE!************************ // The SHT40 has a built-in heater, which can be used for self-decontamination. // The heater can be used for periodic creep compensation in prolongued high humidity exposure. // For normal operation, leave the heater turned off. sht4.setHeater(SHT4X_NO_HEATER); switch (sht4.getHeater()) { case SHT4X_NO_HEATER: Serial.println(F("SHT40 Heater turned OFF")); break; case SHT4X_HIGH_HEATER_1S: Serial.println(F("SHT40 Heater: High heat for 1 second")); break; case SHT4X_HIGH_HEATER_100MS: Serial.println(F("SHT40 Heater: High heat for 0.1 second")); break; case SHT4X_MED_HEATER_1S: Serial.println(F("SHT40 Heater: Medium heat for 1 second")); break; case SHT4X_MED_HEATER_100MS: Serial.println(F("SHT40 Heater: Medium heat for 0.1 second")); break; case SHT4X_LOW_HEATER_1S: Serial.println(F("SHT40 Heater: Low heat for 1 second")); break; case SHT4X_LOW_HEATER_100MS: Serial.println(F("SHT40 Heater: Low heat for 0.1 second")); break; } //********************************************************************* //*************ADVANCED SETUP IS OVER - LET'S CHECK THE CHIP ID!******* if (! sht4.begin(&Wire1)) { Serial.println(F("SHT40 sensor not found!")); while (1) ; } else { Serial.print(F("SHT40 detected!\t")); Serial.print(F("Serial number:\t")); Serial.println(sht4.readSerial(), HEX); } Serial.println(F("----------------------------------")); 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { sensors_event_t humidity, temp; sht4.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data float t = temp.temperature; Serial.println("Temp *C = " + String(t)); float h = humidity.relative_humidity; Serial.println("Hum. % = " + String(h)); dataObj["temperature"] = t; dataObj["humidity"] = h; String jsonString = JSON.stringify(dataObj); mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); delay(500); }   效果现象:HA中可以查看当前室内的湿度和温度,已经历史变化曲线       代码如下:  

  • 发表了主题帖: 【Follow me第二季第2期】+ 扩展任务一 使用LTR-329 环境光传感器,上传到HA并显示

    本帖最后由 御坂10032号 于 2024-9-8 21:45 编辑 前言       在上一个章节中我们学习了如何使用R4连接WIFI并且使用MQTT client 成功的和HA通讯以及交互,那么在本章节我们将会学习如何使用R4 来通过IIC采集LTR-329的数据并且上传到HA, 在HA的面板中显示。   正文           这个任务主要分为三个方面         1- 使用R4读取LTR-329传感器数据         2- 配置HA实体         3- 将数据上传到HA       1- 使用R4读取LTR-329传感器数据                  得益于强大的Arduino生态,我们可以直接在Arduino 库管理器中查找到我们需要的库(在库管理器中搜索LTR329并且安装)       打开Example示例     代码如下   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_LTR329_LTR303.h" Adafruit_LTR329 ltr = Adafruit_LTR329(); void setup() { Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); if ( ! ltr.begin() ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } 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); }   由于我们使用的是Qwiic的连接方式,所以根据官方文档得知, 如果我们使用Qwiic的方式连接的话,我们并不能直接使用原理图上的IIC0, 我们需要使用IIC1     因此, 我们需要做一点小小的修改就像官方文档中提到的示例一样       修改后的代码如下所示, 主要变更在LTR begin的时候传递了IIC总线1作为数据总线   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_LTR329_LTR303.h" Adafruit_LTR329 ltr = Adafruit_LTR329(); void setup() { Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); if ( ! ltr.begin(&Wire1) ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } 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); }   将程序烧录到R4中之后,我们打开串口助手便可以看到如下输出     那么现在第一步已经完成了。 接下来我们来配置Ha的实体   2- 配置HA实体           HA实体的配置主要是涉及到HA容器内的configuration.yml 根据官方文档得知我们可以配置一个如下的光照和举例的传感器     然后我们在HA的Web页面中重新加载一下配置信息       此时我们只需要向名称为 lux的主题内发送json数据即可   如下消息格式 {"psData":143,"brightness":117.2} 此时我们第二部分完成   3 - 将数据上传到HA           由于我们上一个章节已经成功的连接到了WIFI 并且使用MQTT发送了数据,我们可以整合上一节的代码。 主要的逻辑就是初始化WIFI连接并且连接到MQTT服务器。 当获取到光照数据的时候结合Arduino的json库将数据序列化成JSON数据然后发送的MQTT服务器           代码如下   /*************************************************** This is an example for the LTR329 light sensor that reads both channels and demonstrates how to set gain and check data validity Designed specifically to work with the LTR-329 light sensor from Adafruit ----> https://www.adafruit.com/product/5591 These sensors use I2C to communicate, 2 pins are required to interface ****************************************************/ #include "Adafruit_LTR329_LTR303.h" #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> Adafruit_LTR329 ltr = Adafruit_LTR329(); char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "lux"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; void setup() { Serial.begin(115200); Serial.println("Adafruit LTR-329 advanced test"); 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue while (true); } if ( ! ltr.begin(&Wire1) ) { Serial.println("Couldn't find LTR sensor!"); while (1) delay(10); } Serial.println("Found LTR sensor!"); ltr.setGain(LTR3XX_GAIN_2); Serial.print("Gain : "); switch (ltr.getGain()) { case LTR3XX_GAIN_1: Serial.println(1); break; case LTR3XX_GAIN_2: Serial.println(2); break; case LTR3XX_GAIN_4: Serial.println(4); break; case LTR3XX_GAIN_8: Serial.println(8); break; case LTR3XX_GAIN_48: Serial.println(48); break; case LTR3XX_GAIN_96: Serial.println(96); break; } ltr.setIntegrationTime(LTR3XX_INTEGTIME_100); Serial.print("Integration Time (ms): "); switch (ltr.getIntegrationTime()) { case LTR3XX_INTEGTIME_50: Serial.println(50); break; case LTR3XX_INTEGTIME_100: Serial.println(100); break; case LTR3XX_INTEGTIME_150: Serial.println(150); break; case LTR3XX_INTEGTIME_200: Serial.println(200); break; case LTR3XX_INTEGTIME_250: Serial.println(250); break; case LTR3XX_INTEGTIME_300: Serial.println(300); break; case LTR3XX_INTEGTIME_350: Serial.println(350); break; case LTR3XX_INTEGTIME_400: Serial.println(400); break; } ltr.setMeasurementRate(LTR3XX_MEASRATE_200); Serial.print("Measurement Rate (ms): "); switch (ltr.getMeasurementRate()) { case LTR3XX_MEASRATE_50: Serial.println(50); break; case LTR3XX_MEASRATE_100: Serial.println(100); break; case LTR3XX_MEASRATE_200: Serial.println(200); break; case LTR3XX_MEASRATE_500: Serial.println(500); break; case LTR3XX_MEASRATE_1000: Serial.println(1000); break; case LTR3XX_MEASRATE_2000: Serial.println(2000); break; } } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { bool valid; uint16_t visible_plus_ir, infrared; if (ltr.newDataAvailable()) { valid = ltr.readBothChannels(visible_plus_ir, infrared); if (valid) { dataObj["brightness"] = visible_plus_ir; dataObj["psData"] = infrared; String jsonString = JSON.stringify(dataObj); mqttClient.beginMessage(command_topic); mqttClient.print(jsonString); mqttClient.endMessage(); } } delay(500); }   此时便可以在HA的主界面中编辑Dashboard 在实体中搜索配置的实体的名称,如下图所示(成功的配置了光照传感器)     当点击传感器名称的时候还可以查看到历史数据       代码如下所示         

  • 发表了主题帖: 【Follow me第二季第2期】+ 进阶任务 :通过Wi-Fi,利用MQTT协议接入HA

    本帖最后由 御坂10032号 于 2024-9-8 18:39 编辑 前言           在前两章我们已经学习到了如何基础的使用R4, 那么本章节我们将学习一下如何使用R4的 Wifi功能将R4接入HA   正文          在我们开始之前我希望你已经在部署好了以下服务(无论本地或者云端)。        1-  HomeAssistant        2-  MQTT服务   我的这两个服务是跑的本地的一块99元的香橙派上的,如下是容器示例     通过8123端口我们可以正确的访问到HomeAssistant的管理端     同时进行MQTT连接测试   前置工作已经准备好了,那么现在我们就可以开始我们的任务了。 那么这个任务一共分为以下两点         1- 连接WIFI         2- 连接MQTT并且发送消息   对于WIFI的连接比较简单, 我们可以参考S3的wifi连接示例,如下所示       我们仅仅需要的是代码中的 ssid 和 pass (我这里尝试连接5G的信号失败, 正常的2.4G没问题)   代码如下所示 #include <WiFiS3.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { }   我们将代码烧录到开发板之后呢,打开串口助手便可以看到正确的控制台输出        现在我们便开始处理我们的第二个任务, 使用MQTT连接到HA(也就是MQTT服务器,使其HA中集成的MQTT自动发现我们的配置服务)。   参考Arduino的官方文档,我们得知,可以使用ArduinoMqttClient的库来连接MQTT。 我们在上述的代码上稍作修改。   #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char topic[] = "/aht10/test"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { mqttClient.beginMessage(topic); mqttClient.print("Hello EEworld and Digikey!"); mqttClient.endMessage(); delay(500); }   将程序烧录到开发板上后,我们打开MQTTX, 查看我们MQTT的目标主题.       此时我们已经可以正确的接收来自Arduino发送的消息。 接下来我们要做的就是解析数据,使其HA可以根据MQTT的格式自动识别为HA中的实体。根据HA的官方文档我们得知,可以分为自动发现或者配置configuration.yml. 我这里选择是后者。同时配置了一个灯(Switch)     根据上述配置文件得知,我们可以往两个主题内发送消息,从而控制HA的中实体的状态   1- home/bedroom/switch1 状态主题 2- home/bedroom/switch1/set 命令主题   当我们想要关闭灯的时候,只需要向命令主题中发送OFF即可, 如果想要开灯则发送ON. 但是尽管它已经可以正常的控制灯的开关。但是HA中实体的状态并不会发生变化。 如果想要实体的状态也发送变化的话,则需要向状态主题中也发送一个OFF   我们简单的修改一下代码,使其每秒切换灯的状态。   #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> char ssid[] = "ImmortalWrt"; char pass[] = "mazha1997"; int status = WL_IDLE_STATUS; const char broker[] = "192.168.1.113"; int port = 1883; const char command_topic[] = "home/bedroom/switch1/set"; const char state_topic[] = "home/bedroom/switch1"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); bool index = true; void setup() { Serial.begin(9600); while (!Serial) { } if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); // don't continue 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 WPA SSID: "); Serial.println(ssid); // Connect to WPA/WPA2 network: status = WiFi.begin(ssid, pass); // wait 10 seconds for connection: delay(10000); } Serial.print("You're connected to the network"); printCurrentNet(); printWifiData(); if (!mqttClient.connect(broker, port)) { Serial.print("MQTT connection failed! Error code = "); Serial.println(mqttClient.connectError()); while (1); } Serial.println("You are connected to MQTT"); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 0; i < 6; i++) { if (i > 0) { Serial.print(":"); } if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); } Serial.println(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void loop() { if(index) { mqttClient.beginMessage(command_topic); mqttClient.print("ON"); mqttClient.endMessage(); mqttClient.beginMessage(state_topic); mqttClient.print("ON"); mqttClient.endMessage(); }else { mqttClient.beginMessage(command_topic); mqttClient.print("OFF"); mqttClient.endMessage(); mqttClient.beginMessage(state_topic); mqttClient.print("OFF"); mqttClient.endMessage(); } index = !index; delay(1000); } 实验现象如下:   [localvideo]616294a532fb594579ab00d84391b85e[/localvideo]   代码如下:

  • 2024-09-07
  • 发表了主题帖: 【Follow me第二季第2期】+ 基础任务【驱动LED矩阵+DAC正弦波+放大信号+ADC数据采集】

    本帖最后由 御坂10032号 于 2024-9-7 21:19 编辑 前言           在上一个章节中我们学习到了如何使用R4来Blink 和 使用串口输出数据, 那么本章节我们来研究以下如何驱动R4的LED矩阵和使用DAC生成正弦波,然后用OPAMP放大DAC信号。最后用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线。     一、驱动LED矩阵     R4上有一个LED矩阵,根据官方的文档得知, 如果我们想使用LED矩阵主要为以下几步。   1- 引入头文件 #include "Arduino_LED_Matrix.h" 2-定义matrix对象 ArduinoLEDMatrix matrix; 3-在setup中调用matrix的start函数 matrix.begin(); 代码如下所示 #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; void setup() { Serial.begin(115200); matrix.begin(); }   那么上述的起始工作我们已经完成了,但是具体怎么来驱动矩阵呢? 由于这个LED矩阵是一个8*12的, 所以每一个LED灯都占用了一个bit用来存储led的状态。 如下代码所示   byte frame[8][12] = {   { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 },   { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 },   { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 },   { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 },   { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 },   { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 },   { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 },   { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } };   上面的矩阵是一个爱心的形状, 如果想让这个形状更加清晰的话, 可以使用ctrl + f 然后搜索1, 此时你会更清晰的看到这个爱心。 如下图所示       紧接着我们便可以通过 matrix.renderBitmap(frame, 8, 12); 加载这个矩阵数组。 如下代码所示   // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; byte frame[8][12] = { { 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0 }, { 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0 }, { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; void setup() { Serial.begin(115200); matrix.begin(); matrix.renderBitmap(frame, 8, 12); } void loop() { }   实验现象如下:       我们也可以换一种方式来表示LED的状态, 比如说使用16进制   unsigned long frame[] = { 0x3184a444, 0x42081100, 0xa0040000 };   为什么它可以表示LED的状态呢? 首先我们需要把他转换成2进制便得到如下数据   110001100001001010010001000100 1000010000010000001000100000000 10100000000001000000000000000000   然后32位对齐(高位补0保持原本数据不变)   00110001100001001010010001000100 01000010000010000001000100000000 10100000000001000000000000000000   之后呢, 再将其分成8*12的原始矩阵,便得到了如下数据   001100011000 010010100100 010001000100 001000001000 000100010000 000010100000 000001000000 000000000000   它还是上面我们定义的爱心矩阵。之后我们便可以通过matrix.loadFrame() 函数来加载这个定义的矩阵, 代码如下所示   // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; const uint32_t heart[] = { 0x3184a444, 0x44042081, 0x100a0040 }; void setup() { Serial.begin(115200); matrix.begin(); matrix.loadFrame(heart); } void loop() { }   实验现象如下所示           那么基础的原理理解的话,我们便可以看一下今天写的第一个代码, 通过数据帧的方式打印Hello EEworld and Digikey   1 - 首先定义一个头文件eeworld.h 用来存储每一个字母的状态   const uint32_t animation[][4] = { { 0x8808, 0x880f80, 0x88088088, }, { 0xf808, 0x800f80, 0x800800f8, }, { 0x8008, 0x800800, 0x800800f8, }, { 0x8008, 0x800800, 0x800800f8, }, { 0x6009, 0x900900, 0x90090060, }, { 0xf808, 0x800f80, 0x800800f8, }, { 0xf808, 0x800f80, 0x800800f8, }, { 0xf808, 0x800f80, 0x800800f8, }, { 0x40, 0x12221540, 0x88000000, }, { 0x6009, 0x900900, 0x90060000, }, { 0xf009, 0x900f00, 0xc00a0090, }, { 0x8008, 0x800800, 0x800f8000, }, { 0xc00a, 0x900900, 0xa00c0000, }, { 0x00, 0x00, 0x00, }, { 0x400a, 0xa00e00, 0xa00a0000, }, { 0xe00a, 0xa00a00, 0xa00a0000, }, { 0xc00a, 0x900900, 0xa00c0000, }, { 0x00, 0x00, 0x00, }, { 0xc00a, 0x900900, 0xa00c0000, }, { 0xe004, 0x400400, 0x400e0000, }, { 0x1e012, 0x1201601, 0x101f0000, }, { 0xe004, 0x400400, 0x400e0000, }, { 0x900a, 0xc00a00, 0x90000000, }, { 0xf008, 0x800f00, 0x800800f0, }, { 0x1100a, 0x400400, 0x40040000, }, { 0x00, 0x00, 0x00, }, { 0x00, 0x00, 0x00, } };   2- 在主程序中引入头文件   #include "eeworld.h"   3- 完整代码如下所示   #include "eeworld.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; const int frameCount = sizeof(animation) / sizeof(animation[0]); // 获取总帧数 int currentFrame = 0; // 当前帧计数器 void setup() { Serial.begin(115200); matrix.begin(); } void loop() { matrix.loadFrame(animation[currentFrame]); // 加载并显示当前帧 delay(500); // 延迟 500 毫秒 // 更新帧计数器以显示下一个帧 currentFrame++; if (currentFrame >= frameCount) { currentFrame = 0; // 如果达到最后一帧,则返回到第一帧 } }   实验现象如下所示: [localvideo]b35cae86709ef0398f866dd8cf48b55c[/localvideo]   附件代码:     当然还有第二种方式, 比如说使用Arduino 官方提供的LED滚屏的效果, 代码如下所示   // To use ArduinoGraphics APIs, please include BEFORE Arduino_LED_Matrix #include "ArduinoGraphics.h" #include "Arduino_LED_Matrix.h" ArduinoLEDMatrix matrix; void setup() { Serial.begin(115200); matrix.begin(); matrix.beginDraw(); matrix.stroke(0xFFFFFFFF); // add some static text // will only show "UNO" (not enough space on the display) const char text[] = "UNO r4"; matrix.textFont(Font_4x6); matrix.beginText(0, 1, 0xFFFFFF); matrix.println(text); matrix.endText(); matrix.endDraw(); delay(2000); } void loop() { // Make it scroll! matrix.beginDraw(); matrix.stroke(0xFFFFFFFF); matrix.textScrollSpeed(50); // add the text const char text[] = " Hello EEWorld and DigiKey! "; matrix.textFont(Font_5x7); matrix.beginText(0, 1, 0xFFFFFF); matrix.println(text); matrix.endText(SCROLL_LEFT); matrix.endDraw(); }   实验现象如下:   [localvideo]3e4a6cbaf2fc3a87c9319c600ed773ad[/localvideo]   下面我再简单的介绍一下动画的矩阵是怎么实现的。我们可以借助官方的LED tool 来快速自定义我们自己的动画(删除掉持续时间的话就是加载单独帧)         我们可以使用笔刷直观的绘制我们想要的动画, 比如说我这里绘制了一个正方形(起始我们可以使用这个工具直接把绘制的动画烧录到Arduino中,但是谷歌好像不支持这个工具,并且我使用了火狐也没有成功)         绘制完成后点击右上角, 把代码下载下来。         把这个文件放到你Arduino的工程目录下, 并且引入到项目里。 代码如下   #include "Arduino_LED_Matrix.h" //Include the LED_Matrix library #include "animation2.h" // Create an instance of the ArduinoLEDMatrix class ArduinoLEDMatrix matrix; void setup() { Serial.begin(115200); // you can also load frames at runtime, without stopping the refresh matrix.loadSequence(animation2); matrix.begin(); matrix.play(true); } void loop() { } 实验现象如下 [localvideo]0919cf2f7a98957b984fd5dd4fd54156[/localvideo]     二、DAC 输出正弦波,放大信号,并且使用ADC采集显示在串口绘图中   这个任务主要分为三个部分, 分别是使用DAC输出正弦波, 然后使用信号放大器放大DAC输出,然后使用ADC采集输入.   1- DAC 输出   根据官方文档,得知 实现DAC比较简单, 我们只需要使用下面的代码并且按照图示搭建好电路     /* SineWave Generates a pre-generated sawtooth-waveform. See the full documentation here: https://docs.arduino.cc/tutorials/uno-r4-wifi/dac */ #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); // Initialize serial communication at a baud rate of 115200 wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(1000); // Delay for one second before repeating }   那么程序就会读取滑动变阻器的输出端(ADC)动态调整A0 (蜂鸣器输出的频率)       串口助手输出如下所示       由于比较拮据手头没有示波器,便使用了STC的试验箱,烧录了老梁示波器的代码。用来测量A0的输出         虚拟示波器输出如下所示         之后我们使用 opamp 对输出的数据进行放大。 参考官方文档, 我们可以使用下面的电路进行两倍的输出放大。         简单的搭建一下电路, 注意R0,也就是接地的电阻需要再10K欧姆, 另一个电阻则为30K欧姆       代码如下(此时我们已经完成了正弦波和放大信号,那么现在我们将使用ADC来读取放大后的信号)   #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 = 10; // in hertz, change accordingly void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating }   示波器输出如下所示(4V左右,滑动变阻器仍然可以调整输出频率):       参考官方文档, 我们可以使用如下API来配置ADC功能 1- analogReadResolution() 2- analogRead() 如果不需要修改分辨率的话, 可以不使用第一个API。我们在我们的代码上稍微修改下,使其可以把输出被串口绘图正确解析,同时可以获取A4的ADC输入 #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 = 10; // in hertz, change accordingly int reading = 0; void setup() { OPAMP.begin(OPAMP_SPEED_HIGHSPEED); Serial.begin(115200); // Initialize serial communication at a baud rate of 115200 analogWriteResolution(14); wave.sine(freq); // Generate a sine wave with the initial frequency } void loop() { // Read an analog value from pin A5 and map it to a frequency range freq = map(analogRead(A5), 0, 1024, 0, 10000); // Print the updated frequency to the serial monitor Serial.println("Frequency is now " + String(freq) + " hz"); reading = analogRead(A4); Serial.print(reading); wave.freq(freq); // Set the frequency of the waveform generator to the updated value delay(50); // Delay for one second before repeating }   电路如下       串口绘图工具输出如下(蓝色的为ADC读取的值,黄色的为当前的频率)         代码如下:

  • 上传了资料: 【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】代码

  • 发表了主题帖: 【Follow me第二季第2期】+ 入门任务【搭建环境,Blink / 串口日志打印】

    本帖最后由 御坂10032号 于 2024-9-7 00:36 编辑 前言           非常荣幸能够参加DigiKey和EEWorld联合举办的follow me 开发板体验活动, 我也是非常幸运的拿到了参加活动的名额。 那么在第一章节入门任务我将会带着大家一步一步的搭建基于 Arduino IDE的开发环境, 以及使用Arduino API 操作IO翻转实现Blink, 并且使用串口控制台输出Hello world     介绍          Arduino UNO R4 WiFi 是一款基于32位Arm® Cortex®-M4 Renesas RA4M1微控制器,具有用于 Wi-Fi® 和蓝牙连接的ESP32模块,具备强大的计算能力和多种连接功能。该板SRAM 32kB,闪存256kB,时钟频率为48MHz,USB端口升级为USB-C,并且最大电源供应电压增加到24V。该板提供了一个CAN总线,允许用户通过连接多个扩展板来最小化布线并执行不同的任务。板载的Qwiic 连接器可以方便地创建即插即用风格的项目。                            规格参数   • 处理器:Arm cortex M4 • 存储:256KB Flash/32KB SRAM • 工作电压:5V • 输入电压:6~24V • 时钟频率:48MHz • 编程端口:USB-C • WiFi/蓝牙:ESP32-S3-MINI • 发光二极管矩阵:12x8(96 red LEDs) • 额外的连接 • Qwiic连接器 • OFF引脚 • VRTC引脚 • 数字I/O接口数: 14 • PWM接口数:6 • ADC接口数:6 • DAC接口数:1(12bit) • SPI接口数:1 • I2C接口数:2 • CAN接口数:1   数据手册如下(我这个只下载了R4的数据手册和原理图)   • Arduino UNO R4 WiFi数据手册 • Arduino UNO R4 WiFi原理图 • Arduino UNO R4 WiFi引脚图 • Arduino UNO R4 WiFi CAD文件 • LTR-329数据手册 • RA4M1数据手册 • RA4M1硬件用户手册 • SHT40数据手册   上述资料来自 Follow me 第二季     开发环境搭建   1 - 下载Arduino (我们可以通过上述的链接直接访问Arduino IDE的下载界面)       上述一共有三种安装方式,第一种是使用.exe文件的方式进行安装。第二种是使用.MSI的方式进行安装。而第三种则是以压缩包的方式。在此教程中我们使用第一种exe的方式进行下载。 点击后,页面将会询问是是否要捐献美金给Arduino,这里点击 Just downLoad(如下图所示)       下一页将会询问你是否想要使用邮件来订阅Arduino的一些消息(建议不要订阅)如果你订阅的话则输入你的邮件,并且点击 Subscript && Download(订阅并且下载)。我这里点击的是Just download   2-安装Arduino 打开下载后的Arduino IDE,同意许可协议。   选择为所有人安装或者为自己安装(我这里选择的为自己安装)       点击下一步,然后选择安装目录,点击安装       等待ArduinoIDE 安装完成       3- 配置使其下载的Arduino支持最新的Arduino uno R4     在上述的开发板管理器中搜索R4, 并且完成安装。 此时基于Arduino uno R4 的开发环境已经搭建完成, 我们可以通过下图来查看R4的官方examples       入门任务一 Blink   根据原理图得知,R4上一共有四个LED灯(除了led矩阵),其中两个灯用于串口的通讯, 一个灯用于电源的指示灯(绿色)和用户的自定义编程的LED DL4(黄色, 也就是开机demo 闪烁的led)         同时我们得知我们只需要控制P102 toggle 即可控制DL4 led的闪烁。 根据Arduino 官方API, 如果我们想控制IO的状态,那么分别需要用到以下三个函数 digitalRead() digitalWrite() pinMode() 但是在这里我们只需要切换IO的状态,所以我们只需要使用 2 和 3 即可, 那么便代码我们今天的第一个代码Blink led   void setup() { // sets the digital pin 13 as output // 设置GPIO13 为输出模式 pinMode(13, OUTPUT); } void loop() { // sets the digital pin 13 on // 输出高电平 digitalWrite(13, HIGH); // waits for a second // 延时一秒 delay(1000); // sets the digital pin 13 off // 输出低电平 digitalWrite(13, LOW); // 延时一秒 delay(1000); / }   下载并且烧录到R4中     实验现象如下:   [localvideo]e377dea23f9c566fcd22a073071e9775[/localvideo]     入门任务2 串口打印Hello world   根据官方文档和用户手册得知,D0 和D1 被用于USB的串口输入和输出, 因此只需要在程序中配置即可。   涉及的serial API有如下 begin() println()   那么我们便在上面的代码上进行修改,方便汇总   void setup() { // sets the digital pin 13 as output // 设置GPIO13 为输出模式 pinMode(13, OUTPUT); // 设置波特率 Serial.begin(115200); Serial.println("Hello World!"); Serial.println("Hello DigiKey and EEWorld!"); } void loop() { // sets the digital pin 13 on // 输出高电平 digitalWrite(13, HIGH); // waits for a second // 延时一秒 delay(1000); // sets the digital pin 13 off // 输出低电平 digitalWrite(13, LOW); // 延时一秒 delay(1000); }   实验现象如下:    

  • 2024-09-06
  • 回复了主题帖: 动手学深度学习(一)

    nmg 发表于 2024-9-6 14:49 说的不支持LaTex数学公式渲染问题已经反馈了   数学基础是不是可以边用边看,一下子看到这么多 ... 我感觉 搞不懂公式根本没办法继续

  • 2024-09-05
  • 回复了主题帖: 免费尝鲜:热气体式加速度传感器来啦,拍摄冲击对比实验有好礼

    这个打个板配个低功耗的单片机直接从楼房上丢下去, 然后记录加速度有说法没?

  • 2024-09-04
  • 回复了主题帖: [工业级智能控制MCU 匠芯创D133CBS] 7 - RTC 时钟测试

    date: 2024-11-08 time: 18:16:59

  • 2024-09-03
  • 回复了主题帖: [工业级智能控制MCU 匠芯创D133CBS] 7 - RTC 时钟测试

    01:06:00

  • 发表了主题帖: [工业级智能控制MCU 匠芯创D133CBS] 7 - RTC 时钟测试

    简介   Real Time Clock (RTC) 模块用于日期时间的保存和更新,在无网络下为系统提供一份有效的日期和时间。通过备用电池供电,在断电场景下也可以一直计数和保存时间,同时还有闹钟唤醒的功能。在本章节我们将详细的对匠芯创D133CBS 的RTC时钟进行测试。   提前准备工作   在使用RTC之前请确保J9也就是下图标红的地方插入了纽扣电池并且正常供电     配置步骤   1- 在 Luban-Lite 根目录下执行 scons --menuconfig进入 menuconfig 的功能配置界面,按如下选择:   2- 在menuconfig 开启rtc的测试驱动     此时位于bsp/examples/test-rtc 将会被配置并且添加到编译的上下文中。       上述代码主要用于设置RTC的时钟以及打印设置后的时间,并且通过Finsh进行执行。   3- 创建时间打印任务(避免重复设置日期时间) 我们自己创建一个输出当前时间的任务,用于每一秒向控制台输出时间   #include <rtthread.h> #include <rtdevice.h> #include <ulog.h> #include <finsh.h> #include <drivers/rtc.h> #include <drivers/alarm.h> #include "aic_core.h" void rtc_printf(void *agrs) { struct tm *local_time; time_t now; while (1) { now = time(RT_NULL); local_time = localtime(&now); rt_kprintf("date: %04d-%02d-%02d\n", local_time->tm_year + 1900, local_time->tm_mon + 1, local_time->tm_mday); rt_kprintf("time: %02d:%02d:%02d\n", local_time->tm_hour, local_time->tm_min, local_time->tm_sec); rt_thread_delay(1000); } } MSH_CMD_EXPORT(rtc_printf, rtc_printf); int main(void) { rt_thread_t tid = RT_NULL; tid = rt_thread_create("RTC_read", rtc_printf, RT_NULL, 1024, 20, 5); rt_thread_startup(tid); return 0; }   4- 将代码烧录到开发板中   5- 打开控制台输入test_rtc 设置日期时间   6-控制台每隔一秒输出当前的时间     那么目前开发板中设置的时间大概为 2024-11-08  01:01:33. 现在我将记录下当前的时间并且将开发板断电,等到明天早上在评论区更新一下明天的开发板内的时间     历史测评链接   [工业级智能控制MCU 匠芯创D133CBS] 1 - 开箱及其环境搭建 https://bbs.eeworld.com.cn/thread-1290588-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 2 - 创建项目及其注意事项 https://bbs.eeworld.com.cn/thread-1290861-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 3 - GPIO-IO中断 https://bbs.eeworld.com.cn/thread-1290902-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 4-  BUG 反馈 (SDK lunch11 包更新错误) https://bbs.eeworld.com.cn/thread-1290904-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 5- 使用RTT-软件包结合IIC读取BH1750 https://bbs.eeworld.com.cn/thread-1291002-1-1.html [工业级智能控制MCU 匠芯创D133CBS] 6 - PWM 输出 https://bbs.eeworld.com.cn/thread-1291463-1-1.html

最近访客

< 1/6 >

统计信息

已有84人来访过

  • 芯积分:484
  • 好友:2
  • 主题:38
  • 回复:82

留言

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


现在还没有留言