manhuami2007

  • 2024-10-07
  • 加入了学习《Follow me 第二季第2期任务提交》,观看 【得捷电子Follow me】提交视频

  • 2024-10-06
  • 发表了主题帖: 【Follow me第二季第2期】+ 任务总结提交

    本帖最后由 manhuami2007 于 2024-10-31 11:53 编辑 一、任务视频 【得捷电子Follow me】提交视频-Follow me 第二季第2期任务提交-EEWORLD大学堂   二、任务实现详情     一、任务介绍 很高兴能参加此次Follow me第二季第二期活动,通过这次活动学到了Arduino的一些知识,以及Home assistant相关的知识,对智能家居有了更进一步的理解。本次完成了活动所要求的任务,包括LED闪烁、串口输出、LED矩阵、DAC、ADC、WIFI连接HA通过MQTT传输数据、LTR329获取光强数据、SHT40传感器数据获取等。所用到的器件有Arduino UNO R4 WIFI主板一块,LTR329和SHT40传感器小板各一块和4P连接线2根。   这款开发板主控芯片升级为了瑞萨的32位Arm Cortex-M4内核的RA4M1微控制器,拥有256KB Flash和32KB SRAM,时钟频率来到了48MHz,接口可以与之前的R3进行兼容,但是这次与电脑的接口换上了更为先进的TYPE-C接口。这块板子还有一个12*8的LED矩阵,可以用来显示数字、字母、简单的图形甚至汉字,有点像microbit,可玩性更强了。 软件上主要使用的是Arduino IDE进行开发的。但为了完成进阶任务,还需要安装MQTT服务器和Home assistant平台。其中HA平台在windows上安装比较麻烦,花费的时间比较长。     二、任务实现 2.1 入门任务   作为第一个任务,在使用之前需要先安装该开发板的库。在开发板管理器中搜索然后安装即可。   2.1.1 Blink功能 开发板上包含多个LED,分别是串口收发的2个LED、电源LED,以及1个用户可用的LED。为了实现Blink 功能,点击菜单栏的“文件 -> 示例 -> 01.Basics -> Blink”,可以通过这个示例实现了对LED的闪烁控制。   可以修改loop函数中delay函数的参数,改变闪烁时间,例如改成500ms,然后上传代码,可以看到LED闪烁速度的变化。   流程图为:   2.1.2 串口输出Hello EEWorld! 串口输出需要对serial进行初始化,然后调用Serial.println函数进行输出。代码如下:   输出效果如下图:   流程图为:   2.2 基础任务 2.2.1.驱动12x8点阵LED   上图是LED点阵的原理图,总共96个LED。在程序中对应的是3个32位的整型数,LED点阵的顺序是从左至右,从上至下,对应的位为1时点亮LED。 Arduino在程序上有很好的易用性,不用过分的去纠结底层的原理,直接拿来用就行。在该任务中通过其示例代码,可以看到其使用了Arduino_LED_Matrix库,通过matrix.loadFrame() 函数调用对应的数组就可以实现相应的显示。   显示效果是4个LED灯循环转动。      流程图为:   2.2.2 用DAC生成正弦波 通过主控芯片内置的DAC输出正弦信号,在该任务中使用A0通道进行输出。其输出函数也很简单,使用函数wave.sine(freq)通过设置不同参数,改变正弦波的频率,输出波形如下图,可以看到黄色波形为正弦波,输出频率为10Hz。   流程图为;   代码如下: #include "analogWave.h" analogWave wave(DAC);   int freq = 10;  // in hertz, change accordingly void setup() {   Serial.begin(115200);     wave.sine(freq);       // Generate a sine wave with the initial frequency } void loop() { } 2.2.3 用OPAMP放大DAC信号 该开发板的主控芯片内置了运算放大器,在这里搭建了一个同相比例放大电路,放大倍数为2倍。下面的程序使用A0输出正弦信号然后输入到A1,A1作为运放的正相输入端,A2是反相输入端,A3为输出端。接线如下图所示   流程图为:   代码如下 #include <OPAMP.h> int wave_sin[256] = {   0x80,0x83,0x85,0x88,0x8A,0x8D,0x8F,0x92,     0x94,0x97,0x99,0x9B,0x9E,0xA0,0xA3,0xA5,     0xA7,0xAA,0xAC,0xAE,0xB1,0xB3,0xB5,0xB7,     0xB9,0xBB,0xBD,0xBF,0xC1,0xC3,0xC5,0xC7,     0xC9,0xCB,0xCC,0xCE,0xD0,0xD1,0xD3,0xD4,     0xD6,0xD7,0xD8,0xDA,0xDB,0xDC,0xDD,0xDE,     0xDF,0xE0,0xE1,0xE2,0xE3,0xE3,0xE4,0xE4,     0xE5,0xE5,0xE6,0xE6,0xE7,0xE7,0xE7,0xE7,     0xE7,0xE7,0xE7,0xE7,0xE6,0xE6,0xE5,0xE5,     0xE4,0xE4,0xE3,0xE3,0xE2,0xE1,0xE0,0xDF,     0xDE,0xDD,0xDC,0xDB,0xDA,0xD8,0xD7,0xD6,     0xD4,0xD3,0xD1,0xD0,0xCE,0xCC,0xCB,0xC9,     0xC7,0xC5,0xC3,0xC1,0xBF,0xBD,0xBB,0xB9,     0xB7,0xB5,0xB3,0xB1,0xAE,0xAC,0xAA,0xA7,     0xA5,0xA3,0xA0,0x9E,0x9B,0x99,0x97,0x94,     0x92,0x8F,0x8D,0x8A,0x88,0x85,0x83,0x80,     0x7D,0x7B,0x78,0x76,0x73,0x71,0x6E,0x6C,     0x69,0x67,0x65,0x62,0x60,0x5D,0x5B,0x59,     0x56,0x54,0x52,0x4F,0x4D,0x4B,0x49,0x47,     0x45,0x43,0x41,0x3F,0x3D,0x3B,0x39,0x37,     0x35,0x34,0x32,0x30,0x2E,0x2D,0x2C,0x2A,     0x29,0x28,0x26,0x25,0x24,0x23,0x22,0x21,     0x20,0x1F,0x1E,0x1D,0x1D,0x1C,0x1C,0x1B,     0x1B,0x1A,0x1A,0x1A,0x19,0x19,0x19,0x19,     0x19,0x19,0x19,0x19,0x1A,0x1A,0x1A,0x1B,     0x1B,0x1C,0x1C,0x1D,0x1D,0x1E,0x1F,0x20,     0x21,0x22,0x23,0x24,0x25,0x26,0x28,0x29,     0x2A,0x2C,0x2D,0x2F,0x30,0x32,0x34,0x35,     0x37,0x39,0x3B,0x3D,0x3F,0x41,0x43,0x45,     0x47,0x49,0x4B,0x4D,0x4F,0x52,0x54,0x56,     0x59,0x5B,0x5D,0x60,0x62,0x65,0x67,0x69,     0x6C,0x6E,0x71,0x73,0x76,0x78,0x7B,0x7D }; int i = 0; void setup() {   OPAMP.begin(OPAMP_SPEED_HIGHSPEED);   analogWriteResolution(8);  // set the analog output resolution to 12 bit (4096 levels) } void loop() {   analogWrite(DAC, wave_sin[i]/2);  // write the selected waveform on DAC0   i++;   if (i == 256)  // Reset the counter to repeat the wave     i = 0;   delayMicroseconds(10);  // Hold the sample value for the sample time } 输出信号如下图所示,绿色为输入信号,黄色为输出信号,输出信号是输入信号的2倍:      2.2.4 用ADC采集并且打印数据到串口等其他接口可上传到上位机显示曲线 在这个示例里,使用ADC的A0端口,对输入的10Hz的正弦波进行采集。接线图如下所示:  可以看到其在串口绘图器中显示曲线如下图所示:   流程图为:   代码如下: const int analogInPin = A0;  // Analog input pin that the potentiometer is attached to int sensorValue = 0;  // value read from the pot int outputValue = 0;  // value output to the PWM (analog out) void setup() {   // initialize serial communications at 9600 bps:   Serial.begin(9600); } void loop() {   // read the analog in value:   sensorValue = analogRead(analogInPin);   // map it to the range of the analog out:   outputValue = map(sensorValue, 0, 1023, 0, 255);   // change the analog out value:   Serial.println(outputValue);   delay(2); } 2.3 进阶任务 通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant) 这个任务的难度最大了,需要安装多个软件,包括MQTT服务器和HA平台。因为没有使用其它的平台,因此全部安装到windows电脑上了。 首先搭建MQTT的服务器,参考了下面的帖子才找到了能够在windows下使用的MQTT服务器,这里使用的是emqx搭建mqtt服务器。 Windows系统下本地MQTT服务器搭建(保姆级教程)_mqtt windows-CSDN博客 接着安装HA平台,我这里使用的是虚拟机Virtualbox,然后在home assistant的官网下载对应的镜像。启动服务之后,可以在网页上看到对HA的控制面板。     当HA和MQTT的服务器都创建好之后,就可以向HA中添加设备了,这里是参考了 【Follow me第二季第2期】+通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA - DigiKey得捷技术专区 - 电子工程世界-论坛 (eeworld.com.cn) 这篇帖子,通过向topic“homeassistant/sensor/sensorBedroomH/config”发送信息添加设备: { "device_class":"humidity", "name":"Humidity", "state_topic":"homeassistant/sensor/sensorBedroom/state", "unit_of_measurement":"%", "value_template":"{{ value_json.humidity}}", "unique_id":"hum01ae", "device":{ "identifiers":[ "bedroom01ae" ], "name":"Bedroom" } } 这时就可以将新建的设备添加到仪表盘了。从上面的信息可以看出其创建了一个"Humidity"设备,可以通过向"homeassistant/sensor/sensorBedroom/state"这个topic发送json为humidity的数据,这样在仪表盘上就能显示数据了发送的数据示例如下:   显示效果如下:   因此在arduino上需要实现mqtt消息发送的功能。 流程图:      代码如下 #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> char ssid[] = "ChinaNet-JvAb";         char pass[] = "s3fackxx";   const char broker[] = "192.168.1.8"; int        port     = 1883; const char state_topic[]  = "homeassistant/sensor/sensorBedroom/state"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; const long interval = 1000; unsigned long previousMillis = 0; int count = 0; void setup() {   Serial.begin(115200);   while (!Serial) {     ; // wait for serial port to connect. Needed for native USB port only   }   Serial.println("HA com test");   Serial.println("connect to WPA SSID: ");   Serial.println(ssid);   // attempt to connect to WiFi network:   while (WiFi.begin(ssid, pass) != WL_CONNECTED) {     Serial.print("......");     delay(5000);   }   Serial.print("connect wifi succeed!");   Serial.println();   Serial.println(WiFi.localIP());   // You can provide a unique client ID, if not set the library uses Arduino-millis()   // Each client must have a unique client ID    mqttClient.setId("clientId");   // You can provide a username and password for authentication    mqttClient.setUsernamePassword("li", "l1111111");   Serial.print("connect to the MQTT broker: ");   Serial.println(broker);   if (!mqttClient.connect(broker, port)) {     Serial.print("MQTT connection failed! Error code = ");     Serial.println(mqttClient.connectError());     while (1);   }   Serial.println("connected to the MQTT succeed!");   Serial.println(); } void loop() {   // put your main code here, to run repeatedly:   mqttClient.poll();   unsigned long currentMillis = millis();   if (currentMillis - previousMillis >= interval) {     // save the last time a message was sent     previousMillis = currentMillis;     dataObj["humidity"] = count;     String jsonString = JSON.stringify(dataObj);     // send message, the Print interface can be used to set the message contents     mqttClient.beginMessage(state_topic);     mqttClient.print(jsonString);     mqttClient.endMessage();     count++;     if(count>=90)       count = 0;     delay(1000);   } } 2.4 扩展任务 2.4.1 通过外部LTR-329 环境光传感器,上传光照度到HA,通过HA面板显示数据 使用开发板上的I2C接口连接传感器小板。   首先获取LTR-329的光传感器数据,流程图   代码如下 #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);   ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);   ltr.setMeasurementRate(LTR3XX_MEASRATE_200); } void loop() {   bool valid;   uint16_t visible_plus_ir, infrared;   if (ltr.newDataAvailable()) {     valid = ltr.readBothChannels(visible_plus_ir, infrared);     if (valid) {       Serial.print("CH0 Visible + IR: ");       Serial.print(visible_plus_ir);       Serial.print("\t\tCH1 Infrared: ");       Serial.println(infrared);     }   }   delay(100); } 然后在HA平台上新增一个LTR329的传感器。同样通过向topic:homeassistant/sensor/sensorLTR329/config发送如下消息,新建一个LTR329传感器。 {     "name":"LTR329",     "state_topic":"homeassistant/sensor/sensorLTR329/state",     "unit_of_measurement":"Lux",     "value_template":"{{ value_json.value}}",     "unique_id":"ltr01ae",     "device":{         "identifiers":[             "bedroom01ae"         ],         "name":"LTR329-1"     } } 然后arduino通过mqtt协议向相应的topic发送消息即可, 流程图为:   如下代码实现数据的上传: #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> #include "Adafruit_LTR329_LTR303.h" Adafruit_LTR329 ltr = Adafruit_LTR329(); char ssid[] = "ChinaNet-JvAb";         char pass[] = "s3fackxx";   const char broker[] = "192.168.1.8"; int        port     = 1883; const char state_topic[]  = "homeassistant/sensor/sensorLTR329/state"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; const long interval = 1000; unsigned long previousMillis = 0; int count = 0; void setup() {   Serial.begin(115200);   while (!Serial) {     ; // wait for serial port to connect. Needed for native USB port only   }   Serial.println("HA com test");   Serial.println("connect to WPA SSID: ");   Serial.println(ssid);   // attempt to connect to WiFi network:   while (WiFi.begin(ssid, pass) != WL_CONNECTED) {     Serial.print("......");     delay(5000);   }   Serial.print("connect wifi succeed!");   Serial.println();   Serial.println(WiFi.localIP());   // You can provide a unique client ID, if not set the library uses Arduino-millis()   // Each client must have a unique client ID    mqttClient.setId("clientId");   // You can provide a username and password for authentication    mqttClient.setUsernamePassword("li", "l1111111");   Serial.print("connect to the MQTT broker: ");   Serial.println(broker);   if (!mqttClient.connect(broker, port)) {     Serial.print("MQTT connection failed! Error code = ");     Serial.println(mqttClient.connectError());     while (1);   }   Serial.println("connected to the MQTT succeed!");   Serial.println();   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);   ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);   ltr.setMeasurementRate(LTR3XX_MEASRATE_200); } void loop() {   // put your main code here, to run repeatedly:   bool valid;   uint16_t visible_plus_ir, infrared;   if (ltr.newDataAvailable()) {     valid = ltr.readBothChannels(visible_plus_ir, infrared);   }   mqttClient.poll();   unsigned long currentMillis = millis();   if (currentMillis - previousMillis >= interval) {     // save the last time a message was sent     previousMillis = currentMillis;     dataObj["value"] = visible_plus_ir;     String jsonString = JSON.stringify(dataObj);     // send message, the Print interface can be used to set the message contents     mqttClient.beginMessage(state_topic);     mqttClient.print(jsonString);     mqttClient.endMessage();     delay(200);   } } 2.4.2 通过外部SHT40温湿度传感器,上传温湿度到HA,通过HA面板显示数据 因为2个传感器小板都是使用的I2C接口,因此可以进行串行的连接,接线图如下:   温湿度数据包含了2项内容,因此在HA平台上新增了2个设备,一个用于显示温度,一个用于显示湿度。 topic:homeassistant/sensor/sensorSHT40-TEMP/config {   "name":"sht40",   "state_topic":"homeassistant/sensor/sensorSHT40-TEMP/state",   "unit_of_measurement":"C",   "value_template":"{{ value_json.value}}",   "unique_id":"sht40ae",   "device":{     "identifiers":[       "sht40ae-temp"     ],     "name":"sht40-t"   } } topic:homeassistant/sensor/sensorSHT40-HUM/config {   "name":"sht40",   "state_topic":"homeassistant/sensor/sensorSHT40-HUM/state",   "unit_of_measurement":"%",   "value_template":"{{ value_json.value}}",   "unique_id":"sht40ae",   "device":{     "identifiers":[       "sht40ae-hum"     ],     "name":"sht40-h"   } } 流程图为:   代码实现如下: #include <ArduinoMqttClient.h> #include <WiFiS3.h> #include <WiFiClient.h> #include <Arduino_JSON.h> #include "Adafruit_LTR329_LTR303.h" #include "Adafruit_SHT4x.h" Adafruit_LTR329 ltr = Adafruit_LTR329(); Adafruit_SHT4x sht4 = Adafruit_SHT4x(); char ssid[] = "ChinaNet-JvAb";         char pass[] = "s3fackxx";   const char broker[] = "192.168.1.8"; int        port     = 1883; const char state_topic[]  = "homeassistant/sensor/sensorLTR329/state"; const char state_topic_temp[]  = "homeassistant/sensor/sensorSHT40-TEMP/state"; const char state_topic_hum[]  = "homeassistant/sensor/sensorSHT40-HUM/state"; WiFiClient wifiClient; MqttClient mqttClient(wifiClient); JSONVar dataObj; const long interval = 200; unsigned long previousMillis = 0; int count = 0; void setup() {   Serial.begin(115200);   while (!Serial) {     ; // wait for serial port to connect. Needed for native USB port only   }   Serial.println("HA com test");   Serial.println("connect to WPA SSID: ");   Serial.println(ssid);   // attempt to connect to WiFi network:   while (WiFi.begin(ssid, pass) != WL_CONNECTED) {     Serial.print("......");     delay(5000);   }   Serial.print("connect wifi succeed!");   Serial.println();   Serial.println(WiFi.localIP());   // You can provide a unique client ID, if not set the library uses Arduino-millis()   // Each client must have a unique client ID    mqttClient.setId("clientId");   // You can provide a username and password for authentication    mqttClient.setUsernamePassword("li", "l1111111");   Serial.print("connect to the MQTT broker: ");   Serial.println(broker);   if (!mqttClient.connect(broker, port)) {     Serial.print("MQTT connection failed! Error code = ");     Serial.println(mqttClient.connectError());     while (1);   }   Serial.println("connected to the MQTT succeed!");   Serial.println();   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);   ltr.setIntegrationTime(LTR3XX_INTEGTIME_100);   ltr.setMeasurementRate(LTR3XX_MEASRATE_200);   if(sht4.begin(&Wire1) == false)   {     Serial.println("SHT40 not detected. Please check wiring. Freezing.");     while (1)       ;   }   sht4.setPrecision(SHT4X_HIGH_PRECISION);   sht4.setHeater(SHT4X_NO_HEATER);   Serial.println("SHT40 acknowledged."); } void loop() {   // put your main code here, to run repeatedly:   bool valid;   uint16_t visible_plus_ir, infrared;   sensors_event_t humidity, temp;   sht4.getEvent(&humidity, &temp);   if (ltr.newDataAvailable()) {     valid = ltr.readBothChannels(visible_plus_ir, infrared);   }   mqttClient.poll();   unsigned long currentMillis = millis();   if (currentMillis - previousMillis >= interval) {     // save the last time a message was sent     previousMillis = currentMillis;     dataObj["value"] = visible_plus_ir;     String jsonString = JSON.stringify(dataObj);     // send message, the Print interface can be used to set the message contents     mqttClient.beginMessage(state_topic);     mqttClient.print(jsonString);     mqttClient.endMessage();     dataObj["value"] = temp.temperature;     Serial.println("Temp *C = " + String( temp.temperature));     jsonString = JSON.stringify(dataObj);     mqttClient.beginMessage(state_topic_temp);     mqttClient.print(jsonString);     mqttClient.endMessage();     dataObj["value"] = humidity.relative_humidity;     Serial.println("Hum. % = " + String(humidity.relative_humidity));     jsonString = JSON.stringify(dataObj);     mqttClient.beginMessage(state_topic_hum);     mqttClient.print(jsonString);     mqttClient.endMessage();     delay(200);   } } 上传的效果如下图:         三、总结 个人感觉这次的任务比以往更有难度,尤其是开发环境的搭建上,比如HA平台的安装,MQTT服务器的安装等。HA平台的使用上也比较有难度。还有就是这次任务可能需要一些额外的设备,比如示波器、额外的排线。不过有难度的任务才能学到更多的知识,通过这次任务认识了HA平台,对智能家居的开发有了新的任务。最后感谢EEWORLD和得捷对这次活动的支持。   三、可编译下载的代码   Follow me 第二季第2期任务代码-嵌入式开发相关资料下载-EEWORLD下载中心  

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

  • 2024-08-31
  • 发表了主题帖: 【Follow me第二季第2期】+ 开箱

    收到了得捷寄过来的,板子很漂亮。而且底部还有亚克力保护,看着还是挺上档次的,接口也换成了type-c的。        

  • 2024-06-21
  • 发表了主题帖: 【2023 DigiKey大赛参与奖】开箱帖:树莓派ZERO 2W,RP2040和STM32U083C-DK开发板

    纠结了好久,最后选择了树莓派ZERO 2W和STM32U083C-DK开发板,还有一个凑单的RP2040。  

  • 2024-01-29
  • 回复了主题帖: stm32

    你的问题好混乱啊,都没看懂说的是什么。问题里的看运气是什么意思?DMA是不是循环模式,或者是不是一个缓存区都不重要,重要的是你要怎么处理接收到的数据,用的是哪个函数。

回复过的帖子

统计信息

已有602人来访过

  • 芯积分:583
  • 好友:--
  • 主题:125
  • 回复:149

留言

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


现在还没有留言