2017-04-05 35 views
0

我一直在研究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&#22)。然而,这种延迟将周期从可用的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字节缓冲区 - 就像在同一个论坛中建议的那样 - 对我来说是不可能的。
最初,我使用了两个字符串。将它们合并为一个并不影响写入速度,具有任何意义。

+1

擦除延迟是SD卡固有的。如果已满,您可能会预计更长的延迟。另外,如果细胞老化,他们需要花更长的时间来擦写。虽然你的问题太广泛了(我们不是咨询网站),但缓冲可能会有所帮助,但正如你所说你的RAM处于边缘,也许Arduino(至少基于ATmega的)不适合你的项目。最后:Arduino是**不** **。不要垃圾标签。 – Olaf

+0

如果性能很重要,为什么要将值转换为字符串并写入文本?这需要更多的空间和更多的时间。 –

+0

@AndrewHenle:虽然我同意在如此小的平台上使用'printf'等是一个好主意,但它似乎并不是主要问题。它不会避开SD卡摊位。 – Olaf

回答

0

我不知道如何解决延迟,但我遇到一个更稳定和更快的写入时间,如果我写的二进制文件,而不是一个名为“.csv”或.txt”文件。

以下链接提供了一个很好的脚本来将数据作为二进制结构写入SD卡。(在他的例子中有一些小的错字,它很容易修复) https://hackingmajenkoblog.wordpress.com/2016/03/25/fast-efficient-data-storage-on-an-arduino/

这不会帮助你的时间变化,但它可能会减少写入时间,从而忽略了时间问题。