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

如何从SPIFFS读取uint16_t数据并存入uint16_t数组用于IR发送?

解决ESP32从SPIFFS读取uint16_t数组用于IRsend.sendRaw()的问题

前提约定

首先确保SPIFFS中的Turbo_swing_middle文件内容格式正确:每个uint16_t数值以空格或换行分隔,例如:

9000 4500 560 1690 560 560 560 1690 560 560 ...

完整实现代码

以下代码支持动态数组大小,会自动统计文件中的元素数量并分配对应内存:

#include <IRsend.h>
#include <SPIFFS.h>

IRsend irSender(4); // 替换为你的红外发射引脚

void setup() {
  Serial.begin(115200);
  
  // 初始化SPIFFS
  if (!SPIFFS.begin(true)) {
    Serial.println("SPIFFS初始化失败");
    return;
  }

  // 第一步:统计文件中的元素数量
  File file = SPIFFS.open("/Turbo_swing_middle", "r");
  if (!file) {
    Serial.println("无法打开Turbo_swing_middle文件");
    return;
  }

  int count = 0;
  String tempStr;
  // 遍历文件统计有效数值个数
  while (file.available()) {
    char c = file.read();
    // 遇到分隔符(空格、换行)且tempStr不为空时,计数+1并清空临时字符串
    if ((c == ' ' || c == '\n' || c == '\r') && tempStr.length() > 0) {
      count++;
      tempStr.clear();
    } else if (isdigit(c)) { // 只收集数字字符
      tempStr += c;
    }
  }
  // 处理最后一个数值(文件末尾无分隔符的情况)
  if (tempStr.length() > 0) {
    count++;
  }
  file.close();

  if (count == 0) {
    Serial.println("文件中无有效数值");
    return;
  }

  // 第二步:分配动态uint16_t数组
  uint16_t* rawData = new uint16_t[count];
  if (!rawData) {
    Serial.println("内存分配失败");
    return;
  }

  // 第三步:重新打开文件读取并转换数值
  file = SPIFFS.open("/Turbo_swing_middle", "r");
  if (!file) {
    Serial.println("无法重新打开Turbo_swing_middle文件");
    delete[] rawData; // 释放已分配的内存
    return;
  }

  int index = 0;
  tempStr.clear();
  while (file.available() && index < count) {
    char c = file.read();
    if ((c == ' ' || c == '\n' || c == '\r') && tempStr.length() > 0) {
      // 将字符串转换为uint16_t,超出范围时自动截断(符合uint16_t的溢出规则)
      rawData[index++] = (uint16_t)tempStr.toInt();
      tempStr.clear();
    } else if (isdigit(c)) {
      tempStr += c;
    }
  }
  // 处理最后一个数值
  if (tempStr.length() > 0 && index < count) {
    rawData[index++] = (uint16_t)tempStr.toInt();
  }
  file.close();

  // 第四步:发送红外信号
  irSender.begin();
  irSender.sendRaw(rawData, count, 38); // 38为载波频率,根据你的设备调整
  Serial.printf("成功发送%d个红外原始数据\n", count);

  // 第五步:释放动态内存,避免内存泄漏
  delete[] rawData;
}

void loop() {
  // 按需添加循环逻辑,比如定时发送等
}

关键说明

  • 动态数组支持:先统计元素数量再分配内存,避免固定数组大小的限制
  • 文件读取逻辑:两次打开文件,第一次统计数量,第二次读取转换;也可以一次性读取整个文件内容再拆分,但大文件下两次打开更节省内存
  • 内存安全:使用new分配数组后,必须用delete[]释放,防止ESP32内存泄漏
  • 数值转换:用toInt()转换后强制转为uint16_t,如果文件中的数值超过65535,会自动截断为合法的uint16_t值(可根据需求添加范围检查)

内容的提问来源于stack exchange,提问作者hisham2630

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 10:36:23