Arduino プログラミング共に素人ながら前回「Arduinoで模型用の車載データロガーを作りたい」という質問にてアドバイスを頂き、以下のような環境を整えました。
・GingerBread(Arduino pro mini互換機)
・INA260(電流電圧測定モジュール)
・EEPROM 24FC512 (INA260からの測定結果記録用)
INA260、外付けEEPROMそれぞれ単体で動作させるプログラムは見つけ実際に動作することを確認したのですが、この2つを組み合わせた「INA260の測定結果を外付けEEPROMに記録する」プログラムを作るために、いくつか自力で理解できない点がありましたのでご教授いただければと思います。
参考にした作例はこちら(INA260)と**こちら(EEPROM)**です。
また、現状プログラムの意味を調べるのに「Arduino 日本語リファレンス」のみを使用しているので、これ以外に学習の手助けとなるようなサイトがありましたら同様にご教授いただけると幸いです。
①一部プログラムの意味について
EEPROM作例中の
Wire.write((int)(eep_add >> 8)); Wire.write((int)(eep_add & 0xff));
INA260作例中の
Wire.write((value >> 8) & 0xFF); Wire.write(value & 0xFF);
において両方とも「8ビット移動と0×ff(255)の入力?を行っている」と調べた結果認識しましたが、何故このような作業が必要なのかが分かりません。
Arduinoにモジュールを認識させるために必要な儀式のようなものなのでしょうか?
###②Serial.printlnの書き換えに関して
INA260作例中の
Serial.println();
以降でシリアルモニタに表示されてしまう記録データをEEPROMへ記載するために、EEPROM作例中の
void eep_write(int device_add, unsigned int eep_add, int data)
の部分の書き換えが必要なのだろうと思いましたが、具体的にどのように書き換えれば良いかがわかりませんでした。
ヒントでも構いませんのでどう書き換えていくのが良いかを教えていただきたいです。
##追記
教えていただきました内容を踏まえまして追加質問失礼致します。
作例のスケッチを拝見し、INA260の作例をベースとして
#include <Wire.h>
と
#define NELEMS(arg) (sizeof(arg) / sizeof((arg)[0]))
の間に
void eep_write(int device_add, unsigned int eep_add, int data){ Wire.beginTransmission(device_add); Wire.write((int)(eep_add >> 8)); Wire.write((int)(eep_add & 0xff)); Wire.write(data); Wire.endTransmission(); }
を追記し、
Serial.println(); snprintf(buf, NELEMS(buf) , "V:%5ldmV, I:%5dmA, P:%5ldmW" , (voltage + (1000/2)) / 1000 , current , (power + (1000/2)) / 1000 ); Serial.println(buf); dumpRegisters(); delay(1000);
を
int x = 0; while (x <=10){ eep_write(0x50, x*5+0, voltage&0xff); eep_write(0x50, x*5+1, (voltage>>8)&0xff); eep_write(0x50, x*5+2, (voltage>>16)&0xff); eep_write(0x50, x*5+3, current&0xff); eep_write(0x50, x*5+4, (current>>8)&0xff); x++; } delay(1000);
と書き換えました。
このスケッチを使用後、EEPROM参考サイトにあったデータ読み込み用プログラムを使用してアドレス50までの確認を行ったところ、
アドレス0,24,47にそれぞれ
226,255,0とだけ記録されていました。
INA260には測定対象を何も接続しておらず、確認でINA260の作例そのままを出力すると
V: 1mV, I: -1mA, P: 0mW ---INA226 Registers --- Configuration Register (00h) : 6727h (26407) Shunt Voltage (01h) : FFFEh (65534) Bus Voltage (02h) : 0001h (1) Power (03h) : 0000h (0) Current (04h) : FFFFh (65535) Calibration (05h) : 0A00h (2560) Mask/Enable (06h) : 0008h (8) Alert Limit (07h) : 0000h (0) Die ID (FFh) : 2270h (8816)
を常時出力していました。
この問題を解決する手がかりを教えていただければ幸いです。
###使用条件
詳細な使用したい条件は以下の通りです。
電圧範囲 : 2.0~3.5V
電流範囲 : 0.0A~2.0A未満
サンプリング間隔 : 100ms
1回の測定時間 : 120秒未満(主な使用時間40~80秒)
使用回数 : 一度に20回未満(20回以上使用する場合はPCへデータを移動し、eepromをリセットして再記録を行うか、別のeepromに付け替えることを予定しています。)
###INA260の負荷測定結果
無負荷状態だけでなく数値変化するか確認を行ったほうが良いとのご指摘をいただき、負荷をかけたINA260の動作確認を行ったところトラブルが増えてしまいました。
問題としてはどのような負荷をかけても表示されるIの値が-1mAから変化しません。
入出力端子を経由してモーター、LEDは動いているので内部断線はしていないようですが、一先ず購入店舗に問い合わせを行いつつ電力から電流を逆算するようにしたいと思います。
・3Vボタン電池で並列接続したLED3個を稼働
V: 2734mV, I: -1mA, P: 100mW ---INA226 Registers --- Configuration Register (00h) : 6727h (26407) Shunt Voltage (01h) : FFF4h (65524) Bus Voltage (02h) : 088Bh (2187) Power (03h) : 0004h (4) Current (04h) : FFFFh (65535) Calibration (05h) : 0A00h (2560) Mask/Enable (06h) : 0008h (8) Alert Limit (07h) : 0000h (0) Die ID (FFh) : 2270h (8816)
・1.2Vニッケル水素電池でモーターを稼働
V: 1128mV, I: -1mA, P: 1150mW ---INA226 Registers --- Configuration Register (00h) : 6127h (24871) Shunt Voltage (01h) : 0170h (368) Bus Voltage (02h) : 038Fh (911) Power (03h) : 0034h (52) Current (04h) : FFFFh (65535) Calibration (05h) : 0000h (0) Mask/Enable (06h) : 0008h (8) Alert Limit (07h) : 0000h (0) Die ID (FFh) : 2270h (8816)
プログラムが旧バージョン?のINA226用だったので一部アドレスが違うかもしれない、とも考えましたが同じであるという記載を見つけたため問題なさそうです。
プログラムが原因の可能性ありましたらご指摘お願いします。
##現在の進捗に関して
昨晩から本日までに試行した内容を全て羅列致します。
①
ご提案いただいたスケッチ
void eep_write_data(word V,word A){ static word adrs=0; Wire.beginTransmission(INA226_ADDR); Wire.write(adrs>>8); Wire.write(adrs); Wire.write(V>>8); Wire.write(V); Wire.write(A>>8); Wire.write(A); Wire.endTransmission(); adrs+=4;// }
の
Wire.beginTransmission(INA226_ADDR)
がEEPROM作例と異なりEEPROMへのアドレスではなかったので
Wire.beginTransmission(eep_add)
と変更しました。
②
①の後検証を行うと
'eep_add' was not declared in this scope
と言われたので
const int eep_add = 0x50;
を追加しました。
③
VとAが何なのか定義されていないのでは?と思ったため、void loop()内に
for(int V=(voltage + (1000/2)) / 1000;int A=current;)
を追加しました。
④
「EEPROM作例と異なり、eep_write_dataで書き込まれる内容が全てsetup以前に定義されているということはvoid loop以降ではVとAの定義以外eep_write_dataの()の中に入れるものはないのではないか?」
と思い、③以降に
Wire.begin(); eep_write_data; delay(1000);
とだけ記載しました。
しかし実行後読み込みスケッチで読み込みを行っても何も記録されていませんでした。
⑤
やはり
eep_write_data;
には何か書き込まなければならないと思ったので
eep_write_data(V,A);
と記入したところ 'V' was not declared in this scope
eep_write_data(int V,int A);
と記入したところ expected primary-expression before 'int'
eep_write_data(word V,word A);
と記入したところ expected primary-expression before 'V'
eep_write_data("V","A");
と記入したところ エラーは出ませんでしたが実行後読み込みスケッチで読み込みを行っても何も記録されていませんでした。
⑥
for(int V=(voltage + (1000/2)) / 1000;int A=current;)
を
for(word V=(voltage + (1000/2)) / 1000;word A=current;)
へ書き換えました。
エラーは出ませんでしたが実行後読み込みスケッチで読み込みを行っても何も記録されていませんでした。
⑦
Wire.begin(); eep_write_data; delay(1000);
を
Wire.begin(); eep_write_data(); delay(1000);
と書き換えたところ
too few arguments to function 'void eep_write_data(word, word)'
と言われてしまったので⑤へと逆戻りで堂々巡りしてしまっています。
今現在スケッチは以下のようになっています
※文字数制限に引っかかってしまったため以下リンクへ記載を行いました。