esp32笔记[12]-使用串口屏显示时间和温湿度

摘要

使用esp32驱动陶晶驰串口屏显示NTP时间和温湿度信息.

关键信息

  • 开发环境:Arduino IDE

原理简介

NTP时间源简介

[https://www.bdsytime.com/baike/6165.html]
 NTP(Network Time Protocol)时间服务器是一种网络设备,用于提供准确的时间同步服务。它的作用是在计算机网络中确保各个设备的时间保持同步,从而保证网络中的数据传输、日志记录等操作能够准确地进行。
NTP时间服务器可以连接到可靠的时间源,如GPS卫星、原子钟等,通过接收这些时间源的信号,并将其传输给其他设备,为整个网络提供准确的时间源服务。这对于没有直接访问可靠时间源的设备来说尤为重要,因为它们可以通过连接到NTP时间服务器,从而获得准确的时间信息。

组态串口屏

[https://www.elecfans.com/emb/danpianji/202302212013881.html]
很早以前,工业现场有时需要HMI,为工作人员提供便捷的操作环境,但不同的应用现场有不同的操作界面,有组态软件经验的厂商就想到了用嵌入式板卡跑WinCE的方案,这样很容易将Windows中的代码移植过来,用户只需要在Windows端的组态工具根据现场应用进行组态,然后将生产的工程文件,对象文件,数据库等文件下载到WinCE对应的板卡中即可实现所见即所得的显示开发过程。

串口屏对比LVGL开发

[https://whycan.com/t_9350.html]
[https://www.elecfans.com/emb/danpianji/202302212013881.html]
串口屏是一种带有串口的显示设备,它可以通过PC端设计屏幕显示界面,并通过串口修改屏幕显示内容。串口屏的核心功能是显示,显示的数据源来自串口的对端设备。串口屏的价格通常较低,但其串口通常是协议的从设备,一般仅支持一种协议,用户需要通过外部MCU作为串口的主,并实现相关协议去修改显示画面的数据内容。

LVGL是一个开源的、轻量级的图形库,它可以用来创建各种类型的图形界面,包括但不限于仪表盘、状态栏、菜单、列表等。LVGL提供了丰富的图形元素和布局选项,使得开发者可以轻松地设计和实现复杂的用户界面。LVGL可以与各种微控制器(MCU)和操作系统(OS)集成,使其成为嵌入式系统开发的一个非常有用的工具。

在某些情况下,例如需要自定义的用户界面或者需要支持多种协议的场景,LVGL可能更适合。然而,如果预算有限,或者只需要基本的显示功能,那么串口屏可能是更好的选择。

实现

核心代码

/*
硬件:
- esp32-c3
- dht11
- 陶晶驰串口屏
连接:
- dht11_dat:io13
- usb_d-:io18
- usb_d+:io19
- rs485_rx:uart0_tx
- rs485_tx:uart0_rx
- led_d4:io12(high)
- led_d5:io13
- tjc_rx:io0
- tjc_tx:io1
依赖库:
- DHT sensor library
*/

/* start 引入 */
#include <stdio.h>
#include "DHT.h"
#include <DHT_U.h>
#include <WiFi.h>
#include "time.h" // 时间相关
#include "sntp.h" // 时间相关
/* end 引入 */

/* start 全局变量 */
const int led_d4_pin = 12;
const int tjc_rx_pin = 0;
const int tjc_tx_pin = 1;
const int dht11_dat_pin = 13;

// DHT11
#define DHTTYPE DHT11
uint32_t g_delay_ms;
sensor_t g_sensor;
sensors_event_t g_event;

// WIFI
const char* g_wifi_ssid       = "wifi";
const char* g_wifi_password   = "wifi";

// 时间NTP相关
const char* g_ntp_server1 = "ntp.aliyun.com";
const char* g_ntp_server2 = "stdtime.gov.hk";
const char* g_time_zone = "CST-8";  // TimeZone rule for China Standard Time (UTC+8)
/* end 全局变量 */

/* start 函数原型 */
void timeAvailable(struct timeval *t);
void printLocalTime(void);
void printDHT11(void);
/* end 函数原型 */

/* start 自定义类 */
class tjcScreen {
private:
  Stream& serial;

public:
  tjcScreen(Stream& s) : serial(s) {
    // serial.begin(115200);
  }

  // 封装结束符并写入串口屏
  void write(const char* command) {
    serial.print(command);
    serial.write(0xFF);
    serial.write(0xFF);
    serial.write(0xFF);
  }

  // t12
  void set_version(const char* version) {
    char command[30];
    snprintf(command, sizeof(command), "t12.txt=\"%s\"", version);
    write(command);
  }

  // t17
  void set_humidity(const char* humidity) {
    char command[30];
    snprintf(command, sizeof(command), "t17.txt=\"%s\"", humidity);
    write(command);
  }

  // t15
  void set_temperature(const char* temperature) {
    char command[30];
    snprintf(command, sizeof(command), "t15.txt=\"%s\"", temperature);
    write(command);
  }

  // t13
  void set_power_input(const char* power) {
    char command[30];
    snprintf(command, sizeof(command), "t13.txt=\"%s\"", power);
    write(command);
  }
  
  // t14
  void set_power_output(const char* power) {
    char command[30];
    snprintf(command, sizeof(command), "t14.txt=\"%s\"", power);
    write(command);
  }

  // t19
  void set_power_total(const char* power) {
    char command[30];
    snprintf(command, sizeof(command), "t19.txt=\"%s\"", power);
    write(command);
  }

  // t5
  void set_time(const char* time) {
    char command[40];
    // 2024-1-31 19:20:21
    snprintf(command, sizeof(command), "t5.txt=\"%s\"", time);
    write(command);

  }

  // t8
  void set_connection_status(const char* status) {
    char command[32];
    snprintf(command, sizeof(command), "t8.txt=\"%s\"", status);
    write(command);
  }
};
/* end 自定义类 */

/* start 头部声明 */
DHT_Unified g_dht(dht11_dat_pin, DHTTYPE);
tjcScreen g_screen(Serial1);
/* end 头部声明 */

/* start 主函数 */
void setup(){
  Serial.begin(115200);
  Serial.println(F("DHT11 test!"));

  pinMode(dht11_dat_pin,INPUT);
  digitalWrite(dht11_dat_pin,LOW);
  pinMode(led_d4_pin,OUTPUT);

  // 初始化DHT11
  g_dht.begin();
  g_dht.temperature().getSensor(&g_sensor);
  g_dht.humidity().getSensor(&g_sensor);
  g_delay_ms = g_sensor.min_delay / 1000;
  g_dht.temperature().getEvent(&g_event);
  g_dht.humidity().getEvent(&g_event);

  // 初始化串口屏
  // begin(unsigned long baud, uint32_t config = SERIAL_8N1, int8_t rxPin = -1, int8_t txPin = -1, bool invert = false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112) -> void
  Serial1.begin(115200,SERIAL_8N1,tjc_tx_pin,tjc_rx_pin);

  // 初始化USB

  // 初始化WIFI
  WiFi.begin(g_wifi_ssid, g_wifi_password);
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print("wifi connecting...\n");
  }
  Serial.println("wifi connected.");

  // 初始化NTP服务器
  sntp_set_time_sync_notification_cb(timeAvailable); // 配置时间获取回调
  configTzTime(g_time_zone, g_ntp_server1, g_ntp_server2);
  
}

void loop(){
  delay(1000);
  // 翻转led_d4电平
  auto flipLevel = [](int pin) {
      int currentLevel = digitalRead(pin); // 读取当前引脚的状态
      int newLevel = !currentLevel; // 计算相反的电平
      digitalWrite(pin, newLevel); // 设置引脚为新的电平
  };
  flipLevel(led_d4_pin); // 调用lambda函数翻转电平

  // 获取DHT11数据
  printDHT11();

  // NTP打印本地时间
  printLocalTime(); // 同步需要一些时间

}
/* end 主函数 */

/* start 函数本体 */

// 打印本地时间
void printLocalTime(void){
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%Y-%m-%d %H:%M:%S");

  // 更新显示屏
  char s_time[40];
  // 2024-1-31 19:20:21
  strftime(s_time, sizeof(s_time), "%Y-%m-%d %H:%M:%S", &timeinfo);
  g_screen.set_time(s_time);
}

// 时间获取回调
void timeAvailable(struct timeval *t){
  Serial.println("Got time adjustment from NTP!");
  printLocalTime();
}

// 打印DHT11数据
void printDHT11(void){
  String s_message;
  g_dht.temperature().getEvent(&g_event);
  s_message += String(g_event.temperature);
  s_message += "°C;";
  // 更新显示屏
  g_screen.set_temperature(String(g_event.temperature).c_str());
  g_dht.humidity().getEvent(&g_event);
  s_message += String(g_event.relative_humidity);
  s_message += "%;";
  Serial.println(s_message);
  // 更新显示屏
  g_screen.set_humidity(String(g_event.relative_humidity).c_str());
}
/* end 函数本体 */

效果

显示温湿度和时间
posted @ 2024-02-01 21:22  qsBye  阅读(60)  评论(0编辑  收藏  举报