基于FireBeetle 2 ESP32-C5的常用模块测试
本帖最后由 azhu 于 2025-10-11 15:57 编辑基于FireBeetle 2 ESP32-C5的常用模块测试前言: 本来是想要做一个陀螺仪/摇杆控制舵机的例程,在测试过程中,有好几个模块想要测试一下,结果就有了本期帖子。0.96oled(iic)屏幕接触测温模块MLX90614(iic)陀螺仪MPU6050/MPU6650(iic)
舵机云台MG90S(PWM)
一、0.96oled(iic)屏幕介绍:规格参数:工作电压:3.3V工作电流:9MA模块尺寸:27.3 x 27.8 MM像素大小:128(H) x 64(V)RGB驱动芯片:SSD1306通信协议:IIC管脚数量:4 Pin(2.54mm间距排针)
前期准备:对于0.96oled屏幕再arduino环境中只需要安装SSD1306Wir库即可。实验结果:
参考代码:
#include <Wire.h>
#include "SSD1306Wire.h"//导入0.96寸屏幕显示库
// 使用Wire库初始化OLED显示器
SSD1306Wire display(0x3c, 9, 10); // 三个参数分别是 器件地址, SDA引脚, SCL引脚
//画线
void drawLines()
{
for (int16_t i = 0; i < display.getWidth(); i += 4)
{
display.drawLine(0, 0, i, display.getHeight() - 1);
display.display();
delay(10);
}
for (int16_t i = 0; i < display.getHeight(); i += 4)
{
display.drawLine(0, 0, display.getWidth() - 1, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i = 0; i < display.getWidth(); i += 4)
{
display.drawLine(0, display.getHeight() - 1, i, 0);
display.display();
delay(10);
}
for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4)
{
display.drawLine(0, display.getHeight() - 1, display.getWidth() - 1, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i = display.getWidth() - 1; i >= 0; i -= 4)
{
display.drawLine(display.getWidth() - 1, display.getHeight() - 1, i, 0);
display.display();
delay(10);
}
for (int16_t i = display.getHeight() - 1; i >= 0; i -= 4)
{
display.drawLine(display.getWidth() - 1, display.getHeight() - 1, 0, i);
display.display();
delay(10);
}
delay(250);
display.clear();
for (int16_t i = 0; i < display.getHeight(); i += 4)
{
display.drawLine(display.getWidth() - 1, 0, 0, i);
display.display();
delay(10);
}
for (int16_t i = 0; i < display.getWidth(); i += 4)
{
display.drawLine(display.getWidth() - 1, 0, i, display.getHeight() - 1);
display.display();
delay(10);
}
delay(250);
}
//画矩形
void drawRect(void)
{
for (int16_t i = 0; i < display.getHeight() / 2; i += 2)
{
display.drawRect(i, i, display.getWidth() - 2 * i, display.getHeight() - 2 * i);
display.display();
delay(10);
}
}
//画填充矩形
void fillRect(void)
{
uint8_t color = 1;
for (int16_t i = 0; i < display.getHeight() / 2; i += 3)
{
display.setColor((color % 2 == 0) ? BLACK : WHITE); // alternate colors
display.fillRect(i, i, display.getWidth() - i * 2, display.getHeight() - i * 2);
display.display();
delay(10);
color++;
}
// Reset back to WHITE
display.setColor(WHITE);
}
// 画圆
void drawCircle(void)
{
for (int16_t i = 0; i < display.getHeight(); i += 2)
{
display.drawCircle(display.getWidth() / 2, display.getHeight() / 2, i);
display.display();
delay(10);
}
delay(1000);
display.clear();
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000001);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000011);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00000111);
display.display();
delay(200);
display.drawCircleQuads(display.getWidth() / 2, display.getHeight() / 2, display.getHeight() / 4, 0b00001111);
display.display();
}
void printBuffer(void)
{
// 初始化日志缓冲区
// 分配内存来存储8行文本,每行30个字符。
display.setLogBuffer(5, 30);
// 测试内容
const char* test[] =
{
"Hello",
"World" ,
"----",
"Show off",
"how",
"the log buffer",
"is",
"working.",
"Even",
"scrolling is",
"working"
};
for (uint8_t i = 0; i < 11; i++)
{
//清屏
display.clear();
//打印到屏幕并且换行
display.println(test);
// 将其绘制到内部屏幕缓冲区
display.drawLogBuffer(0, 0);
// 把它显示在屏幕上
display.display();
delay(500);
}
}
void setup()
{
//初始化屏幕
display.init();
//设置对比度
display.setContrast(255);
}
void loop() {
// put your main code here, to run repeatedly:
//画线测试
drawLines();
delay(1000);
//清屏
display.clear();
//画矩形测试
drawRect();
delay(1000);
//清屏
display.clear();
//画填充矩形测试
fillRect();
delay(1000);
//清屏
display.clear();
//画圆测试
drawCircle();
delay(1000);
display.clear();
//显示文本测试
printBuffer();
delay(1000);
display.clear();
}
二、无接触测温模块MLX90614(iic)介绍: MLX90614 系列模块是一组通用的红外测温模块。在出厂前该模块已进行校验及线性化,具有非接触、体积小、精度高,成本低等优点。被测目标温度和环境温度能通过单通道输出,并有两种输出接口,适合于汽车空调、室内暖气、家用电器、手持设备以及医疗设备应用等。测温方式可分为接触式和非接触式,接触式测温只能测量被测物体与测温传感器达到热平衡后的温度,所以响应时间长,且极易受环境温度的影响;而红外测温是根据被测物体的红外辐射能量来确定物体的温度,不与被测物体接触,具有影响动被测物体温度分布场,温度分辨率高、响应速度快、测温范围广、不受测温上限的限制、稳定性好等特点,所以我们选择mlx90614来作为红外测温模块。 单片机与mlx90614红外测温模块之间通信的方式是“类IIC”通信,意思就是通信方式跟IIC通信方式很像但又不是IIC,它有另外一个名字叫做SMBus。SMBus (System Management Bus)是 1995 年由 intel 公司提出的一种高效同步串行总线,SMBus 只有两根信号线:双向数据线和时钟信号线,容许 CPU 与各种外围接口器件以串行方式进行通信、交换信息,即可以提高传输速度也可以减小器件的资源占用,另外即使在没有SMBus 接口的单片机上也可利用软件进行模拟。前期准备: 该模块的通信的方式是“类IIC”通信,所以我们需要安装相关库Adafruit_MLX90614,之后的引脚连接与其他iic设备相同,在我的实验中oled屏幕与MLX90614使用同一组接口。SDA引脚、与SCL引脚分别为9、10引脚。 设备可以读取四种数据分别为环境温度、物体温度的摄氏温度、华氏温度。在实验结果中显示为四行。实验结果:
参考代码:#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_MLX90614.h>
// OLED屏幕参数
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// MLX90614传感器
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
void setup() {
// 初始化SDA和SCL引脚
pinMode(9, INPUT_PULLUP); // SDA引脚
pinMode(10, INPUT_PULLUP); // SCL引脚
Serial.begin(9600);
Serial.println("Adafruit MLX90614 test");
// 初始化I2C通信,指定SDA和SCL引脚
Wire.begin(9, 10);
// 初始化OLED屏幕
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
// 初始化MLX90614传感器
if (!mlx.begin()) {
Serial.println("MLX90614 初始化失败");
while (1);
}
}
void loop() {
// 读取温度数据
float ambientTempC = mlx.readAmbientTempC();
float objectTempC = mlx.readObjectTempC();
float ambientTempF = mlx.readAmbientTempF();
float objectTempF = mlx.readObjectTempF();
// 显示数据到OLED屏幕
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
display.print("hjwd: ");
display.print(ambientTempC);
display.print("C");
display.setCursor(0, 20);
display.print("wtwd: ");
display.print(objectTempC);
display.print("C");
display.setCursor(0, 30);
display.print("hjwd: ");
display.print(ambientTempF);
display.print("F");
display.setCursor(0, 40);
display.print("wtwd: ");
display.print(objectTempF);
display.print("F");
display.display();
// 串口打印数据
Serial.print("环境温度 = ");
Serial.print(ambientTempC);
Serial.print("℃\t");
Serial.print("物体温度 = ");
Serial.print(objectTempC);
Serial.println("℃");
Serial.print("环境温度 = ");
Serial.print(ambientTempF);
Serial.print("℉\t");
Serial.print("物体温度 = ");
Serial.print(objectTempF);
Serial.println("℉");
Serial.println();
delay(500);
}注: 在使用无接触测温模块的时候我对ESP32_C5的模组进行了温度测量,温度大概与环境持平,相差大概0.5摄氏度,具体结果如下:三、陀螺仪MPU6050/MPU6650(iic)介绍: MPU6050 是 InvenSense 公司推出的整合性 6 轴运动处理组件,其内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个IIC 接口, 可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor) 硬件加速引擎,通过主 IIC 接口,向应用端输出完整的 9 轴融合演算数据。 InvenSense 公司提供了一套基于DMP的运动处理驱动库,可大大降低单片机对动处理运算的负荷,同时也大大降低了编程难度。该模块广泛运用于飞控、计步等电子产品中。前期准备: 在arduino环境下需要安装MPU6050库,在使用中只需要声明一个MPU6050的类即可。像MPU6500这样的6轴传感器,结合了三轴加速度计和三轴陀螺仪,可以提供六个参数,初始化之后读取六个数据分别为:
[*]Ax:X轴线性加速度,单位通常是g(重力加速度)或m/s²。
[*]Ay:Y轴线性加速度,单位通常是g或m/s²。
[*]Az:Z轴线性加速度,单位通常是g或m/s²。
[*]Gx:绕X轴的角速度(旋转速率),单位通常是°/s(度每秒)或rad/s(弧度每秒)。
[*]Gy:绕Y轴的角速度,单位通常是°/s或rad/s。
[*]Gz:绕Z轴的角速度,单位通常是°/s或rad/s。在实验中,将读取的数据显示在屏幕中,分为六行。
实验结果:
参考代码:#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <MPU6050.h>
// OLED屏幕参数
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// MPU6500参数
MPU6050 mpu;
bool checkMPU6500Connection() {
Wire.beginTransmission(0x68); // MPU6500的I2C地址
return Wire.endTransmission() == 0;
}
void setup() {
Serial.begin(115200);
Wire.begin(9, 10); // 指定SDA和SCL引脚
// 初始化OLED屏幕
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 尝试0x3C地址
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.display();
// 检查MPU6500连接
if (!checkMPU6500Connection()) {
Serial.println(F("MPU6500 not connected or initialization failed"));
for (;;);
}
// 初始化MPU6500传感器
mpu.initialize();
}
void loop() {
// 读取MPU6500数据
int16_t ax, ay, az;
int16_t gx, gy, gz;
mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
// 显示数据到OLED屏幕
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Ax: ");
display.print(ax/100);
display.setCursor(0, 10);
display.print("Ay: ");
display.print(ay/100);
display.setCursor(0, 20);
display.print("Az: ");
display.print(az/100);
display.setCursor(0, 30);
display.print("Gx: ");
display.print(gx/100);
display.setCursor(0, 40);
display.print("Gy: ");
display.print(gy/100);
display.setCursor(0, 50);
display.print("Gz: ");
display.print(gz/100);
display.display();
delay(500);
}
四、舵机云台MG90S(PWM)介绍:SG90,9克经典舵机是180度舵机,好像也有360度款式的,这里主要以180度来说明,它主要控制0-180度角度,左边90度,右边90度。MG90S是360度舵机,但是它是没有0-360度角度控制的功能,在控制方式上和SG舵机其实是一样的,只不过它控制的不是角度,而是控制速度和方向(顺时针旋转/逆时针旋转),它实际就相当于无级变速的减速电机。总之,SG90舵机和MG90S舵机的区别在于它们的旋转角度范围不同,选择哪种舵机需要根据具体的应用需求来决定。
前期准备: 在arduino环境中想要使用ESP32控制舵机与arduino uno控制舵机不同,使用Servo库无法控制舵机,需要单独安装ESP32Servo库。 之后使用定义PWM相关引脚、声明servo类,之后在初始化中设置PWM频率与脉冲宽度即可 servo1.setPeriodHertz(50); // 设置 PWM 信号频率为 50Hz servo1.attach(PIN_SERVO1, 500, 2500); // 设置脉冲宽度范围为 500-2500 微秒在控制代码中设置妒忌角度即可,具体如下:servo1.write(angle); // 设置舵机角度
控制多个舵机,只需要将上述步骤重复多次即可。
实验结果:
参考代码:#include <ESP32Servo.h>
#define PIN_SERVO1 26 // 舵机信号线连接的 GPIO 引脚
Servo servo1;
#define PIN_SERVO2 27 // 舵机信号线连接的 GPIO 引脚
Servo servo2;
void setup() {
servo1.setPeriodHertz(50); // 设置 PWM 信号频率为 50Hz
servo1.attach(PIN_SERVO1, 500, 2500); // 设置脉冲宽度范围为 500-2500 微秒
servo1.write(90); // 初始化舵机角度为 90 度
servo2.setPeriodHertz(50); // 设置 PWM 信号频率为 50Hz
servo2.attach(PIN_SERVO2, 500, 2500); // 设置脉冲宽度范围为 500-2500 微秒
servo2.write(90); // 初始化舵机角度为 90 度
}
void loop() {
for (int angle = 20; angle <= 160; angle += 5) {
servo1.write(angle); // 设置舵机角度
delay(100);
}
servo1.write(90); // 设置舵机角度
for (int angle1 = 20; angle1 <= 140; angle1 += 5) {
servo2.write(angle1); // 设置舵机角度
delay(100);
}
servo2.write(90); // 设置舵机角度
}
注:使用舵机需要单独供电,单片机本身不足以给两个舵机供电。参考文献:0.96寸IIC单色屏:0.96寸IIC单色屏 | 立创开发板技术文档中心MPU6050六轴传感器:MPU6050六轴传感器 | 立创开发板技术文档中心SG90舵机和MG90S舵机对比:https://blog.csdn.net/qq_44836335/article/details/134896538
		页: 
[1]