私は外部EEPROMから読み込まれている120以上の変数を持つ以下の "setup"のコードを短縮しようとしています。 EEPROMアドレスの位置を格納する変数には、配置される変数の名前に "Pos"という文字列を加えたパターンがあります。
byte fanSpeed, nl1Toggle, ledsToggle;
byte fanSpeedPos = 12, nl1TogglePos = 95, ledsTogglePos = 7;
void setup() {
fanSpeed = readEE(fanSpeedPos);
nl1Toggle = readEE(nl1TogglePos);
ledsToggle = readEE(ledsTogglePos);
//there are over 120 of the above readEE statements in the actual code.
}
uint8_t readEE(uint8_t entry) {
readEEPROM(AT24C32_ADDRESS, 1, entry);
}
理想的には、私はこのように動作するようにしたいと思います(これを行う方法がわからないので疑似コードを使用しています):
char* variableNames [] = { "fanSpeed", "nl1Toggle", "ledsToggle" };
byte fanSpeedPos = 12, nl1TogglePos = 95, ledsTogglePos = 7;
void setup() {
for (int i = 1; i < 120; i++;) {
variableNames[i] = readEE(variableNames[i] + 'Pos');
}
これはC ++/Arduinoを使って可能ですか?
variableNames[i] = readEE(variableNames[i] + 'Pos');
これはC ++/Arduinoを使って可能ですか?
いいえ!実行時に多くの情報を必要とするため、プログラミング言語がほとんどできません。
代わりに問題を再訪しましょう。 EEPROM から大量の変数セットを読み込みます。これを助けることができるC/C ++やAVRライブラリのメカニズムは?
ここでは、「ワンライナー」という結果をもたらす本当にシンプルなソリューションがあります。 eeprom_read_block()。
struct var_t {
byte fanSpeed, nl1Toggle, ledsToggle;
};
var_t var;
const void* pos = ...;
eeprom_read_block(&var, pos, sizeof(var));
明らかに var_t
と var
はあまり良い名前ではありませんが、内部EEPROM用ですが、同じテクニックをI2C EEPROM
乾杯!
BW:どのAT24CXXXライブラリを使用していますか?これは奇妙に見えるので。
uint8_t readEE(uint8_t entry) {
readEEPROM(AT24C32_ADDRESS, 1, entry);
}
返品明細書等はありません
これは単純なプリプロセッサマクロで実現できます:
#define readEE(VAR) VAR = readEEPROM(AT24C32_ADDRESS, 1, VAR ## Pos)
あなたは次に使用することができます:
readEE(foo);
それは次のように展開されます:
foo = readEEPROM(AT24C32_ADDRESS, 1, fooPos);
マクロの ##
演算子は、両辺(VARとPos)を展開し、結果を連結します。 VAR自体はマクロなので(マクロを呼び出すときに渡すもの)、その値で置き換えられますが、Posではマクロではないため、Posのままです。だからあなたの変数名は、単語Posと連結して終わる。
変数名は配列内の変数名を持つループで使用することはできません - 変数名はコンパイルされたコードではなくソースコードにのみ存在するため、これらの変数名では何もできません。コンパイルされた。したがって、プリプロセッサを使用してジョブを実行する必要があります。
はい、120変数すべてに対して120行のコードを書く必要がありますが、 readEE(varname);
に短縮されています。
しかし、もっと良い解決策はMikaelのstructメソッドを使うか、単に配列を使って名前の概念について違った考えをすることです:
uint8_t data[120];
for (int i = 0; i < 120; i++) {
data[i] = readEEPROM(AT24C32_ADDRESS, 1, i);
);
したがって、すべての変数の値は data []
配列にあり、プログラム内でどの値がどの値であるかを知るだけで済みます。そして、各位置の名前をプリプロセッサマクロ:
#define FAN_SPEED 12
#define N1_TOGGLE 95
#define LEDS_TOGGLE 7
次に、数値の代わりにそれらのマクロを使用します。
Serial.println(data[FAN_SPEED]);
あるいは、マクロを使用して変数名を「マスク」することもできます。
#define fanSpeed data[12]
#define n1Toggle data[95]
#define ledsToggle data[7]
あなたが気づいたかもしれないことが1つあります:ここではあなたのコードを短縮するものはありません。 120の場所に120個の変数が格納されています。あなたが何をしても、それらの変数とその場所に何らかの形の120個のポインタが必要です。あなたが本当に行うことができるのは、コードを見ている誰かが何が起こっているのかを理解できるように、最も可読性が高いメソッドを選択することです。あなたが何をしているにしても、定義や設定を行う変数や変数名のリストがたくさんあります。これはたくさんの型付けを意味します。