之前在社区看到大佬发的集中点屏让我突然想起以前积分兑换的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
- cd esp32c5_oled_mpu6050/
-
- # 编辑文档
- vim esp32c5_oled_mpu6050.ino
复制代码
2. 测试一下屏幕,哎,这个得先安装一下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_PIN 2
- #define SDA_PIN 9
- #define SCL_PIN 10
-
- #define OLED_DC 8 // GPIO 8
- #define OLED_CS 27 // 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[64];
-
- Quaternion q;
- VectorFloat gravity;
- float ypr[3]; // [yaw, pitch, roll]
-
- 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[1] * 180 / M_PI) * 2; // 根据俯仰角调整 X 位置
- int circleY = 32 - (int)(ypr[0] * 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[0] * 180 /M_PI);
- Serial.print("\tPITCH: ");
- Serial.print(ypr[1] * 180 /M_PI);
- Serial.print("\tROLL: ");
- Serial.println(ypr[2] * 180 /M_PI);
- }
- }
-
复制代码
然后编译上传后,就看手稳不稳了,稳定就可以fire in the hole了哈哈

视频如下:
哈哈,面对疾风吧~
|