0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Arduinoを USB/HIDデバイス(仮想キーボード)として活用する(第六回)ロギングとプロット②

Last updated at Posted at 2021-07-25

##本記事について
 Arduinoを USB/HIDデバイスとして活用する第六回②です。[第六回①はここ]
(https://qiita.com/pronechia/items/5054b9567454df6b9edd)。①で実現した制御結果をロギングするところを紹介します。
##第六回)「赤外線によるエアコンのON/OFFと結果のロギングとプロット②」
①で紹介した、赤外線によるエアコンのON/OFFと温度調整制御を行いながら、周期毎のセンサー値や制御結果をEEPROMにロギングします。
 ロギングは、周期的に発生するデータ一式を繰り返し回数分保持し、実行後にデータを指定して時系列順に取り出すなどして利用します。個々のデータのことをチャンネル(ch)と呼びます。
 実現方法として特筆すべきは、アプリとデータの独立性を高めデータの追加/変更を容易とするため、EEPROM上のデータを読み書きする仕組みとして、INFOという考え方を導入したことです。これは、さまざまなアプリに適用することができます。
 データの発生頻度が高くなければ、より大量にデータを保存できる方法として、ファイルをSDカードに保存する方法もあります。が、今回はエアコンのON/OFF制御のロギングということで、1日程度、データを保管する仕組みとしてEEPROMを使って実現しました。

##機能概要
  下図にあるように、初期化時に蓄積するデータにラベル名(ch名)を付与してEEPROMアドレスと紐付けをします。これをINFO情報と呼びます。データは個別データと周期データを格納することができます。個別データはアプリ間のデータ共有として利用します。周期データはロギング/ビューワーで利用します。
 制御実行時には、ロガーにより、ch名を指定して(EEPROMのアドレスを指定することなく)EEPROMに書き込みます。制御実行後動かすビューアーでは、 ch名と周期を指定してデータを読み出すことができます。また、アクセスをサポートするライブラリーも用意しました。ライブラリーでは、INFO情報を使ってchを読み書きすることができます。
 この仕組みを使えば、データの追加/変更が簡単にでき、複数のアプリが共通のINFOを介してEEPROM上のデータにアクセスすることもできます。

・データの追加/変更が簡単にでき、EEPROMの物理アドレスを気にすることなくアプリ実装ができる。
・今回はマイコン1つだが、マイコンが複数であってもEEPROMを共有する仕組みが実現できる。
・INFOの提供元としてSDカードがあれば、ファイル渡しもできる。

<INFO を使ってEEPROMをアクセスするイメージ>
image.png

##info情報

info情報の変数定義
//info 情報定義構造体
typedef struct _INFO {
   char label[8];       //ch
   uint16_t  address;   //EEPROM保存時のアドレス
   uint16_t  len;       //1,2,4byte
} INFO;
//個別データ
#define INFOMAX 5
int tableInfoCount = INFOMAX;
INFO tableInfo[INFOMAX];
//周期データ(ヘッダー)
#define HEADERMAX 20
INFO tableHeaderInfo[HEADERMAX];
//周期データ(データ)
#define LOGRMAX 8
INFO tableLogInfo[LOGRMAX];
info情報
//初期化にて、設定する情報の例
//BME280で取得した温度、湿度、気圧を共有する
#define MAPDT     0x0040
#define MAPDH     0x0042
#define MAPDP     0x0044
#define MAPDC     0x0046
#define MAPDY     0x0047
//周期データは、温度、湿度、制御値
#define MAPLOGK     0x0000
#define MAPLOGL     0x0002
#define MAPLOGC     0x0003
//個別データのchごとの情報
  strcpy(tableInfo[0].label , "Dtemp");
  tableInfo[0].address = MAPDT;
  tableInfo[0].len = 2;
  strcpy(tableInfo[1].label , "Dhum");
  tableInfo[1].address = MAPDH;
  tableInfo[1].len = 2;
  strcpy(tableInfo[2].label , "Dpress");
  tableInfo[2].address = MAPDP;
  tableInfo[2].len = 2;
  strcpy(tableInfo[3].label , "Dctl");
  tableInfo[3].address = MAPDC;
  tableInfo[3].len = 1;
  strcpy(tableInfo[4].label , "Dyobi");
  tableInfo[4].address = MAPDY;
  tableInfo[4].len = 1;
  tableInfoCount = 5;
//周期データのchごとの情報
  strcpy(tableLogInfo[0].label , "LK");
  tableLogInfo[0].address = MAPLOGK;
  tableLogInfo[0].len = 2;
  strcpy(tableLogInfo[1].label , "LL");
  tableLogInfo[1].address = MAPLOGL;
  tableLogInfo[1].len = 1;
  strcpy(tableLogInfo[2].label , "LC");  //controll値 エアコン on/off
  tableLogInfo[2].address = MAPLOGC;
  tableLogInfo[2].len = 1;  // int8_t とする 
  tableLogInfoCount = 4
//周期データの管理情報
  tableLogRepeat[0] = 2048; //最大個数
  tableLogRepeat[1] = 2048;
  tableLogRepeat[2] = 2048;
  tableLogStartAddr[0] = 0x4000; //先頭アドレス
  tableLogStartAddr[1] = 0x8000;
  tableLogStartAddr[2] = 0xc000;

INFO構造体が、ch名とEEPROM物理アドレスを変換する主要な情報となる。
この例では、個別データを5つ、周期データを4つ定義している。周期データの最大個数を2048 としている。これだけのことを初期化で行っておけば、実際のEEPROM読み書き時は、ch名でアクセスできる。

##提供されるライブラリ

ログヘッダーの読み書き
//Logヘッダーを読む  
bool sub_EEPROM512_ReadLogHeader(int8_t p_lognum, unsigned long* p_s, unsigned long* p_e, int16_t* p_c, int16_t* p_n)
//
//Logヘッダーを書く 
void sub_EEPROM512_WriteLogHeader(char p_se)

ロギングされたデータを管理するため、ログヘッダーの読み書き関数を提供する。

ラベルを指定してログを読み書き
//chデータを書く
  int16_t p_t;  //温度、 25.00度の場合は2500とする
  char* p = (char*)&p_t;
  sub_SetLogVal(gCount, "LK", p); //温度
//chデータを読む
    char p[8];
  int16_t* fp;
  sub_GetLogVal(pCount, "LK", p);
  fp = (int16_t*)(p);

周期データの読み書き関数を提供する。

##実行時のログ蓄積

・個別データ用の例
 "Dtemp"というch名のデータを制御で書き、別アプリで読むイメージの図です。
image.png
・周期データ用の例
"LK"というch名の周期データをロガーで書き、ビューアーで読み出すイメージ図です。何番名のデータかを意味する、パラメータ=cがあることがわかります。
image.png

##ログ管理機能
3セットのログを保持できるようにした。ログヘッダには、開始、終了、実行周期、データ点数を保持している。3セットのログのうち、次回書き込む番号(つまりログを残す番号)、次回読み取る番号(つまりプロットする番号)を指定することができる。
LLISTの例) LPLOT 0 / LNEXT 2 を実行した後の状態
image.png
ログに関する命令は以下の3種類
・LLIST 一覧表示
・LNEXT n 次回使用するログの指定 (書込番号)
・LPLOT n PLOTログの指示 (読込番号)

 使い方手順例)
1。LLIST でログの状況を確認する。次回のロギングはログ番号2を使うと決める
2。LNEXT 2 で書込番号を2に設定する
3。ロギング実行
4。ロギング終了後、LLISTでログが書き込まれたことを確認する(時間、点数など)
5。LPLOT 2 で読込番号を2に設定する
6。シリアルモニター画面に切り替えて、1を入力すると、1ページ目が描画される。
  点数が500点以上であれば、2を入力して、2ページ目を描画する、、、

##まとめ
 実装上の工夫として、アプリとデータの独立性を高めデータの追加/変更を容易とする、INFOという考え方を実現できました。開発中にEEPROMを違うサイズに取り替えることが発生しましたが、アドレス依存部分が局所的で簡単に対応することができました。アプリの仕様変更にも柔軟に対応できると考えます。また、各種アプリで利用するために、ライブラリーとして提供することも考えられます。
 ③では、ロギングしたデータを取り出してIDEのシリアルプロッターにプロットする仕組みを紹介します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?