合宙ESP32-C3 arduino lvgl8.3 Squarelin_studio 开发体验 (一个温湿度监控屏幕)

目录

先看最终效果

材料准备 

 使用squarelin_studio 创建ui界面

 项目创建

 放置控件与修改控件样式

使用自己准备的字体

 导出项目的UI文件与创建示例工程

 修改配置文件

打开arduino文件修改代码

选择开发板与端口编译运行!


先看最终效果

使用 squarelin_studio 开发ui界面直观,美观,体验很不错,接下来开始这个demo的制作。

材料准备 

合宙esp32开发板

tft屏幕模块 SPI接口 (文中使用的为1.8'128x160) 驱动芯片为st7735s

dht11 温湿度传感器一个

 使用squarelin_studio 创建ui界面

下载与安装 squarelin_studio 的过程省略,自行完成。

 项目创建

 创建项目时选择arduino平台,将使用tft_espi 模块驱动lvgl项目。

具体选择如下图所示,项目地址等设置好,根据自身所有的屏幕模块的素质进行相关设置之后点击创建按钮。

 

 放置控件与修改控件样式

 直接使用拖拽的方式将控件元素拖拽到页面上,包括按钮,文本,输入框,图片等等。

 可以直接对组件的各种属性进行设置。

 

综上所述,按照自己的需求摆放控件位置,对控件样式进行设置,不同选项的效果一试便知,最终达到自己心仪的效果即可。

这里不讨论添加事件与动画,可以查看其它文章。

使用自己准备的字体

默认的可选字体并不丰富,我们可以自己添加创建字体,参考字体的创建,自己添加图片等资源的操作也是类似的。 在底部的 assets 选项卡下点击 add file into assets 按钮将自己下载好的字体文件添加进来。

 点击右侧选项卡的 Font Manager 选项卡。

 创建字体名称,选择添加进来的字体文件,字体大小等设置之后点击创建即可。

 此时字体就可以使用了,选择一个文本控件找到属性里字体相关设置,将其字体设置为我们自己创建的字体即可。

 

 导出项目的UI文件与创建示例工程

当我们已经将界面设置的符合自己的要求之后可以直接使用软件导出ui文件也一块使用软件直接创建一个demo。

这里我两个都导出直接使用。 

选择好你要导出的文件位置,导出结束之后打开。

导出项目之后再点击导出UI文件之后它会自动在ui文件夹中更新。

主文件夹中一个是存放所需库的libreries 文件夹,一个是ui文件夹,它包括arduino文件和一些其它生成的ui文件。

库文件夹内容如下 

tft_espi lvgl 为导出项目时自动创建,adafruit_sensor-master dth-sensor-library-master,为接下来驱动温湿度传感器的库。

下面的文章中提供了下载链接。

Arduino DHT11温湿度传感器模块的使用(安装对应库和代码)_arduino温湿度传感器代码_赴遥的博客-CSDN博客

 修改配置文件

现在仍然无法正确的驱动屏幕,需要对tft_espi 和 lvgl 的配置文件进行修改。

tft_espi 中,设置你的屏幕所使用的驱动,屏幕的规格,屏幕对应SPI的引脚信息等,这部分可以自行搜索参考其它文章。

修改 \libraries\TFT_eSPI 下的 User_Setup.h

选择对应的驱动

// Only define one driver, the other ones must be commented out
//#define ILI9341_DRIVER       // Generic driver for common displays
//#define ILI9341_2_DRIVER     // Alternative ILI9341 driver, see https://github.com/Bodmer/TFT_eSPI/issues/1172
#define ST7735_DRIVER      // Define additional parameters below for this display
//#define ILI9163_DRIVER     // Define additional parameters below for this display
//#define S6D02A1_DRIVER

选择屏幕规格

// For ST7789, ST7735, ILI9163 and GC9A01 ONLY, define the pixel width and height in portrait orientation
// #define TFT_WIDTH  80
#define TFT_WIDTH  128
// #define TFT_WIDTH  172 // ST7789 172 x 320
// #define TFT_WIDTH  240 // ST7789 240 x 240 and 240 x 320
#define TFT_HEIGHT 160
// #define TFT_HEIGHT 128

屏幕的颜色 

 #define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue
// #define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red

定义引脚

// The hardware SPI can be mapped to any pins

#define TFT_MOSI 3 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 2
#define TFT_CS   7 // Chip select control pin
#define TFT_DC   6  // Data Command control pin
#define TFT_RST  10  // Reset pin (could connect to Arduino RESET pin)
#define TFT_BL   11  // LED back-light

将 lvgl/lv_conf_template.h 复制到 lvgl 同级目录下,并将其重命名为 lv_conf.h 。 打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

LV_TICK_CUSTOM 设置为 1

打开arduino文件修改代码

现在可以打开arduino文件并对代码进行修改添加温湿度传感器的部分。

下面是温湿度传感器的demo 将引脚修改为你的实际引脚。

#include <DHT.h>

// 定义传感器引脚
#define DHTPIN 2

// 传感器类型为DHT11
#define DHTTYPE DHT11

// 创建DHT对象
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  // 初始化串口通信
  Serial.begin(9600);
  Serial.println("DHT11 温湿度传感器测试");
  
  // 初始化DHT传感器
  dht.begin();
}

