esp32使用lvgl界面来控制四线散热风扇


参考这位同学的文章   esp8266 4线风扇调速测速 | OldGerman’s Blog

esp32是3.3v的单片机 io口可以忍受5v电平    所以如果接普通的电脑上5v的风扇 不需要电平转换,加上拉电阻就行   。我这是一个12v风扇但是用5V驱动的。所以电路偷懒了也能用。如果用12V那需要跟上边教程一样电平转换 

接线    风扇正负极接5V电源 ,测速线接13针脚,并用1k电阻上拉到5v。pwm线直接接14针脚 

#include <lvgl.h>
#include <TFT_eSPI.h>
//Ticker tick; /* timer for interrupt handler */
//代码滴答; /* 中断处理程序定时器 */
#define LVGL_TICK_PERIOD 30
#define  speed_pin 13 //使用13针来计算速度
unsigned long duration = 0;//获得脉冲的周期
#include <Ticker.h>
Ticker timer1;//声明计时任务
TFT_eSPI tft = TFT_eSPI(); /* TFT instance 显示驱动实例化*/
static lv_disp_buf_t disp_buf;
static lv_color_t buf[LV_HOR_RES_MAX * 10];
lv_obj_t * slider_label;
int screenWidth = 480;
int screenHeight = 320;
#if USE_LV_LOG != 0
/* Serial debugging 串口debug*/
void my_print(lv_log_level_t level, const char * file, uint32_t line, const char * dsc)
{
Serial.printf("%s@%d->%s/r/n", file, line, dsc);
delay(100);
}
#endif
/* Display flushing 显示内容填充*/
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint16_t c;
tft.startWrite(); /* Start new TFT transaction 开始新事务*/
tft.setAddrWindow(area->x1, area->y1, (area->x2 - area->x1 + 1), (area->y2 - area->y1 + 1)); /* set the working window 设置工作窗口*/
for (int y = area->y1; y <= area->y2; y++) {
for (int x = area->x1; x <= area->x2; x++) {
c = color_p->full;
tft.writeColor(c, 1);
color_p++;
}
}
tft.endWrite(); /* terminate TFT transaction 结束事务*/
lv_disp_flush_ready(disp); /* tell lvgl that flushing is done 告知填充结束*/
}
bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
{
uint16_t touchX, touchY;
bool touched = tft.getTouch(&touchX, &touchY, 600);
if(!touched)
{
return false;
}
if(touchX>screenWidth || touchY > screenHeight)
{
Serial.println("Y or y outside of expected parameters..");
Serial.print("y:");
Serial.print(touchX);
Serial.print(" x:");
Serial.print(touchY);
}
else
{
data->state = touched ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
/*Save the state and save the pressed coordinate*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*Set the coordinates (if released use the last pressed coordinates)*/
/*保存状态并保存按下的坐标*/
//if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
/*设置坐标(如果松开使用最后按下的坐标)*/
data->point.x = touchX;
data->point.y = touchY;
Serial.print("Data x");
Serial.println(touchX);
Serial.print("Data y");
Serial.println(touchY);
}
return false; /*Return `false` because we are not buffering and no more data to read返回 `false` 因为我们没有缓冲并且没有更多数据要读取*/
}
void printEvent(String Event, lv_event_t event)
{
Serial.print(Event);
printf(" ");
switch(event) {
case LV_EVENT_PRESSED:
printf("Pressed/n");
break;
case LV_EVENT_SHORT_CLICKED:
printf("Short clicked/n");
break;
case LV_EVENT_CLICKED:
printf("Clicked/n");
break;
case LV_EVENT_LONG_PRESSED:
printf("Long press/n");
break;
case LV_EVENT_LONG_PRESSED_REPEAT:
printf("Long press repeat/n");
break;
case LV_EVENT_RELEASED:
printf("Released/n");
break;
}
}
void slider_event_cb(lv_obj_t * slider, lv_event_t event)
{
printEvent("Slider", event);
if(event == LV_EVENT_VALUE_CHANGED) {
static char buf[4];  /* max 3 bytes  for number plus 1 null terminating byte 数字最多 3 个字节加上 1 个空终止字节*/
int pwm =   lv_slider_get_value(slider);    //获得拖动条的数值并用来设置pwm
snprintf(buf, 4, "%u", pwm); //int转换成char *
lv_label_set_text(slider_label, buf); /*Refresh the text刷新文字*/
int pwm_pin = 14;//14针脚当pwm输出
ledcSetup(0, 10000, 8);//使用0通道,频率10000,分辨率8
ledcAttachPin(pwm_pin, 0);//输出针脚跟0通道关联
ledcWrite(0, pwm);//输出pwm
}
}
lv_obj_t *label_speed_value;
void get_speed()//计算速度
{
char charPData[64];
duration  = pulseIn(speed_pin, HIGH, 9000000);//测量每次脉冲的事件 ,9000000表示9秒后如果还没有测量到就看门狗重启
if (duration != 0)//除数为0也会导致复位
{
sprintf(charPData, "%11d", 1000000/duration/2*15);//实测风扇一圈给4个脉冲,转换long到char*
lv_label_set_text(label_speed_value, charPData);//设置文本标签的值
}
}
void setup() {
Serial.begin(115200); /* prepare for possible serial debug 为可能的串行调试做准备*/
lv_init();
#if USE_LV_LOG != 0
lv_log_register_print_cb(my_print); /* register print function for debugging 注册打印功能以进行调试*/
#endif
tft.begin(); /* TFT init tft初始化*/
tft.setRotation(1);
uint16_t calData[5] = { 275, 3620, 264, 3532, 1 };
tft.setTouch(calData);
lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
/*Initialize the display初始化显示*/
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
/*Initialize the input device driver初始化输入设备*/
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver输入设备驱动器的描述符*/
indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device触摸板是一种类似指针的设备*/
indev_drv.read_cb = my_touchpad_read;      /*Set your driver function设置您的驱动程序功能*/
lv_indev_drv_register(&indev_drv);         /*Finally register the driver最终注册驱动*/
//Set the theme..设置主题
lv_theme_t * th = lv_theme_material_init(LV_THEME_DEFAULT_COLOR_PRIMARY, LV_THEME_DEFAULT_COLOR_SECONDARY, LV_THEME_DEFAULT_FLAG, LV_THEME_DEFAULT_FONT_SMALL , LV_THEME_DEFAULT_FONT_NORMAL, LV_THEME_DEFAULT_FONT_SUBTITLE, LV_THEME_DEFAULT_FONT_TITLE);     
lv_theme_set_act(th);
lv_obj_t * scr = lv_cont_create(NULL, NULL);
lv_disp_load_scr(scr);
//lv_obj_t * tv = lv_tabview_create(scr, NULL);
//lv_obj_set_size(tv, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
/* Create simple label创建label */
lv_obj_t *label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(label, "Hello Arduino! (V7.0)");
lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, -80);
/* Create a slider in the center of the display 创建silder*/
lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);
lv_obj_set_width(slider, screenWidth-90);                        /*Set the width*/
lv_obj_set_height(slider, 50);
lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0);    /*Align to the center of the parent (screen)与父组件居中对齐*/
lv_obj_set_event_cb(slider, slider_event_cb);         /*Assign an event function注册事件*/
/* Create a label below the slider slider下创建一个label用来显示silidre值也是用于输出的pwm*/
slider_label = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text(slider_label, "0");
lv_obj_set_auto_realign(slider, true);
lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
/* Create a label below the slider slider下创建一个label——pwm*/
lv_obj_t *label_PWM = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text( label_PWM, "PWM:");
lv_obj_set_auto_realign( slider, true);
lv_obj_align(label_PWM, slider, LV_ALIGN_OUT_BOTTOM_MID, -50, 10);
/* Create a label below the slider slider下创建一个label_speed*/
lv_obj_t *label_speed = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text( label_speed, "SPEED:");
lv_obj_set_auto_realign( slider, true);
lv_obj_align(label_speed, slider, LV_ALIGN_OUT_BOTTOM_MID, -50, 30);
/* Create a label below the slider slider下创建一个label_speed_value*/
label_speed_value = lv_label_create(lv_scr_act(), NULL);
lv_label_set_text( label_speed_value, "0");
lv_obj_set_auto_realign( slider, true);
lv_obj_align(label_speed_value, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 30);
timer1.attach_ms(1000, get_speed);//每隔1000毫秒调用一次get_speed函数
}
void loop() {
lv_task_handler(); /* let the GUI do its work gui开始工作*/
delay(5);
}

实验现象,,如果9秒内没有检测到脉冲单片机就复位了  

6.10 Kjp:/ 四线风扇使用触屏调整输出pwm,显示测速# esp32 # 单片机开发 https://v.douyin.com/j4EV3Pc/ 复制此链接,打开Dou音搜索,直接观看视频!

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/281915.html

(0)
上一篇 2022年8月24日
下一篇 2022年8月24日

相关推荐

发表回复

登录后才能评论