项目介绍
IO扩展板上有三轴加速度传感器,读出传感器的数值显示在屏幕上,并且板子上有RGB彩灯,使用三轴加速度控制彩灯出现不同颜色,手持板子转到不同方位彩灯颜色跟随变化。在板子静置30秒后,彩灯规律周期变化。
设计思路
通过IIC总线定时读取三轴加速度传感器的数据,通过SPI输出到128*128的LCD显示屏上去,判断当前三轴加速度传感器的数据是哪一个轴的绝对值最大,再判断这个轴数据的正负,得到当前板子朝向,当检测到当前板子朝向一直没变化时,就进入彩灯规律变化模式。
MMA7660支持输出6位数字值,用户可配置输出数据的传输速率,还支持中断引脚(INT)识别传感器的数据变化、产品的朝向和姿态等,不过本次设计只需要用到加速度读取功能,为了简化设计,使用轮询的方式实现了这一次的功能,在Arduino里面有用户提供了对应操作的库,可以使用这个库直接对其读取,MMA7660的库使用Wire这个库作为IIC操作的接口,因此可以使用Wire的接口去初始化使用的IIC接口。
扩展板板载了一块.44寸128*128的LCD彩屏,通过SPI进行控制,其显示控制芯片是ST7735,属于一颗应用很广泛的显示控制芯片,在Arduino里面有许多可以使用的显示库。选取一个配置即可。
对于前六面状态,只是固定显示某一种颜色,可以判断到对应面,然后去切换灯到对应的状态,但是对于放置30s后要求灯颜色循环就不能这么操作了,可以考虑使用加速度中断的方式进行实现,主循环一直控制灯变化,也可用定时器中断定时去操作灯变化。这次为了简单,就使用了一直轮询的方式进行操作,主循环按照一定时间去运行,每500ms循环一次,每一次都去读加速度的值与操作灯变化,通过对主循环进行计数得到当前运行的时间。
程序流程图
硬件介绍
1、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开发环境,我们可以通过USB对其编程,作为带wifi的MCU单独使用,也可以烧录AT固件,作为WiFi透传模块与RP2040游戏机套件结合使用。
2、平台含有:
- ESP32 WiFI模块 x1
- 输入、输出扩展板 x1
- Type-C数据线 x1
3、输入、输出扩展板介绍:
本扩展板包含如下功能:
- 按键、旋转编码器输入 - 以模拟信号的方式
- 双电位计控制输入 - 以数字信号的方式
- RGB三色LED显示
- 1.44寸128*128 LCD,SPI总线访问
- MMA7660三轴姿态传感器
- 电阻加热
- 温度传感器
- 与ESP32-S2核心模块的接口
环境搭建
开发环境选择
对于ESP32系列模块,主流的开发环境有三种:ESP-IDF,PlatformIO,Arduino。
为了简单省事,最终选用了Arduino作为本次的开发平台。
安装程序库
MMA7660驱动库
TFT_eSPI驱动库
根据屏幕驱动来修改库文件中的User_Setup.h文件,库里面内置了很多种屏幕的驱动,具体可以到TFT_Drivers目录下查看。
主要代码
TFT_eSPI配置
#define USER_SETUP_INFO "User_Setup"
#define ST7735_DRIVER // Define additional parameters below for this display
#define TFT_WIDTH 128
#define TFT_HEIGHT 128
#define ST7735_GREENTAB
#define TFT_INVERSION_OFF
#define TFT_MOSI 21 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 41
#define TFT_CS 13 // Chip select control pin
#define TFT_DC 17 // Data Command control pin
#define TFT_RST 18 // Reset pin (could connect to Arduino RESET pin)
#define LOAD_GLCD // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2 // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4 // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6 // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7 // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8 // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
#define SMOOTH_FONT
#define SPI_FREQUENCY 27000000
#define SPI_READ_FREQUENCY 20000000
#define SPI_TOUCH_FREQUENCY 2500000
主循环
accelemeter.getAcceleration(&ax,&ay,&az);
abs_ax = abs(ax);
abs_ay = abs(ay);
abs_az = abs(az);
if((abs_ax > abs_ay) && (abs_ax > abs_az))
{
if(ax < 0) acc_direction = 1;
else acc_direction = 4;
}
else if((abs_ay > abs_ax) && (abs_ay > abs_az))
{
if(ay < 0) acc_direction = 2;
else acc_direction = 5;
}
else
{
if(az < 0) acc_direction = 3;
else acc_direction = 6;
}
count_time++;
if(acc_direction != dis_acc_direction)
{
count_time = 0;
dis_acc_direction = acc_direction;
led_control(acc_direction);
}
if(count_time >= 60)
{
led_control(0);
}
tft.setCursor(0,10);
tft.print("ax=");
tft.print(ax);
tft.println(" ");
tft.print("ay=");
tft.print(ay);
tft.println(" ");
tft.print("az=");
tft.print(az);
tft.println(" ");
delay(500);
LED控制
void led_control(int8_t led_mode)
{
static int8_t voluntarily_mode = 0;
if(led_mode == 0)
{
led_mode = voluntarily_mode;
voluntarily_mode++;
if(voluntarily_mode >= 7)
voluntarily_mode = 0;
}
switch(led_mode)
{
case 1: digitalWrite(LED1, LOW); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); break;
case 2: digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW); digitalWrite(LED3, HIGH); break;
case 3: digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, LOW); break;
case 4: digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, HIGH); break;
case 5: digitalWrite(LED1, LOW); digitalWrite(LED2, HIGH); digitalWrite(LED3, LOW); break;
case 6: digitalWrite(LED1, HIGH); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); break;
case 7: digitalWrite(LED1, LOW); digitalWrite(LED2, LOW); digitalWrite(LED3, LOW); break;
default: digitalWrite(LED1, HIGH); digitalWrite(LED2, HIGH); digitalWrite(LED3, HIGH); break;
}
}
实现的功能及图片展示
显示加速度值
不同方向彩灯颜色不同
静置30秒后,彩灯颜色周期性变化
遇到的主要难题及解决方法
问题:刷新效果差,闪烁严重
方法:不清屏,显示时多加几个空格,覆盖刷新
未来的计划或建议
搭建尝试乐鑫官方提供的开发环境,将这个项目移植到官方环境下。
建议加热电路可以直接在硬件上关闭,或者将其改进为一个外部模块,以免操作不注意时烫伤手。