我一直在研究Arduino(ATMega328p)原型,它必须在某些事件中记录数据。 LSM6DS33传感器用于以104 Hz的采样率生成6个值(每个2个字节)。这些数据需要记录500-20000ms。如何防止在记录期间SD卡创建写入延迟?
在我的代码中,我使用Timer1每1/104秒产生一个中断。发生此中断时,将从传感器读取数据,进行校准,然后写入SD卡。通常情况下,这不是问题。从传感器读取数据需要约3350us,校准〜5us并写入〜550us。这意味着整个循环需要约4000us,而9615us可用。
为了节省电力,我希望降低电压到3.3V。根据atmel数据表,这也意味着时钟频率应该降至8MHz。假设一切都会慢两倍,测量周期仍然是可能的,因为〜8000us < 9615us。
然而,经过一些测试(仍然是5V @ 16MHz)后,我发现写一个周期需要约1880us而不是约550us。我正在使用库SdFat编写和测试SD卡(RawWrite示例)。以下结果出来时,我测试的卡:
开始原始写入的100000 KB
目标速率:100 KB /秒
目标时间:100秒
闵块写入时间:1244百万分之一
最大块写时间:12324万分之一
平均块写入时间:1247万分之一
正如所看到的,写的平均时间是相当一致的,但有时10倍平均峰值时间发生!根据库的作者,这是因为SD卡在x个写入周期之间需要一些擦除周期。这会导致写入延迟(src:post#18)。然而,这种延迟将周期从可用的9615us支架中抽出所需的时间,因为总的测量周期将是10672us。
我想写的数据,使用的sprintf首次投入一个字符串:
char buf[20] = "";
sprintf(buf,"%li\t%li\t%li\t%li\t%li\t%li",rawData[0],rawData[1],rawData[2],rawData[3],rawData[4],rawData[5]);
myLog.println(buf);
这将数据写入到一个txt文件。但以我的速度,只有21 * 104 = 2184 B/s就足够了。将RawWrite示例的速度降低至6 KB/s,会导致SD卡写入而不会延长写入延迟。然而我的代码仍然有它们,即使写入的数据较少。
我的问题是:如何防止发生延迟(如果可能)?如果不可能,我该如何解决它?如果我明白为什么发生延迟,这将有所帮助,因为间隔不总是相同的(每10-15次写入)。
一些附加信息:
草图当前使用变量的69%的RAM(2kB)。创建两个512字节缓冲区 - 就像在同一个论坛中建议的那样 - 对我来说是不可能的。
最初,我使用了两个字符串。将它们合并为一个并不影响写入速度,具有任何意义。
擦除延迟是SD卡固有的。如果已满,您可能会预计更长的延迟。另外,如果细胞老化,他们需要花更长的时间来擦写。虽然你的问题太广泛了(我们不是咨询网站),但缓冲可能会有所帮助,但正如你所说你的RAM处于边缘,也许Arduino(至少基于ATmega的)不适合你的项目。最后:Arduino是**不** **。不要垃圾标签。 – Olaf
如果性能很重要,为什么要将值转换为字符串并写入文本?这需要更多的空间和更多的时间。 –
@AndrewHenle:虽然我同意在如此小的平台上使用'printf'等是一个好主意,但它似乎并不是主要问题。它不会避开SD卡摊位。 – Olaf