もちろん、Arduinsの内部にはEEPROMがあります。 長い整数のかかとを格納するために多くのスペースは必要ありませんが、ニュアンスがあります。 EEPROMの書き込みリソースが制限されすぎています。 少なくとも数秒ごとにデータを書き込みたいです。 リソースEEPROMを使用すると、これをかなり目に見える時間で実行できます。つまり、内蔵メモリは明らかに永遠ではありません。
最初は、チップの1Kメモリのさまざまな場所のデータ構造を円で書き留めて、運命を欺いたかったのです。 ポインターもどこかに格納する必要があり、データはシーケンシャル検索に何らかのマーカーを使用するのに十分なほどランダムであると休息しました。
ポインターを格納する必要は、多くの方法でだまされる可能性があります。 たとえば、次のように:
struct MarkedSavedData { byte marker; // , . struct SavedData { // } } data;
MarkedSavedData構造体は、eerpomまたはflash、または円で囲まれた何かで満たされています。 ポインターを書き込まないために、たとえば、空きレコードではdata.marker = 0x00を実行し、現在のデータではdata.marker = 0xffを占有します。 作業の過程では、もちろん、記録はポインターに従って行われ、コントローラーが起動すると、メモリ全体を検索するだけでdata.marker == 0xffの構造が検索されます。これが最後の正しいデータです。 2つのレコードが取得されるたびに、リリースされたレコードのdata.markerをリセットする必要があるかもしれません。
シリアルカウンター付きのオプションがあります。
struct MarkedSavedData { unsugned int counter; // . struct SavedData { // } } data;
レコードごとに、カウンターを1つ増やし、オーバーフローを記録します。 コントローラーを起動するとき、オーバーフローの可能性を考慮して最大のカウンターを探すことはそれほど難しくありませんが、このための関数を作成し、スタック上の中間構造体をローカル変数に配置することで、スラムを節約できます。
これはすべて良いですが、これらは湿布です。
STC Metrotekの同僚は、FRAMの検索を提案しました。 これは、途方もない速度と10 14の書き込みサイクルを持つフェライトメモリです。

参考になったAliexpressはそのようなモジュールを私にもたらしました 。 ちなみに、モジュール形式のメモリは非常に高価です。 チップ自体の価格は16p / pcです。 チップのサイズは512バイトです。つまり、少々見えますが、無限のレコード数を考慮すれば十分です。
このチップの準備ができているもののトピックをグーグルで検索しても、何も見つかりませんでした。 素晴らしい猫、私は決めました、私はそれに訓練します! Wireのドック、FM24のデータシート、誰かのEEPROM / I2Cプロジェクトを同様のインターフェースで開き、FRAMのクラスをスケッチしました。

Githubプロジェクト: github.com/nw-wind/FM24I2C
例はこのように添付されます。
#include "FM24I2C.h" // . i2c. FM24I2C fm(0x57); void setup() { Wire.begin(); Serial.begin(9600); char str1[]="12345678901234567890"; char str2[]="qwertyuiopasdfghjklzxcvbnm"; int a1=0x00; // FRAM int a2=0x40; // FRAM fm.pack(a1,str1,strlen(str1)+1); // delay(5); fm.pack(a2,str2,strlen(str2)+1); // delay(5); char buf[80]; fm.unpack(a2,buf,strlen(str2)+1); // Serial.println(str2); fm.unpack(a1,buf,strlen(str1)+1); // Serial.println(str1); }
FRAMのi2cプロトコルは、EEPROMよりもはるかに簡単です。 メモリはバス上のデータ転送よりも高速に動作し、少なくとも2Kのarduino脳を一度に注ぐことができます。 私のコードの利点は、32バイトの不要なブロッキングやバイト転送さえないことです。
class FM24I2C { private: int id; public: FM24I2C(int id_addr); ~FM24I2C(); void pack(int addr, void* data, int len); // FRAM int unpack(int addr, void* data, int len); // FRAM. . // , . void inline writeUnsignedLong(int addr, unsigned long data) { pack(addr, (void*)&data, sizeof(unsigned long)); } // . unsigned long inline readUnsignedLong(int addr) { unsigned long data; return unpack(addr, (void*)&data, sizeof(unsigned long)) == sizeof(unsigned long) ? data : 0UL; } // /, , . // . };
コードは少しだけです。
void FM24I2C::pack(int addr, void* data, int len) { Wire.beginTransmission(id); Wire.write((byte*)&addr,2); Wire.write((byte*)data,len); // , unsigned int :) Wire.endTransmission(true); } int FM24I2C::unpack(int addr, void* data, int len) { int rc; byte *p; Wire.beginTransmission(id); Wire.write((byte*)&addr,2); Wire.endTransmission(false); Wire.requestFrom(id,len); // rc p-data :) for (rc=0, p=(byte*)data; Wire.available() && rc < len; rc++, p++) { *p=Wire.read(); } return(rc); }
モジュールにはチップとコネクタ以外はほとんど何もないので、すでにいくつかのマイクロ回路を購入したいと思っています。 それが好きです。