OLED Animation Optimization
Created on: December 22, 2024
Created on: December 22, 2024
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
int fps=40;
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, 20, 21, U8X8_PIN_NONE);
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(115200);
u8g2.setI2CAddress(0x3D*2);
u8g2.begin();
u8g2.enableUTF8Print();
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}// Pause for 2 seconds
// Clear the buffer.
}
void loop() {
display.clearDisplay();
display.drawBitmap(0, 0, gImage_1, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_2, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_3, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_4, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_5, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_6, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_7, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_8, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_9, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_10, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_11, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_12, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_13, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_14, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_15, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_16, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_17, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_18, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_19, 128, 64, 1);
display.display();
delay(fps);
display.clearDisplay();
display.drawBitmap(0, 0, gImage_20, 128, 64, 1);
display.display();
delay(fps);
}
对代码内容进行优化
Certainly! Your current code displays a sequence of 20 bitmaps on an SSD1306 OLED display using the Adafruit library. However, it contains a lot of repetitive code, which can be optimized for better readability, maintainability, and efficiency. Below are the key optimizations and an improved version of your code:
Eliminate Redundant Libraries:
U8G2_SSD1306 and Adafruit_SSD1306 libraries, but only using the Adafruit library in the loop(). Unless you have a specific reason to use both, it's better to stick with one to conserve memory and reduce complexity.Use Arrays for Bitmaps:
Correct Frame Rate Handling:
fps variable is set to 40, which is used as a delay in milliseconds (delay(fps);). If you intend fps to represent frames per second, the delay should be calculated as 1000 / fps. For example, fps = 25 would correspond to 40 ms per frame.Optimize Display Updates:
clearDisplay() Calls: Clearing the display before each new frame ensures no ghosting, but you can structure the code to make it cleaner.Enhance Code Readability:
const for variables that don't change, such as the number of frames and frame rate.cpp#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // Display dimensions #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 // OLED reset pin (set to -1 if sharing Arduino reset pin) #define OLED_RESET -1 // Frame rate settings const int FPS = 25; // Frames per second const int FRAME_DELAY = 1000 / FPS; // Delay per frame in milliseconds // Number of frames const int NUM_FRAMES = 20; // Initialize the display Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Array of bitmap pointers const unsigned char* frames[NUM_FRAMES] = { gImage_1, gImage_2, gImage_3, gImage_4, gImage_5, gImage_6, gImage_7, gImage_8, gImage_9, gImage_10, gImage_11, gImage_12, gImage_13, gImage_14, gImage_15, gImage_16, gImage_17, gImage_18, gImage_19, gImage_20 }; void setup() { Serial.begin(115200); // Initialize the OLED display if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for most modules Serial.println(F("SSD1306 allocation failed")); while(true); // Don't proceed, loop forever } display.clearDisplay(); display.display(); // Ensure the display is cleared at start } void loop() { for(int i = 0; i < NUM_FRAMES; i++) { display.clearDisplay(); // Clear the buffer // Draw the current frame display.drawBitmap(0, 0, frames[i], SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); display.display(); // Update the display with the new frame delay(FRAME_DELAY); // Wait for the next frame } }
Removed U8G2 Library:
loop(), the U8G2-related code has been removed to simplify the setup.Defined Constants:
FPS and FRAME_DELAY are defined to make frame rate adjustments easier.NUM_FRAMES specifies the total number of frames, making it easier to manage if you add or remove frames in the future.Bitmap Array:
frames holds pointers to all your bitmap images (gImage_1 to gImage_20). This allows for easy iteration using a for loop.Loop Optimization:
loop() function now iterates through the frames array, displaying each bitmap sequentially with the specified delay.drawBitmap uses WHITE as the color parameter, which is standard for monochrome displays. Adjust if your display uses a different color scheme.Error Handling:
Code Readability:
Memory Management:
gImage_x bitmaps are properly defined and stored in program memory (PROGMEM) if they are large, to conserve SRAM.Dynamic Frame Handling:
Non-blocking Delays:
delay() is simple but blocks the CPU. For more advanced applications, consider using non-blocking timing (e.g., millis()) to allow other tasks to run concurrently.Power Optimization:
By implementing these optimizations, your code becomes more efficient, easier to manage, and better suited for future enhancements.
我所使用的iic接口为scl20,sda21,请你帮我完成代码的编写。并加上中文注释
好的,以下是优化后的代码,使用Adafruit_SSD1306库,并配置I2C接口的SCL为20,SDA为21。同时,代码中添加了详细的中文注释以便理解和维护。
cpp#include <Wire.h> // 引入I2C通信库 #include <Adafruit_GFX.h> // 引入Adafruit图形库 #include <Adafruit_SSD1306.h> // 引入Adafruit SSD1306 OLED显示库 // 显示屏的宽度和高度 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 // OLED复位引脚(如果不使用复位引脚,则设置为-1) #define OLED_RESET -1 // 帧率设置 const int FPS = 25; // 每秒帧数(Frames Per Second) const int FRAME_DELAY = 1000 / FPS; // 每帧延迟时间(毫秒) // 帧数总数 const int NUM_FRAMES = 20; // 初始化SSD1306显示对象,使用Wire库,指定SDA为21,SCL为20 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // 存储所有位图的数组 const unsigned char* frames[NUM_FRAMES] = { gImage_1, gImage_2, gImage_3, gImage_4, gImage_5, gImage_6, gImage_7, gImage_8, gImage_9, gImage_10, gImage_11, gImage_12, gImage_13, gImage_14, gImage_15, gImage_16, gImage_17, gImage_18, gImage_19, gImage_20 }; void setup() { // 初始化串口,波特率为115200,用于调试 Serial.begin(115200); // 初始化I2C通信,指定SDA为21,SCL为20 Wire.begin(21, 20); // 初始化OLED显示屏 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // 通常地址为0x3C Serial.println(F("SSD1306 初始化失败")); while(true); // 如果初始化失败,进入无限循环 } // 清空显示缓冲区 display.clearDisplay(); display.display(); // 确保显示屏在开始时是清空的 } void loop() { // 遍历所有帧 for(int i = 0; i < NUM_FRAMES; i++) { display.clearDisplay(); // 清空显示缓冲区 // 在显示屏的(0,0)位置绘制当前帧的位图 display.drawBitmap(0, 0, frames[i], SCREEN_WIDTH, SCREEN_HEIGHT, WHITE); display.display(); // 将缓冲区内容显示到屏幕上 delay(FRAME_DELAY); // 延迟以控制帧率 } }
库的引入:
Wire.h:用于I2C通信。Adafruit_GFX.h:Adafruit的图形库,提供绘图功能。Adafruit_SSD1306.h:专门用于SSD1306 OLED显示屏的库。显示屏配置:
OLED_RESET设置为-1,表示不使用复位引脚。帧率设置:
FPS定义了每秒显示的帧数,这里设置为25帧每秒。FRAME_DELAY根据FPS计算每帧的延迟时间。显示对象初始化:
Adafruit_SSD1306库初始化显示对象,指定I2C的SDA和SCL引脚为21和20。位图数组:
frames数组存储了所有需要显示的位图指针(gImage_1到gImage_20)。请确保这些位图在代码的其他部分正确定义,并且大小为128x64像素。setup()函数:
loop()函数:
for循环遍历所有帧。delay(FRAME_DELAY)控制每帧的显示时间,以达到设定的帧率。内存管理:
PROGMEM)中,以节省SRAM。例如:
cppconst unsigned char gImage_1[] PROGMEM = { ... };
非阻塞延迟:
delay()会阻塞CPU,影响其他任务的执行。可以考虑使用millis()实现非阻塞延迟,以便在显示帧的同时执行其他操作。动态帧处理:
错误处理:
通过上述优化,代码不仅更加简洁高效,而且更易于维护和扩展。如果有任何进一步的问题或需求,请随时告知!