7| 0
|
[ESP8266/ESP32] 基于FireBeetle 2 ESP32-C5的常用模块测试 |
本帖最后由 azhu 于 2025-10-10 22:17 编辑 基于FireBeetle 2 ESP32-C5的常用模块测试前言: 本来是想要做一个陀螺仪/摇杆控制舵机的例程,在测试过程中,有好几个模块想要测试一下,结果就有了本期帖子。 一、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 是 InvenSense 公司推出的整合性 6 轴运动处理组件,其内部整合了 3 轴陀螺仪和 3 轴加速度传感器,并且含有一个IIC 接口, 可用于连接外部磁力传感器,并利用自带的数字运动处理器(DMP: Digital Motion Processor) 硬件加速引擎,通过主 IIC 接口,向应用端输出完整的 9 轴融合演算数据。 InvenSense 公司提供了一套基于DMP的运动处理驱动库,可大大降低单片机对动处理运算的负荷,同时也大大降低了编程难度。该模块广泛运用于飞控、计步等电子产品中。 ![]() 在arduino环境下需要安装MPU6050库,在使用中只需要声明一个MPU6050的类即可。像MPU6500这样的6轴传感器,结合了三轴加速度计和三轴陀螺仪,可以提供六个参数,初始化之后读取六个数据分别为:
![]() ![]() 参考代码:#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 |
© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed