You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Arduino代码优化请求:消除else if并实现16到0计数显示图片

嘿,我完全懂你的烦恼——一大串else if不仅写起来麻烦,还占了超多Flash空间,用数组确实是解决这个问题的完美方案,大概率是你对Arduino里PROGMEM数组的用法没摸透,我来给你一步步捋清楚!

首先,先复盘下核心思路:把所有图片的存储地址放进一个数组里,然后根据当前的计数值直接索引对应的图片,这样既省代码空间,后期维护也方便。

第一步:整理你的图片定义

假设你原来的图片是存在PROGMEM里的(如果还没加,一定要加上,不然会占满宝贵的RAM),示例如下:

// 你的原有图片定义(补全你所有17张图:img16到img0)
const unsigned char img16[] PROGMEM = { /* 16对应的图片数据 */ };
const unsigned char img15[] PROGMEM = { /* 15对应的图片数据 */ };
// ... 中间省略img14到img1的定义
const unsigned char img0[] PROGMEM = { /* 0对应的图片数据 */ };

第二步:创建图片指针数组

我们把所有图片的地址按16到0的顺序放进一个指针数组里,并且也把这个数组存在PROGMEM里(进一步节省RAM):

// 存储所有图片的指针,顺序对应count从16到0
const unsigned char* const imageArray[] PROGMEM = {
  img16, img15, img14, img13, img12, img11, img10, img9,
  img8, img7, img6, img5, img4, img3, img2, img1, img0
};

// 自动计算图片总数(不用手动数,避免出错)
const int totalImages = sizeof(imageArray) / sizeof(imageArray[0]);

第三步:编写图片显示函数

根据当前的计数值,计算数组索引,然后从PROGMEM里读取图片指针,再调用你的显示逻辑:

void displayCountImage(int currentCount) {
  // 计算索引:currentCount从16→0,对应数组的0→16
  int arrayIndex = 16 - currentCount;
  
  // 从PROGMEM读取对应的图片指针(这一步很关键,不然会读错数据)
  const unsigned char* targetImage = (const unsigned char*)pgm_read_word(&imageArray[arrayIndex]);
  
  // 这里替换成你实际的显示代码!
  // 举个例子,如果你用SSD1306 OLED屏,大概是这样:
  // oled.clearDisplay();
  // oled.drawBitmap(0, 0, targetImage, 128, 64, WHITE); // 替换成你的屏尺寸
  // oled.display();
}

第四步:主循环里的计数逻辑

最后在主循环里实现从16到0的计数,每步调用显示函数:

void loop() {
  static int count = 16; // static让变量保持上一次的值
  
  // 显示当前计数对应的图片
  displayCountImage(count);
  
  delay(1000); // 每步的延迟时间,按需调整
  
  // 更新计数:到0后可以重置循环,也可以停止
  if (count > 0) {
    count--;
  } else {
    count = 16; // 不需要循环的话,把这行删掉就行
  }
}

额外优化:如果图片尺寸不同

要是你的图片宽高不一样,可以用结构体数组来存储每个图片的完整信息,这样更灵活:

// 定义结构体,存图片数据、宽、高
typedef struct {
  const unsigned char* data;
  int width;
  int height;
} ImageData;

// 结构体数组,按顺序存所有图片的信息
const ImageData imageInfoArray[] PROGMEM = {
  {img16, 128, 64},
  {img15, 128, 64},
  // ... 补全所有图片的信息
  {img0, 128, 64}
};

// 获取图片信息的函数
ImageData getImageInfo(int currentCount) {
  int arrayIndex = 16 - currentCount;
  ImageData info;
  // 从PROGMEM读取结构体的每个成员
  info.data = (const unsigned char*)pgm_read_word(&imageInfoArray[arrayIndex].data);
  info.width = pgm_read_word(&imageInfoArray[arrayIndex].width);
  info.height = pgm_read_word(&imageInfoArray[arrayIndex].height);
  return info;
}

// 显示函数就可以改成这样:
void displayCountImage(int currentCount) {
  ImageData imgInfo = getImageInfo(currentCount);
  // 用imgInfo.data、imgInfo.width、imgInfo.height来显示
}

为什么这比else if好?

  • 省空间:一堆else if会生成大量分支判断的机器码,而数组只需要存储指针,代码量骤减;
  • 易维护:后期要加/删图片,只需要修改数组,不用改一堆条件判断;
  • 更高效:直接索引数组比多次条件判断执行速度更快。

内容的提问来源于stack exchange,提问作者Marco Llerena Palomo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:51:18