RT-Thread Studio 项目实战教程 | 快速打造一个桌面mini网络时钟TOC
一、前期准备
1. 1.1开发环境准备
RT-Thread Studio 是一站式的 RT-Thread 开发工具,通过简单易用的图形化配置系统以及丰富的软件包和组件资源,让物联网开发变得简单和高效。 官网下载
新建工程采用开发板项目
1. 1.2硬件准备
ART-Pi硬件需求
- 主控:ART-Pi开发板
- 温湿度传感器: SHT30
- 通信模组:ESP8266(WIFI)
- 显示模组:0.96’OLED(SSD1306)
二、获取温湿度与添加SHT3x软件包
- 获取温湿度
通过点击RT-Thread Settings 配置相应的模拟i2c引脚,右击打开并打开详细配置,配置引脚。
进入如下界面,本文基于ART-Pi,读者可根据自己所用开发板自行配置。
- 添加SHT3x软件包
2.1搜索并点击添加软件包
ctrl+s保存,将程序下载到开发板上。
下载后命令行输入如下指令
sht3x probe i2c2 pd //根据实际连接的引脚选择正确的iic总线
sht3x read
将shtx注册上,命令行输入list_device 将显示注册详情。
三、获取NTP时间
- 添加ESP8266设备驱动
RT-Thread Studio有在线软件包中心,里面有非常丰富的软件包供用户使用
首先先开启libc组件,之后打开at_device软件包
- 添加at_device软件包
同样,添加到工程设置之后,右键单击进入该软件包配置页面,并配置实际信息。 - 设置里选择wifi框架
- 硬件中选择AP6216
- 添加netutils工具软件包
- 开启NTP服务器配置
开启软件模拟RTC
添加后 ctrl+s 保存编译
将程序下载到开发板中,命令行输入以下命令
wifi scan //搜索wifi
wifi join [SSID] [PASSWORD] //连接WiFi
ssid:是将要连接wifi的名字
password:是将要连接WiFi的密码
- 自动连接wifi
在board/port 目录下创建wifi_config.c文件来实现wifi上电自动连接
并在main.c中添加自动连接函数
这样wifi就会在下载程序后自动连接
四、OLED显示温湿度和时间
- 添加u8g2软件包
编写程序显示OLED线程
在application分组下创建一个用户文件oled_display.cpp文件,存放本项目中的OLED显示代码如下:
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <U8g2lib.h>
#include <stdio.h>
#include <drv_soft_i2c.h>
extern "C"
{
#include <sht3x.h>
}
extern "C"
{
sht3x_device_t sht3x_init(const char *i2c_bus_name, rt_uint8_t sht3x_addr);
rt_err_t sht3x_read_singleshot(sht3x_device_t dev);
}
#define OLED_I2C_PIN_SCL 7 // PA7
#define OLED_I2C_PIN_SDA 20 // PB4
static U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0,\
/* clock=*/ OLED_I2C_PIN_SCL,\
/* data=*/ OLED_I2C_PIN_SDA,\
/* reset=*/ U8X8_PIN_NONE);
#define SUN 0
#define SUN_CLOUD 1
#define CLOUD 2
#define RAIN 3
#define THUNDER 4
static void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
// fonts used:
// u8g2_font_open_iconic_embedded_6x_t
// u8g2_font_open_iconic_weather_6x_t
// encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic
switch(symbol)
{
case SUN:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 69);
break;
case SUN_CLOUD:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 65);
break;
case CLOUD:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 64);
break;
case RAIN:
u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
u8g2.drawGlyph(x, y, 67);
break;
case THUNDER:
u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
u8g2.drawGlyph(x, y, 67);
break;
}
}
static void drawWeather(uint8_t symbol, int degree)
{
drawWeatherSymbol(0, 63, symbol);
u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.setCursor(55, 63);
u8g2.print(degree);
u8g2.print("C");
}
static void drawHumidity(uint8_t symbol, int humidity)
{
drawWeatherSymbol(0, 63, symbol);
u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.setCursor(55, 63);
u8g2.print(humidity);
u8g2.print("%");
}
void oled_display()
{
u8g2.begin();
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_logisoso32_tf);
u8g2.setCursor(48+3, 42);
u8g2.print("Hi~"); // requires enableUTF8Print()
u8g2.setFont(u8g2_font_6x13_tr); // choose a suitable font
u8g2.drawStr(30, 60, "By Mculover666"); // write something to the internal memory
u8g2.sendBuffer();
sht3x_device_t sht3x_device;
sht3x_device = sht3x_init("i2c1", 0x44);
rt_thread_mdelay(2000);
int status = 0;
char mstr[3];
char hstr[3];
time_t now;
struct tm *p;
int min = 0, hour = 0;
int temperature = 0,humidity = 0;
while(1)
{
switch(status)
{
case 0:
now = time(RT_NULL);
p=gmtime((const time_t*) &now);
hour = p->tm_hour;
min = p->tm_min;
sprintf(mstr, "%02d", min);
sprintf(hstr, "%02d", hour);
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_logisoso42_tn);
u8g2.drawStr(0,63,hstr);
u8g2.drawStr(50,63,":");
u8g2.drawStr(67,63,mstr);
} while ( u8g2.nextPage() );
rt_thread_mdelay(5000);
status = 1;
break;
case 1:
if(RT_EOK == sht3x_read_singleshot(sht3x_device))
{
temperature = (int)sht3x_device->temperature;
}
else
{
temperature = 0;
}
u8g2.clearBuffer();
drawWeather(SUN, temperature);
u8g2.sendBuffer();
rt_thread_mdelay(5000);
status = 2;
break;
case 2:
if(RT_EOK == sht3x_read_singleshot(sht3x_device))
{
humidity = (int)sht3x_device->humidity;
}
else
{
humidity = 0;
}
u8g2.clearBuffer();
drawHumidity(RAIN, humidity);
u8g2.sendBuffer();
rt_thread_mdelay(5000);
status = 0;
break;
}
}
}
MSH_CMD_EXPORT(oled_display, oled start);
主程序如下:
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
#include <oled_display.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);
rt_wlan_config_autoreconnect(RT_TRUE);
oled_display();
while(count++)
{
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_HIGH);
rt_thread_mdelay(500);
rt_pin_write(LED_PIN, PIN_LOW);
}
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);
五、实验现象