ESP32-C5连载系列之透明LED你有我也有
之前在社区看到大佬发的集中点屏让我突然想起以前积分兑换的1.5inch 透明OLED屏幕,这次正好趁着ESP32-C5开箱测试也尝试点亮一下,写点儿好玩儿的显示在上面。看看是否能够实现和MPU6050的梦幻联动。产品还不便宜呢。。哈哈
官方的说明:这是一块带转接板的1.51”透明单色屏幕,分辨率为128x64(完全透明的区域分辨率为128*56,在靠近排线侧有一小块区域不能完全透明,但可显示),显示颜色为蓝色,全视角显示。尺寸小巧的转接板提供了GDI接口和SPI排针两种接线方式,为用户留有足够的使用和发挥的空间。DFRobot还提供了多样化的显示例程,能满足用户的大部分基础显示需求
规格:
[*]工作电压:3.3V
[*]视角方向:全视角
[*]驱动芯片:SSD1309
[*]转接板接口类型:SPI,GDI
[*]转接板尺寸:18mm*28mm
[*]显示区域:35mm*15mm
[*]显示颜色:蓝色
[*]像素间距:0.274mm*0.274mm
[*]透明显示屏屏幕尺寸:42mm*27mm
[*]工作温度:-40~70℃
尺寸和合适DIY,之前想着有空再画个3D模型,做到驴车上,作为一个资深的牛马,一直没时间折腾自己的爱好,不知道屏幕前的你是不是和我一样。
实际上会占用很多的引脚:
ESP32-C5与OLED连接:根据DFRobot的GDI 1.51寸透明OLED的接口定义,使用FPC线将其与ESP32-C5的GDI接口相连,具体引脚对应关系如下:
VCC接ESP32-C5的3V3
BLK接ESP32-C5的15/D13
GND接ESP32-C5的GND
SCLK接ESP32-C5的23/SCLK
MOSI接ESP32-C5的24/MOSI
MISO接ESP32-C5的25/MISO
DC接ESP32-C5的8/D2
RES接ESP32-C5的26/D3
CS接ESP32-C5的27/D6
SCL接ESP32-C5的10/SCL
SDA接ESP32-C5的9/SDA
这些信息有了,再加上官方的wiki就很nice,代码世界一大抄,不抄袭不成佛哈哈,给个链接防止新手迷失在丛林~
https://wiki.dfrobot.com.cn/SKU_DFR0934_Fermion_1.51''_128x64_OLED_Transparent_Display_with_Converter_Breakout
官方接线图和我的接线图对比一下,真实感还是不错的吧~
最终效果还不错,什么?你问我MPU6050 怎么接?去看我之前的帖子,就四根线, 哦不,5根线就好了,走I2C协议,记得int引脚也控制起来哈哈
还是一并写了吧,免得你找不到帖子了。
MPU6050---ESP32-C5 IO板
VCC ------ 3v3
GND ------- GND
SCL -------- 10/C
SDA----------9/D
AD0----------GND
INT ---------- 2
接好就行。等线接好了,接下来就开始安装库,写代码(抄AI) 然后添加一丢丢创意就好了哈哈
官方wiki使用的是U8g2lib,所以我也得安装一下。哈哈
1. 先创建一个sketch再说。
arduino-cli sketch new esp32c5_oled_mpu6050
cdesp32c5_oled_mpu6050/
# 编辑文档
vim esp32c5_oled_mpu6050.ino2. 测试一下屏幕,哎,这个得先安装一下u8g2lib库,这个好像比较帅。。
# 查询一下
arduino-cli lib search u8g2
# 安装一下 这个U得大写哈
arduino-cli lib install U8g2
瞬间搞定
然后要注意的是需要根据这个官方提供的GDI的pinout来修改初始化代码的信息:
初始化代码引脚信息需要改一下:
参考这个,我下面代码定义了一些宏变量,方便修改。
然后写个测试代码看看屏幕是否能用:
<blockquote>#include <Arduino.h>
火速编译上传看效果:arduino-cli compile -b esp32:esp32:esp32c5:CDCOnBoot=cdc -p /dev/ttyACM0 --upload
每次打这么长的代码你肯定不爽,但是可以用alias命令直接设置成一个超级简答的命令,编辑一下你用户属主目录下的.bashrc 文件,添加:
alias upcode='arduino-cli compile -b esp32:esp32:esp32c5:CDCOnBoot=cdc -p /dev/ttyACM0 --upload' 以后就直接输入:upcode命令就可以编译和上传了,舒服了~
然后屏幕没问题了,就可以添加mpu6050的消息了。
我就直接post代码了,如下:
#include <Arduino.h>
#include <U8g2lib.h>
#include <Wire.h>
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include <SPI.h>
#define INTERRUPT_PIN2
#define SDA_PIN 9
#define SCL_PIN 10
#define OLED_DC8 // GPIO 8
#define OLED_CS27 // GPIO 27
#define OLED_RST 26 // GPIO 26
#define OLED_CLK 23 // clock 23
#define OLED_DATA 24 // data 24
U8G2_SSD1309_128X64_NONAME2_F_4W_SW_SPI u8g2(
/*rotation=*/U8G2_R0,
/*clock=*/OLED_CLK,
/*data */OLED_DATA,
/*cs=*/ OLED_CS,
/*dc=*/ OLED_DC,
/*reset=*/ OLED_RST);
MPU6050 mpu;
volatile bool mpuInterrupt = false;
bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint8_t fifoBuffer;
Quaternion q;
VectorFloat gravity;
float ypr;//
void IRAM_ATTR dmpDataReady() {
mpuInterrupt = true;
}
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
Wire.setClock(100000);
u8g2.begin();
u8g2.setFontPosTop();
mpu.initialize();
if (!mpu.testConnection()) {
Serial.println("MPU6050连接失败!");
while (1);
}
devStatus = mpu.dmpInitialize();
if (devStatus != 0) {
Serial.printf("DMP初始化失败,状态码: %d\n", devStatus);
while (1);
}
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788);
mpu.CalibrateAccel(6);
mpu.CalibrateGyro(6);
mpu.setDMPEnabled(true);
pinMode(INTERRUPT_PIN, INPUT);
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
dmpReady = true;
packetSize = mpu.dmpGetFIFOPacketSize();
}
void loop() {
if (!dmpReady) return;
uint16_t fifoCount = mpu.getFIFOCount();
if (!mpuInterrupt && fifoCount < packetSize) return;
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
fifoCount = mpu.getFIFOCount();
if((mpuIntStatus & 0x10) || fifoCount == 1024){
mpu.resetFIFO();
Serial.println("DAMN, FIFO特喵的溢出了!");
return;
}
if (mpuIntStatus & 0x02) {
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
mpu.getFIFOBytes(fifoBuffer, packetSize);
fifoCount -= packetSize;
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
// 计算圆心位置
int circleX = 64 + (int)(ypr * 180 / M_PI) * 2; // 根据俯仰角调整 X 位置
int circleY = 32 - (int)(ypr * 180 / M_PI) * 2; // 根据偏航角调整 Y 位置
// 限制圆的位置在屏幕范围内
circleX = constrain(circleX, 0, 123);
circleY = constrain(circleY, 0, 58);
// 清屏并绘制新的圆
u8g2.firstPage();
do {
u8g2.drawCircle(64, 32, 1); //绘制半径5的圆形
u8g2.drawCircle(64, 32, 3); //绘制半径5的圆形
u8g2.drawCircle(64, 32, 7); //绘制半径5的圆形
u8g2.drawCircle(circleX, circleY, 5); //绘制半径5的圆形
} while (u8g2.nextPage());
Serial.print("YAW: ");
Serial.print(ypr * 180 /M_PI);
Serial.print("\tPITCH: ");
Serial.print(ypr * 180 /M_PI);
Serial.print("\tROLL: ");
Serial.println(ypr * 180 /M_PI);
}
}
然后编译上传后,就看手稳不稳了,稳定就可以fire in the hole了哈哈
视频如下:
https://www.bilibili.com/video/BV19xsVzuEkj/?vd_source=bdff96c7413b9836f4a9c717176dc2da
哈哈,面对疾风吧~
页:
[1]