Miniclock -- desktop network small clock based on RT thread OS

Posted by Entanio on Sun, 23 Jan 2022 16:42:15 +0100

Recently, I was interested in the Internet of things and had the honor to contact RT thread OS after learning:

RT thread is an open source real-time operating system developed by the Chinese team. It is not only a real-time kernel, but also an operating system with complete functions. It has the advantages of modular development, rich community resources and easy for beginners.

For this reason, the author developed the desktop network Miniclock project according to RT thread studio.

1, Video presentation:

Desktop network small clock - Open Source Project Based on RT thread

2, Realize function

1. Obtain the temperature and humidity information of the equipment area

2. Get the current time information online

3. Display current time information and temperature and humidity (OLED)

III. component equipment

Development board: STM32L432KC NUCLEO

Temperature and humidity sensor: SHT31 (connected to development board I2C3)

WIFI module: atk-esp8266-v1 3 (connect the development board UART2)

OLED display module: SSD 1306(0.96 inch) (connected to development board I2C1)

Debugging module: atk-usb-uart-v1 2 (UART1 serial port debugging)

4, Main Codes

1.main.c function code

#include <rtthread.h>
#include<drv_soft_i2c.h>
#include<arpa/inet.h>
#include<netdev.h>
#include<ntp.h>

#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

int sh31_ccollcet(void);

int main(void)
{
    LOG_D("HELLO!");
    //Get network card object
    struct netdev* net = netdev_get_by_name("esp0");
    //Blocking determines whether the current network is connected normally
    while(netdev_is_internet_up(net) != 1)
    {
       rt_thread_mdelay(200);
    }
    //Prompt that the current network is ready
                                                        //rt_kprintf("network is ok!\n");
    //NTP automatic timing
    time_t cur_time;
    cur_time = ntp_sync_to_rtc(NULL);
    if (cur_time)
    {
        rt_kprintf("Cur Time: %s", ctime((const time_t*) &cur_time));
    }
    else
    {
        rt_kprintf("NTP sync fail.\n");
    }


    return RT_EOK;
}

2.OLED display module control code

#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                    9   // PA9
#define OLED_I2C_PIN_SDA                    10  // PA10

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 Erith");   // write something to the internal memory
    u8g2.sendBuffer();

    sht3x_device_t  sht3x_device;
    sht3x_device = sht3x_init("i2c3", 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);

5, Learning experience

1. Environment construction: the environment construction of RT thread studio is extremely simple. Compared with Mbed online compiler and MbedOS, the construction options of RT thread studio are very simple.

2. Rich software packages; Visual package configuration

RT thread studio has a domestic software package community, in which the number and types of software packages are very rich, which greatly improves the efficiency of novices in building the project environment.

3. The network supports MDK download, and there is no need to find the corresponding development board configuration on the network

4. One deficiency

Personally, I think the description of console error reporting is slightly vague, which improves the efficiency of debug ging less; Secondly, the compilation speed of the software needs to be improved.

As an embedded real-time operating system of the Internet of things developed by the domestic team, I think it can be comparable to the old school of MbedOS and other systems in foreign countries. I wish the domestic software industry is booming!

This learning work has been open source, open source platform: Githib

Reference learning tutorial: RT thread studio project practical tutorial | quickly create a desktop mini network clock

Reference data manual: datasheet-STM32L432KC

Topics: Embedded system