基于RT-Thread系统的迷你时钟

基于RT-Thread系统的迷你时钟

项目目标

通过OLED显示屏显示时间与温湿度的基本功能。

准备工作

软件

RT-Thread Studio v2.1.0
I2C设备驱动(用于读取温湿度传感器)
sht3X软件包(使用sht30进行温湿度测量)
at_device软件包(使用esp8266wifi模块进行网络连接)
netutils软件包(用于获取NTP时间)
u8g2软件包(驱动OLED显示)
cpp组件(支持u8g2软件包)
在这里插入图片描述

硬件

小熊派开发板
ESP8266
sht30温湿度传感器
OLED

项目开发

IIC设置

打开IIC设置
在这里插入图片描述
设置为与sht31传感器相连的引脚
在这里插入图片描述

温湿度测量

sht30使用方法:首先进行init初始化,调用sht3x_read_singleshot函数读取传感器的采集信息,其返回6字节数组
1[温度高八位]

2[温度第八位]

3[温度crc校验]

4[湿度高八位]

5[湿度第八位]

6[湿度crc校验]

以下为读取数据的函数

rt_err_t sht3x_read_singleshot(sht3x_device_t dev)
{
    rt_uint8_t temp[6] ;
    rt_err_t result;
    RT_ASSERT(dev);

    result = rt_mutex_take(dev->lock, RT_WAITING_FOREVER);
    if (result == RT_EOK)
    {
        if( write_cmd(dev, dev->cmd_readout) == RT_EOK)
        {
			// wait about 5 ms
			rt_thread_mdelay(5);
            if(read_bytes(dev, temp, 6) == RT_EOK){
                if(crc8(temp, 2) == temp[2]){
                    dev->temperature = -45.0 + (temp[1] | temp[0] << 8) * 175.0 / (0xFFFF - 1) ; //sensor temperature convert to reality
                    result = RT_EOK ;
                }else{
                    result = -RT_ERROR ;
                }
                if(crc8(temp + 3, 2) == temp[5]){
                    dev->humidity = (temp[4] | temp[3] << 8) * 0.0015259022 ; //sensor humidity convert to reality
                }else{
                    result = -RT_ERROR ;
                }
            }else
            {
                result = -RT_ERROR ;
            }
        }
        else
        {
            result = -RT_ERROR ;
        }
	rt_mutex_release(dev->lock);
    }
    else
    {
        LOG_E("Taking mutex of SHT3x failed.");
        result = -RT_ERROR;
    }
	
    return result;
}

在终端输入以下指令即可通过串口显示温湿度值

sht3x probe i2c2 pd   //根据实际连接的引脚选择正确的iic总线
sht3x read

在这里插入图片描述

获取时间

打开at_device详细配置,配置如下
SSID 和密码即为所连接wifi名称与密码
在这里插入图片描述

我们需要手动开启lpusart1串口,在boar.h文件中添加如下定义
在这里插入图片描述
编译下载即可在控制台访问网络

打开软件模拟RTP和at_device详细配置,使能NTP
在这里插入图片描述
控制台发送指令即可获取当前时间

ntp_sync	

在这里插入图片描述

OLED显示时间与温湿度

打开ugg2软件包详细配置,使能IIC OLED,如下图
在这里插入图片描述
打开ssd1306_12864_sw_i2c_example.cpp文件,修改相应的引脚
在这里插入图片描述
编译下载,在控制台输入ssd1306_12864_sw_i2c_example进行测试
正常显示后即可关闭该实例文件。

然后编写函数将得到的时间与温湿度数据通过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);

最后在main.c文件中调用 oled_display()函数
代码如下


int main(void)
{
   //获取网卡对象
	struct netdev* net = netdev_get_by_name("esp0");

	//阻塞判断当前网络是否正常连接
	while(netdev_is_internet_up(net) != 1)
	{
   		rt_thread_mdelay(200);
	}
	//NTP自动对时
	time_t cur_time;
	cur_time = ntp_sync_to_rtc(NULL);



    oled_display();

}




结果展示

在这里插入图片描述
在这里插入图片描述

https://blog.csdn.net/Mculover666/article/details/104428132

参考文献

https://www.rt-thread.org/document/site/#/development-tools/rtthread-studio/applications/project-collection/project-collection

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值