2023寒假一起练 用 ESP32 WiFi 实现二级菜单显示在OLDE显示屏
一 . ESP32-S2 WiFi硬件介绍
ESP32-S2 WiFi模块是物联网、可穿戴电子设备和智能家居等应用场景的理想选择,另搭配输入控制、输出显示以及传感器感知和控制的套件,使其功能更加完善。
该模块板载了:
- ESP32-S2-MINI-1模组
- 这是一款2.4 GHz WiFi 模组
- 内置 ESP32S2 系列芯片,Xtensa® 单核 32 位 LX7 微处理器
- 内置芯片叠封 4 MB flash,可叠封 2 MB PSRAM
- 37 个 GPIO,具有丰富的外设
- 板载 PCB 天线
配套的ESP32 S2 开发板除了ESP32wifi模组之外还集成了USB TYPE -C接口,两个按键,一个电源指示灯,一个用户LED灯,2排10pin的排针,将重要IO引出。使用USB供电或通过排针3.3V供电。
ESP32-S2 是一款高度集成、高性价比、低功耗、主打安全的单核 Wi-Fi SoC,具备强大的功能和丰富的 IO 接口。使用乐鑫ESP-IF开发环境,也可以使用arduino编程,。ESP32-S2 WiFi模块如图1.1所示。
图1.1
同时该平台还提供了搭配数字系统的输入、输出扩展板,该模块包括
- 按键、旋转编码器输入 - 以模拟信号的方式
- 双电位计控制输入 - 以数字信号的方式
- RGB三色LED显示
- 1.44寸128*128 LCD,SPI总线访问
- MMA7660三轴姿态传感器
- 电阻加热
- 温度传感器
- 与MSP430 Launch Pad开发板的接口
- 与ESP32-S2核心模块的接口
示意图如图1.2所示
图1.2
二.开发环境搭建
1.ESP32的开发环境的开发环境主要有乐鑫ESP-IF开发环境,arduino和MicroPython环境,这里使用的是arduino开发环境,开发环境的搭建参考了官方文档Getting Started — Arduino-ESP32 2.0.6 documentation。
2.在arduino官网安装arduino。
3.库文件的安装,打开 Arduino IDE,选择 文件
->首选项
->设置
如图2.1所示
图2.1
4.将https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/arduino/package_m5stack_index.json复制到附加开发板管理器。
5.选择 工具
->开发板:
->开发板管理器...
在新弹出的对话框中,输入并搜索 ESP32
,点击安装
6.选择 工具
->开发板:
->ESP32
, 根据我们所使用的设备(EPS32
)选择对应的开发板配置。
三.任务说明
我这里选择的是项目1详细内容如下
项目1 - 通过IO扩展板上的按键和旋转编码器控制并实现菜单功能
- IO扩展板上的1个按键和旋转编码器的3个输入端口是通过R-2R电阻网络的方式连接在一起,生成一个模拟电压量。按下任何一个按键都会改变这个模拟电压量的值。
- IO扩展板上的LCD屏幕为128*128分辨率的1.44寸彩色屏幕,通过SPI总线进行访问
要求:本任务需要通过ESP32核心板的ADC监测IO板模拟输出管脚的变化,判断哪一个按键或编码器的旋转发生了变化,进而控制1.44寸LCD屏幕的菜单显示,要求实现主菜单和至少二级菜单。
所需器件:
-
ESP32-S2 WiFi模块简介一套
- 搭配数字系统的输入、输出扩展板
-
连接模块之间的杜邦线
1.由于要驱动编码器和遥感模块,查看了数字系统的输入、输出扩展板原理图如图3.1所示编码器部分是一个权电阻网络,连接到ESP32的adc模块,通过改变每一位权重电阻的接地与否改变adc的值,可以通过程序判断出那个按键被按下,和编码器的旋转方向,摇杆部分是通过4个运放搭建了一个输出pwm的模块,通过测量pwm的频率和占空比可以判断出遥感所在位置是,比如上下左右中的某个位置。
图3.1
程序部分使用了ESP32的一个adc模块和一个测量pwm的模块,一共使用了两个引脚,详细程序如下。
void changeISR()
{
auto now=micros();
if(digitalRead(pwm_pin))//现在是高电平
{
portENTER_CRITICAL_ISR(&mux);//加锁
auto total=now-raiseTime;
fre=1e6/(double)total;
auto h=fallTime-raiseTime;
duty=h/(double)total;
portEXIT_CRITICAL_ISR(&mux);
raiseTime=now;
}
else
{
fallTime=now;
}
}
//遥感方向判断函数
//0无动作1左2右3上4下
int Rocker(void)
{
portENTER_CRITICAL(&mux);
double f=fre;
double d=duty;
portEXIT_CRITICAL(&mux);
//遥感判断
if(f>=290&&f<=300&&d>=0.5&&d<=0.6)
{
return 0;
}
else if(f>=220&&f<=230&&d>=0.5&&d<=0.6)
{
return 1;
}
else if(f>=410&&f<=420&&d>=0.5&&d<=0.6)
{
return 2;
}
else if(f>=290&&f<=300&&d>=0.3&&d<=0.4)
{
return 3;
}
else if(f>=290&&f<=300&&d>=0.7&&d<=0.9)
{
return 4;
}
return 0;
}
const int adc_cankao=2400;
int key_1()
{
int adc_value=analogReadMilliVolts(1);
delay(5);
int adc_value_1=analogReadMilliVolts(1);
if(adc_value-adc_value_1>1200)
{
return 2;
}
else if(adc_value-adc_value_1>300&&adc_value-adc_value_1<600)
{
return 1;
}
else if(adc_value-adc_value_1>100&&adc_value-adc_value_1<200)
{
int i=0;
int count=1;
while(i<=10)
{
i++;
int first=analogReadMilliVolts(1);
delay(5);
int second=analogReadMilliVolts(1);//Filter();
if((first-second)>100||(first-second)<-100)
{
count++;
}
}
if(count>=4&&count<=5)
{
return 3;
}
else if(count>5)
{
return 4;
}
}
else
{
return 0;
}
}
2.LCD的驱动显示部分,查看了LCD与ESP32模块连接的引脚的原理图,包括5个引脚,为 TFT_CS 13引脚TFT_RST 18引脚TFT_DC 17引脚TFT_MOSI 21引脚TFT_SCLK 41引脚,从引脚的命名可以看出使用的是spi的协议,这里使用的是一块128*128LCD屏幕使用了TFT_eSPI的库进行开发,首先修改了库文件里用于驱动LCD模块的程序,使其可以驱动这块LCD模块。然后进行编写一个二级菜单,通过编码器和按键来进行菜单的选择,一级菜单包括一个ADC选项和Rocker选项,使用编码器可以选择不同的选项,ADC选项下是一个二级菜单实时显示ADC采集的值。Rocker选项实时显示当前摇杆所处的位置(up,down,left,rigth)详细程序如下.
unsigned char key_value=0;//键盘值
//定义按键结构体
typedef struct
{
unsigned char index;
unsigned char up;
unsigned char down;
unsigned char left;
unsigned char right;
void(*operation)(void);
} Rocker_Table;
unsigned char funIndex=0;//菜单索引
//定义一个函数指针
void(*current)(void);
//4个菜单
void menu11(void);
void menu12(void);
void menu21(void);
void menu22(void);
//定义按键操作数据
Rocker_Table table[4]=
{
{0,0,1,0,2,(*menu11)},
{1,0,1,1,3,(*menu12)},
{2,2,2,0,2,(*menu21)},
{3,3,3,1,3,(*menu22)},
};
//一级菜单
void menu11(void)
{
//tft.fillScreen(TFT_BLACK);
tft.setCursor(10,20,2);//设置初始坐标和字体大小
tft.println("MENU");
tft.setCursor(20,40);
tft.println("->1.keyboard");
tft.setCursor(20,60);
tft.println("2.Rocker");
// tft.fillScreen(TFT_BLACK);
}
void menu12(void)
{
// tft.fillScreen(TFT_BLACK);
tft.setCursor(10,20,2);//设置初始坐标和字体大小
tft.println("MENU");
tft.setCursor(20,40);
tft.println("1.keyboard");
tft.setCursor(20,60);
tft.println("->2.Rocker");
//tft.fillScreen(TFT_BLACK);
}
void menu21(void)
{
//tft.fillScreen(TFT_BLACK);
tft.setCursor(10,20,2);//设置初始坐标和字体大小
tft.println("ADC: ");
tft.setCursor(20,40);
int analogVolts = analogReadMilliVolts(1);
tft.println(analogVolts);
//tft.fillScreen(TFT_BLACK);
}
void menu22(void)
{
tft.setCursor(10,20,2);//设置初始坐标和字体大小
tft.println("Rocker: ");
tft.setCursor(20,40);
int R = Rocker();
switch(R)
{
case 1:
tft.setTextPadding(128);
tft.drawString("left",60,20,2);break;
case 2:
tft.setTextPadding(128);
tft.drawString("right",60,20,2);break;
case 3:
tft.setTextPadding(128);
tft.drawString("up",60,20,2);break;
case 4:
tft.setTextPadding(128);
tft.drawString("under",60,20,2);break;
default:tft.drawString("middle",60,20,2);break;
}
}
五.结果与总结
4.1结果
板子连接上电脑后,打开arduino软件,把程序下载到ESP32中,通过旋转编码器进行菜单的选择,一级菜单有两个选项,ADC和ROCKER,按下按钮可以进入ADC的二级菜单,可以实时的看到ADC 采集的值,或者进入Rocker的菜单,可以摇动遥杆模块,可以看到摇杆所处的方位显示在显示屏上(left,rigth,up,down),详细演示在视频里。
4.2总结
很高兴参加硬禾学堂举办的寒假一起练的活动,学习了ESP32的在arduino平台下的软件开发流程,以及摇杆和编码器驱动程序的编写,同时更加熟悉了arduino的使用。