void loop() {
  // 读取温湿度值
  float temperature = dht.readTemperature();
  float humidity = dht.readHumidity();
  
  // 检查是否成功读取温湿度值
  if (isnan(temperature) || isnan(humidity)) {
    Serial.println("无法读取温湿度值!");
    return;
  }
  
  // 打印温湿度值
  Serial.print("温度:");
  Serial.print(temperature);
  Serial.print(" °C\t");
  Serial.print("湿度:");
  Serial.print(humidity);
  Serial.println(" %");

  delay(2000); // 间隔2秒钟进行下一次读取
}

添加到生成的arduino文件中。

#include <DHT.h>
#include <lvgl.h>
#include <TFT_eSPI.h>
#include "ui.h"
#include <stdio.h>
#include <string.h>

// 定义传感器引脚
#define DHTPIN 8
// 传感器类型为DHT11
#define DHTTYPE DHT11

// 创建DHT对象
DHT dht(DHTPIN, DHTTYPE);

/*If you want to use the LVGL examples,
  make sure to install the lv_examples Arduino library
  and uncomment the following line.
#include <lv_examples.h>
*/

/*Change to your screen resolution*/
static const uint16_t screenWidth  = 128;
static const uint16_t screenHeight = 160;

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[ screenWidth * screenHeight / 10 ];

TFT_eSPI tft = TFT_eSPI(screenWidth, screenHeight); /* TFT instance */

#if LV_USE_LOG != 0
/* Serial debugging */
void my_print(const char * buf)
{
    Serial.printf(buf);
    Serial.flush();
}
#endif

/* Display flushing */
void my_disp_flush( lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p )
{
    uint32_t w = ( area->x2 - area->x1 + 1 );
    uint32_t h = ( area->y2 - area->y1 + 1 );

    tft.startWrite();
    tft.setAddrWindow( area->x1, area->y1, w, h );
    tft.pushColors( ( uint16_t * )&color_p->full, w * h, true );
    tft.endWrite();

    lv_disp_flush_ready( disp );
}

/*Read the touchpad*/
void my_touchpad_read( lv_indev_drv_t * indev_driver, lv_indev_data_t * data )
{
    uint16_t touchX = 0, touchY = 0;

    bool touched = false;//tft.getTouch( &touchX, &touchY, 600 );

    if( !touched )
    {
        data->state = LV_INDEV_STATE_REL;
    }
    else
    {
        data->state = LV_INDEV_STATE_PR;

        /*Set the coordinates*/
        data->point.x = touchX;
        data->point.y = touchY;

        Serial.print( "Data x " );
        Serial.println( touchX );

        Serial.print( "Data y " );
        Serial.println( touchY );
    }
}

void setup()
{
    Serial.begin( 115200 ); /* prepare for possible serial debug */

    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.println( LVGL_Arduino );
    Serial.println("DHT11 温湿度传感器测试");
    // 初始化DHT传感器
    dht.begin();

    lv_init();

#if LV_USE_LOG != 0
    lv_log_register_print_cb( my_print ); /* register print function for debugging */
#endif

    tft.begin();          /* TFT init */
    tft.setRotation( 0 ); /* Landscape orientation, flipped */

    lv_disp_draw_buf_init( &draw_buf, buf, NULL, screenWidth * screenHeight / 10 );

    /*Initialize the display*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init( &disp_drv );
    /*Change the following line to your display resolution*/
    disp_drv.hor_res = screenWidth;
    disp_drv.ver_res = screenHeight;
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.draw_buf = &draw_buf;
    lv_disp_drv_register( &disp_drv );

    /*Initialize the (dummy) input device driver*/
    static lv_indev_drv_t indev_drv;
    lv_indev_drv_init( &indev_drv );
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read_cb = my_touchpad_read;
    lv_indev_drv_register( &indev_drv );


    ui_init();

    Serial.println( "Setup done" );
}

