基于RT-Thread OS的 迷你时钟项目

2023-05-16

基于RT-Thread OS的 迷你时钟项目

近期在自学RT-Thread OS, 这是一个国内团队开发的实时物联网操作系统,具有组件完整丰富、高度可伸缩、简易开发等优点。
在这里插入图片描述
RTOS官网
参考学习文档

作品演示

基于RT-Thread OS的网络小时钟

实现功能:
1.联网获取时间;
2.测温测湿度;
3.将天气数据实时显示在一块OLED屏幕上。

在这里插入图片描述

主要元件

在这里插入图片描述

开发板:STM32L432KC Nucleo
Wi-Fi模块:ESP8266-01S
温湿度传感器模块:SHT31
显示屏:ssd1306 (0.96英寸)

调试工具:USB-UART串口模块

其中,UART1用于串口调试,Wi-Fi模块使用UART2,传感器和屏幕分别挂载于I²C1和I²C2

代码部分

本作品开源地址:Github仓库
参考教程:桌面mini网络时钟
参考数据手册:STM32L432KC
核心部分(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 Matt");   // 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);

学习心得

  1. RTOS的内置软件包资源非常丰富,相较于ARM mbed OS,RT软件包的数量和质量都占优势,并且中文说明能够带来很多便利;

  2. RT-Thread Studio 的高度集成化,大大减少了新手在配置环境时可能会遇到的麻烦;
    在这里插入图片描述
    在这里插入图片描述 与Mbed Studio相比,RTT Studio功能更加丰富,个人感觉界面更加友好

  3. RTT支持主流的各种STM32开发板,SDK的下载更新十分流畅(不像某绿色软件的SDK管理器:)在这里插入图片描述

  4. 唯一的小不足是编译速度会小慢一点,不过瑕不掩瑜,能够稳定运行,提供丰富功能对于一个高集成度的开发平台来说已经非常难得,相信国产会越来越好!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于RT-Thread OS的 迷你时钟项目 的相关文章

  • std::atomic_thread_fence

    在原子变量的存取上应用不同的memory order可以实现不同的内存序来达到数据同步的目的 xff0c 而在C 43 43 11及之后的标准里 xff0c 除了利用原子操作指定内存序 xff0c 还定义了单独使用 内存栅栏 xff08 s
  • 线程池为什么能维持线程不释放,随时运行各种任务?

    版权声明 本文为博主原创文章 未经博主允许不得转载 技术交流可邮 cjh94520 outlook com https blog csdn net cjh94520 article details 70545202 线程池 之前一直有这个疑
  • Python使用threading.Timer实现执行可循环的定时任务

    前言 Python中使用threading Timer执行定时任务时 执行任务是一次性的 类似于JS中的setTimeout方法 我们对其在封装 改造成可循环的定时器 类似于JS中setInterval方法的效果 值得注意的是 thread
  • CreateEvent人工重置事件对象

    include
  • CreateEvent自动重置事件对象

    include
  • ThreadLocal,看我就够了!

    ThreadLocal 开胃菜 研究过Handler的应该对ThreadLocal比较眼熟的 线程中的Handler对象就是通过ThreadLocal来存放的 初识ThreadLocal的可能被它的名字有所误导 ThreadLocal初一看
  • linux默认系统进程

    http blog chinaunix net uid 7553302 id 64864 html linux启动后 默认有以下系统进程 Init 1 Linux的第一个进程 也是其它所有进程的父进程 events 0 5 处理内核事件守护
  • Java 多线程 -- 从入门到精通

    持续更新中 欢迎收藏 关注 以便查看后续 Java 多线程 从入门到精通 Java线程与线程的区别 多线程的实现方法 Thread中start和run方法的区别 Thread和Runnable的关系 使用Callable和Future创建线
  • 线程进程协程的实现代码

    单线程 import time def run print hello world time sleep 1 if name main for i in range 5 run 多线程 import threading import tim
  • 关于CoInitialize()

    在msdn中对于CoInitialize的解释如下 Initializes the COM library on the current apartment and identifies the concurrency model as s
  • muduo1——编程风格:面向对象的编程和基于对象的编程(上)

    muduo库其实不是面向对象的编程 而是基于对象的编程 那么在进入正式的muduo源码分析之前 先来看看这两种编程风格 一 面向对象编程风格 通过对一个线程类的封装来进行讲解 Thread是一个抽象类不能实例化对象 TestThread是派
  • 分析Java线程池执行原理

    Java并发编程源码分析系列 分析Java线程池的创建 上一篇已经对线程池的创建进行了分析 了解线程池既有预设的模板 也提供多种参数支撑灵活的定制 本文将会围绕线程池的生命周期 分析线程池执行任务的过程 线程池状态 首先认识两个贯穿线程池代
  • 笔试题10:Runnable接口与Thread类的区别?

    1 线程类继承自Thread则不能继承自其它类 而Runnable接口可以 2 线程类继承自Thread相对于Runnable来说 使用线程的方法更方便一些 3 实现Runnable接口的线程类的多个线程 可以更方便的访问同一变量 而Thr
  • log4net使用

    说明 本程序演示如何利用log4net记录程序日志信息 log4net是一个功能著名的开源日志记录组件 利用log4net可以方便地将日志信息记录到文件 控制台 Windows事件日志和数据库 包括MS SQL Server Access
  • 关于RT-Thread中优先级翻转问题的简记

    最近在学习RT Thread的相关知识 记录一下心得 优先级翻转 是指当一个高优先级线程试图通过信号量机制访问共享资源时 如果该信号量已被低优先级线程持有 而这个低优先级线程在运行过程中可能又被其他一些中等优先级的线程抢占 从而造成高优先级
  • 使用org.apache.tools.zip包操作文件

    import java io import org apache tools zip import java util Enumeration 功能 zip压缩 解压 支持中文文件名 说明 本程序通过使用Apache Ant里提供的zip工
  • CreateRemoteThread的使用(转载)

    先解释一下远程进程 其实就是要植入你的代码的进程 相对于你的工作进程 如果叫本地进程的话 它就叫远程进程 可理解为宿主 首先介绍一下我们的主要工具CreateRemoteThread 这里先将函数原型简单介绍以下 CreateRemoteT
  • 一、使用interrupt()中断线程

    当一个线程运行时 另一个线程可以调用对应的Thread对象的interrupt 方法来中断它 该方法只是在目标线程中设置一个标志 表示它已经被中断 并立即返回 这里需要注意的是 如果只是单纯的调用interrupt 方法 线程并没有实际被中
  • 多线程之创建工作者线程和用户界面线程区别

    转帖 部分原创 1 工作者线程倾向于琐碎的处理 与它不同的是 用户界面线程具有自己的界面而且实际上类似于运行其他应用程序 创建线程而不是其他应用程序的好处是线程可与应用程序共享程序空间 这样可以简化线程与应用程序共享数据的功能 2 典型情况
  • QT实现多线程,以及子线程调用主线程方法与变量

    实现思路 第一步需要将子线程声明为主线程的友元类 第二步是将主线程类对象的地址通过信号槽传递给子线程中创建的对象 使得子线程能访问主线程的数据的 1 子线程 displayresult h 头文件 伪代码 include tabwindow

随机推荐

  • ubuntu的不同版本

    ubuntu是现在最流行的Linux安装包 xff0c 本文介绍了ubuntu的各种版本 一 Ubuntu 每个ubuntu的版本都包含一个版本号 xff08 version number xff09 和一个代码名 xff08 code n
  • Linux下通过service服务管理用户进程

    文章目录 一 service配置介绍1 1 service配置文件1 2 配置文件的区块1 3 修改配置文件后重启1 4 服务管理 二 设计一个可执行程序三 设计一个service管理 home ubuntu test servicetes
  • c++中多态调用场景下基类析构函数的virtual声明

    文章目录 一 基类析构函数未加virtual声明的情况1 1 基础示例演示1 2 进阶示例演示 二 基类析构函数添加virtual声明的情况三 总结 一 基类析构函数未加virtual声明的情况 在多态场景中 xff0c 可通过基类的指针指
  • protobuf协议原理及实现,基于c++

    文章目录 一 protobuf协议简介1 1 protobuf协议简介1 2 数据交互xml json protobuf格式比较1 3 关于 ProtoBuf 的一些思考 二 protobuf库安装三 protobuf库使用第一步 xff0
  • OLED显示屏驱动:8080并口,IIC,SPI三种驱动方式

    本文介绍了对OLED的几种驱动方式 xff0c 8080并口 xff0c IIC xff0c SPI三种驱动方式 xff0c 采用的单片机是STM32F407 文章目录 一 OLED驱动原理介绍二 8080并口驱动方式三 IIC驱动方式四
  • ROS2学习笔记(1)ROS2+docker的配置方法

    ROS2学习笔记 xff08 1 xff09 ros2 43 docker的配置方法 1 前言2 安装docker2 1 docker的发展史2 2 什么是docker2 3 docker的思想2 3 1 集装箱2 3 2 标准化1 运输方
  • ubuntu之更改ubuntu和windows双系统启动顺序

    ubuntu之更改ubuntu和windows双系统启动顺序 背景方法 背景 安装好ubuntu和windows双系统后 xff0c 一般grub引导默认选择第一个为启动项 xff0c 在公司打工还好 xff0c 毕竟要进ubuntu挣钱
  • 【lightDM】组件理解

    前言 LightDM xff08 Light Display Manager xff09 是轻量级 Linux 桌面显示管理器 其目的是成为 X org 的 X Server 的标准显示管理器 LightDM 负责启动 X servers
  • 【机器人学中的状态估计】第一讲

    1 什么是状态估计 xff1f 通过获得传感器的观测值 xff0c 建立观测值到状态量的模型 xff0c 估计出状态量 2 概率密度函数 后验概率 p x y
  • VScode环境下使用git与github远程操作要点记录

    部分内容来源于网络 xff0c 外加了自己的实践 xff0c 记录了一下 文章目录 一 windows上使用git1 官网下载git https git scm com download win 2 创建本地仓库 二 git远程连接gith
  • 【千律】C++基础:TXT文件的创建、写入和读取

    include lt fstream gt include lt iostream gt using namespace std int main 初始化 ifstream iread txt 初始化输入流 ofstream write t
  • Matlab计算福利彩票的中奖概率

    Quez1 计算福彩双色球一等奖的中奖概率 福彩双色球的玩法如下 从编号1 33的红球里任选6个 另外在编号1 16的蓝球里再任选1个 如果选择的红球和蓝球和当期的开奖结果完全一致 顺序可不同 则中一等奖 Analysis 这是一个组合问题
  • 【千律】OpenCV基础:基于梯度的模板匹配

    环境 xff1a Python3 8 和 OpenCV 内容 xff1a 基于梯度的模板匹配 主要关注边缘信息 xff0c 能够较好的识别不同颜色的目标 实现步骤 xff1a 1 给定原图像I和模板T 2 指定差异度 xff08 相似度 x
  • golang使用SM2(SM2withSM3)签名、验签数据

    golang使用SM2签名 验签数据 场景标准密钥签名算法 Start依赖公钥转base64私钥转hex私钥生成公钥生成密钥对Hex私钥转私钥对象base64公钥转公钥对象签名验签 测试 场景 对接招行支付 标准 密钥 私钥 xff1a H
  • 树莓派与pixhawk串口通信

    一 Pixhawk部分 1 读取数据测试 步骤 xff1a 在Firmware src modules中添加一个新的文件夹 xff0c 命名为rw uart在rw uart文件夹中创建CMakeLists txt文件 xff0c 并输入以下
  • 关于pixhawk波特率修改的两种方法

    一 QGC地面站修改 将pixhawk与地面站相连接进入参数设置界面 xff0c 搜索SYS COMPANION参数设置需要的波特率保存设置 二 终端 xff08 Terminal xff09 修改 打开终端 xff0c 进入源码所在Fir
  • gazebo仿真环境搭建

    主要内容 xff1a 安装gazebo配置gazebo运行gazebomavros控制飞机 1安装gazebo 如果已经安装MAVROS可以直接在终端上输入gazebo查看是否已经拥有gazebo xff0c 因为MAVROS中含有gaze
  • Intel Realsense D435i标定详细步骤

    主要介绍Inter D435i深度相机的IMU 相机和IMU与相机外参数标定的过程 其中 IMU使用的是realsense官方文档的教程 相机和外参数使用的是Kalibr的标定方法 本文所介绍过程的所有代码和生成文件资源放在Kalibr工具
  • 在Ubuntu、NVIDIA_TX2下查看CPU/GPU/内存使用率

    一 Ubuntu 1 cpu 内存 1 使用top命令 top 2 更直观的工具htop sudo apt get install htop htop 2 gpu 用nivida smi命令 xff0c nvidia smi 这个命令只能显
  • 基于RT-Thread OS的 迷你时钟项目

    基于RT Thread OS的 迷你时钟项目 近期在自学RT Thread OS 这是一个国内团队开发的实时物联网操作系统 xff0c 具有组件完整丰富 高度可伸缩 简易开发等优点 RTOS官网 参考学习文档 作品演示 基于RT Threa