一、准备工作
- 开发平台:RT-Thread Studio
- 开发板:ART-PI
- 主控芯片:STM32H750
- 温湿度传感器:SHT30
- 显示模组:0.96’OLED(SSD1306)
- 串口调试助手:SecureCRT
注意:这里由于ART-PI开发板自带WiFi模组,可直接使能。如果使用其他开发板,可考虑使用ESP8266通信模块。
二、新建RT-Thread 项目
三、获取温湿度数据
1、双击打开左边导航栏的RT-Thread Setting
2、使能软件模拟i2c(单击点亮即可)
3、配置i2c及相关引脚
这里的i2c引脚配置依自己开发板而定,配置完成后CTRL+S保存配置
4、添加SHT3X软件包
CTRL+S保存配置,点击编译并下载
具体RT-Thread Studio的一般使用可参照【玩转RT-Thread】 RT-Thread Studio使用(1)(按键控制电机正反转、蜂鸣器)
此时打开串口工具,可以看到前面配置的i2c1和i2c3已经注册成功
此时在串口输入help,可以看出有一个sht3x配置
输入: sht3x probe i2c3 pd sht3x read(读取温湿度信息)
四、获取NTP时间
1、使能选择WiFi框架
2、使能AP6212库
3、添加easyflash和netutils软件包
鼠标右键netutils打开配置项
使能NTP (网络时间协议)客户端
使能软件模拟RTC
CTRL+S保存配置
修改配置
(1)打开电脑中项目所在的路径-workpace-项目名称-packages-EasyFlash-v4.1.0-port,将port目录下的ef_fal_port.c文件复制到workpace-项目名称-board-port中 (2)修改port中宏定义FAL_EF_PART_NAME 中的名字 #define FAL_EF_PART_NAME "easyflash" //修改后的宏定义
此时再编译并下载到开发板中
4、连接WiFi
wifi scan //搜索wifi wifi join [SSID] [PASSWORD] //连接WiFi SSID:WiFi名称 PASSWORD:WiFi密码
5、设置开机自连接WiFi
(1)在board/port 目录下创建wifi_config.c文件来实现wifi上电自动连接 代码如下:
/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2022-06-09 ASUS the first version */ #include <rtthread.h> #ifdef BSP_USING_WIFI #include <wlan_mgnt.h> #include <wlan_cfg.h> #include <wlan_prot.h> #include <easyflash.h> #include <fal.h> #include <stdio.h> #include <stdlib.h> #if (EF_SW_VERSION_NUM < 0x40000) static char *str_base64_encode_len(const void *src, char *out, int input_length); static int str_base64_decode(const char *data, int input_length, char *decoded_data); static const unsigned char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char base64_decode_table[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; static char *str_base64_encode_len(const void *src, char *out, int len) { unsigned char *pos; const unsigned char *end, *in; size_t olen; olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ olen += olen / 72; /* line feeds */ olen++; /* nul termination */ end = (const unsigned char *)src + len; in = (const unsigned char *)src; pos = (unsigned char *)out; while (end - in >= 3) { *pos++ = base64_table[in[0] >> 2]; *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; *pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; *pos++ = base64_table[in[2] & 0x3f]; in += 3; } if (end - in) { *pos++ = base64_table[in[0] >> 2]; if (end - in == 1) { *pos++ = base64_table[(in[0] & 0x03) << 4]; *pos++ = '='; } else { *pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; *pos++ = base64_table[(in[1] & 0x0f) << 2]; } *pos++ = '='; } *pos = '\0'; return (char *)out; } /* * return: length, 0 is error. */ static int str_base64_decode(const char *data, int input_length, char *decoded_data) { int out_len; int i, j; if (input_length % 4 != 0) return 0; out_len = input_length / 4 * 3; if (data[input_length - 1] == '=') out_len--; if (data[input_length - 2] == '=') out_len--; for (i = 0, j = 0; i < input_length;) { uint32_t sextet_a = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]]; uint32_t sextet_b = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]]; uint32_t sextet_c = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]]; uint32_t sextet_d = data[i] == '=' ? 0 & i++ : base64_decode_table[data[i++]]; uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6); if (j < out_len) decoded_data[j++] = (triple >> 2 * 8) & 0xFF; if (j < out_len) decoded_data[j++] = (triple >> 1 * 8) & 0xFF; if (j < out_len) decoded_data[j++] = (triple >> 0 * 8) & 0xFF; } return out_len; } static int read_cfg(void *buff, int len) { char *wlan_cfg_info = RT_NULL; wlan_cfg_info = ef_get_env("wlan_cfg_info"); if (wlan_cfg_info != RT_NULL) { str_base64_decode(wlan_cfg_info, rt_strlen(wlan_cfg_info), buff); return len; } else { return 0; } } static int get_len(void) { int len; char *wlan_cfg_len = RT_NULL; wlan_cfg_len = ef_get_env("wlan_cfg_len"); if (wlan_cfg_len == RT_NULL) { len = 0; } else { len = atoi(wlan_cfg_len); } return len; } static int write_cfg(void *buff, int len) { char wlan_cfg_len[12] = {0}; char *base64_buf = RT_NULL; base64_buf = rt_malloc(len * 4 / 3 + 4); /* 3-byte blocks to 4-byte, and the end. */ if (base64_buf == RT_NULL) { return -RT_ENOMEM; } rt_memset(base64_buf, 0, len); /* interger to string */ sprintf(wlan_cfg_len, "%d", len); /* set and store the wlan config lengths to Env */ ef_set_env("wlan_cfg_len", wlan_cfg_len); str_base64_encode_len(buff, base64_buf, len); /* set and store the wlan config information to Env */ ef_set_env("wlan_cfg_info", base64_buf); ef_save_env(); rt_free(base64_buf); return len; } #else static int read_cfg(void *buff, int len) { size_t saved_len; ef_get_env_blob("wlan_cfg_info", buff, len, &saved_len); if (saved_len == 0) { return 0; } return len; } static int get_len(void) { int len; size_t saved_len; ef_get_env_blob("wlan_cfg_len", &len, sizeof(len), &saved_len); if (saved_len == 0) { return 0; } return len; } static int write_cfg(void *buff, int len) { /* set and store the wlan config lengths to Env */ ef_set_env_blob("wlan_cfg_len", &len, sizeof(len)); /* set and store the wlan config information to Env */ ef_set_env_blob("wlan_cfg_info", buff, len); return len; } #endif /* (EF_SW_VERSION_NUM < 0x40000) */ static const struct rt_wlan_cfg_ops ops = { read_cfg, get_len, write_cfg }; void wlan_autoconnect_init(void) { fal_init(); easyflash_init(); rt_wlan_cfg_set_ops(&ops); rt_wlan_cfg_cache_refresh(); } #endif
(2)在main.c中添加自动连接函数
#include <rtthread.h> #include <rtdevice.h> #include "drv_common.h" #define LED_PIN GET_PIN(I, 8) extern void wlan_autoconnect_init(void); int main(void) { rt_uint32_t count = 1; rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT); /* init Wi-Fi auto connect feature */ wlan_autoconnect_init(); /* enable auto reconnect on WLAN device */ rt_wlan_config_autoreconnect(RT_TRUE); return RT_EOK; } #include "stm32h7xx.h" static int vtor_config(void) { /* Vector Table Relocation in Internal QSPI_FLASH */ SCB->VTOR = QSPI_BASE; return 0; } INIT_BOARD_EXPORT(vtor_config);
编译并下载,此时开发板就能够从flash中自动读取上次连接数据并自动连接WiFi了。