void loop()
{
    // 读取温湿度值
   int temperature = (int)dht.readTemperature();
   int humidity = (int)dht.readHumidity();
     // 检查是否成功读取温湿度值
   if (isnan(temperature) || isnan(humidity)) {
     Serial.println("无法读取温湿度值!");
     return;
   }

    // 打印温湿度值
    Serial.print("温度:");
    Serial.print(temperature);
    Serial.print(" °C\t");
    Serial.print("湿度:");
    Serial.print(humidity);
    Serial.println(" %");

    lv_arc_set_value(ui_ta, temperature);
    char temperchar[10];
    sprintf(temperchar,"%d",temperature);
    lv_label_set_text(ui_tnumber, temperchar);

    lv_arc_set_value(ui_ha, humidity);
    char humiditychar[10];
    sprintf(humiditychar,"%d",humidity);
    lv_label_set_text(ui_hnumber, humiditychar);

    lv_timer_handler(); /* let the GUI do its work */
    delay(5);
}

读取到的数据更新到ui上只需要使用lvgl自带的函数。

例如下面将读取到的温湿度数据更新到 arc类型控件 ta,label类型控件tnumber 上。

lv_arc_set_value(ui_ta, temperature);
    char temperchar[10];
    sprintf(temperchar,"%d",temperature);
    lv_label_set_text(ui_tnumber, temperchar);

    lv_arc_set_value(ui_ha, humidity);
    char humiditychar[10];
    sprintf(humiditychar,"%d",humidity);
    lv_label_set_text(ui_hnumber, humiditychar);

选择开发板与端口编译运行!

欢迎交流 。

  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
ESP32-C3定时器开发文档 ESP32-C3是一款低功耗、高性能的Wi-Fi和蓝牙双模SoC,它集成了多个定时器,可以用于各种应用场景,如PWM控制、定时中断、计时等。本文将介绍ESP32-C3定时器的使用方法。 一、ESP32-C3定时器的类型 ESP32-C3有四种类型的定时器,分别为:通用定时器、高精度定时器、看门狗定时器、RTC定时器。 1.通用定时器 ESP32-C3有两个通用定时器,可以用于PWM控制、定时中断、计时等。这两个定时器分别为定时器0和定时器1,每个定时器有16位的自由运行计数器和一个16位的比较器。通用定时器的主要特点如下: - 可以配置为定时器或计数器 - 支持自由运行计数器和比较器 - 支持自动重载计数器 - 支持PWM输出 - 支持定时中断 2.高精度定时器 ESP32-C3一个高精度定时器,可以用于需要高精度计时的应用场景。这个定时器是单向计时器,可以自由设置计时周期和定时中断时间。高精度定时器的主要特点如下: - 可以设置自由运行计数器的计数周期 - 可以设置定时中断时间 - 支持单向计时模式 - 支持自动重载计数器 3.看门狗定时器 ESP32-C3一个看门狗定时器,可以用于应用程序中的异常保护。当应用程序出现异常时,看门狗定时器会自动重启系统。看门狗定时器的主要特点如下: - 可以设置看门狗定时器的计数周期 - 支持看门狗定时器中断 - 支持自动重载计数器 4.RTC定时器 ESP32-C3一个RTC定时器,可以用于实时时钟应用。RTC定时器的主要特点如下: - 可以设置RTC计数器的计数周期 - 支持RTC定时器中断 - 支持自动重载计数器 二、ESP32-C3定时器的使用步骤 1.初始化定时器 在使用定时器前,需要先初始化定时器。以定时器0为例,初始化代码如下: // 配置定时器0的参数 timer_config_t timer_cfg = { .divider = 16, // 定时器分频系数 .counter_dir = TIMER_COUNT_UP, // 定时器计数器方向 .counter_en = TIMER_PAUSE, // 定时器计数器是否启动 .alarm_en = TIMER_ALARM_EN, // 定时器报警是否启动 .auto_reload = TIMER_AUTORELOAD_EN, // 定时器是否自动重载 .counter_bit_width = TIMER_DATA_WIDTH_16BIT, // 定时器计数器位宽 .alarm_value = 10000, // 定时器报警值 }; // 初始化定时器0 timer_init(TIMER_GROUP_0, TIMER_0, &timer_cfg); 2.启动定时器 初始化定时器后,需要启动定时器才能开始计时。以定时器0为例,启动代码如下: timer_start(TIMER_GROUP_0, TIMER_0); 3.设置定时器中断 如果需要在定时器到达一定时间后触发中断,则需要设置定时器中断。以定时器0为例,设置中断代码如下: // 配置定时器0中断参数 timer_isr_t isr_cfg = { .func = timer0_isr, // 定时器中断处理函数 .arg = NULL, // 中断处理函数参数 }; // 注册定时器0中断 timer_isr_register(TIMER_GROUP_0, TIMER_0, &isr_cfg, NULL, 0); 4.停止定时器 如果需要停止定时器,则可以使用以下代码: timer_pause(TIMER_GROUP_0, TIMER_0); 5.重启定时器 如果定时器已经停止,则可以使用以下代码重启定时器: timer_start(TIMER_GROUP_0, TIMER_0); 6.设置定时器报警值 如果需要定时器到达一定时间后触发报警,则需要设置定时器报警值。以定时器0为例,设置报警值代码如下: timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, 20000); 7.获取定时器计数器值 如果需要获取定时器的计数器值,则可以使用以下代码: uint64_t timer_value; timer_get_counter_value(TIMER_GROUP_0, TIMER_0, &timer_value); 8.清除定时器中断标志 当定时器中断被触发后,需要清除中断标志才能继续触发中断。以定时器0为例,清除中断标志代码如下: timer_group_clr_intr_status(TIMER_GROUP_0, TIMER_0); 三、ESP32-C3定时器应用示例 以下是一个使用定时器0实现PWM输出的示例代码: #include "driver/timer.h" #define LED_PIN 2 #define PWM_FREQ 1000 #define PWM_MAX_DUTY 1023 void timer0_isr(void *arg) { timer_group_clr_intr_status(TIMER_GROUP_0, TIMER_0); static uint32_t pwm_count = 0; static uint16_t pwm_duty = 0; pwm_count++; if (pwm_count >= (1000000 / PWM_FREQ)) { pwm_count = 0; pwm_duty++; if (pwm_duty > PWM_MAX_DUTY) { pwm_duty = 0; } timer_set_alarm_value(TIMER_GROUP_0, TIMER_0, (1000000 / PWM_FREQ)); timer_set_counter_value(TIMER_GROUP_0, TIMER_0, 0); ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, pwm_duty); ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0); } } void app_main() { // 初始化LED gpio_pad_select_gpio(LED_PIN); gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT); gpio_set_level(LED_PIN, 0); // 配置定时器0的参数 timer_config_t timer_cfg = { .divider = 16, // 定时器分频系数 .counter_dir = TIMER_COUNT_UP, // 定时器计数器方向 .counter_en = TIMER_PAUSE, // 定时器计数器是否启动 .alarm_en = TIMER_ALARM_EN, // 定时器报警是否启动 .auto_reload = TIMER_AUTORELOAD_EN, // 定时器是否自动重载 .counter_bit_width = TIMER_DATA_WIDTH_16BIT, // 定时器计数器位宽 .alarm_value = (1000000 / PWM_FREQ), // 定时器报警值 }; // 初始化定时器0 timer_init(TIMER_GROUP_0, TIMER_0, &timer_cfg); // 注册定时器0中断 timer_isr_t isr_cfg = { .func = timer0_isr, // 定时器中断处理函数 .arg = NULL, // 中断处理函数参数 }; timer_isr_register(TIMER_GROUP_0, TIMER_0, &isr_cfg, NULL, 0); // 设置PWM输出 ledc_timer_config_t ledc_timer_cfg = { .duty_resolution = LEDC_TIMER_10_BIT, // PWM位宽 .freq_hz = PWM_FREQ, // PWM频率 .speed_mode = LEDC_LOW_SPEED_MODE, // PWM速度模式 .timer_num = LEDC_TIMER_0, // PWM定时器号 .clk_cfg = LEDC_AUTO_CLK, // PWM时钟配置 }; ledc_timer_config(&ledc_timer_cfg); ledc_channel_config_t ledc_channel_cfg = { .channel = LEDC_CHANNEL_0, // PWM通道号 .duty = 0, // PWM占空比 .gpio_num = LED_PIN, // PWM输出引脚 .speed_mode = LEDC_LOW_SPEED_MODE, // PWM速度模式 .timer_sel = LEDC_TIMER_0, // PWM定时器号 }; ledc_channel_config(&ledc_channel_cfg); ledc_fade_func_install(0); // 启动定时器0 timer_start(TIMER_GROUP_0, TIMER_0); }
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值