結論
PINAやPINCなるマクロは定数として数値を返すわけではなく、端子の入力を読み取って返してくれるため構造体のメンバとして持たせる発想が間違いでした。
ほかのアプローチでソースを作成します。
前提・実現したいこと
変数でPINA,PINC,PINLなどとして定義されている値を取得したい。
Arduinoの入力の取得を高速化する手法としてdigitalRead(22)
のかわりにPINA&_BV(0)
をスケッチに記述する方法をとろうとしています。
いま、構造体にPINAなどと定義されている値を格納して利用しようとしています。
cpp
1// structs.h 2struct PinPorts { 3 char pinDivision; 4 int pin; 5}; 6 7volatile uint8_t InterpretPinDivision(PinPorts pinInfo);
しかし以下のコードのコメントのような現象が発生しており、どうすれば良いのかわからなくなっています。
cpp
1const PinPorts info1 = {'a', 0}, //digitalRead(22)として 2 info2 = {'a', 6}, //digitalRead(28)として 3 info3 = {'c', 3}, //digitalRead(34)として 4 info4 = {'g', 1}, //digitalRead(40)として 5 info5 = {'l', 2}; //digitalRead(46)として 6 7void setup() { 8 // Arduinoセッティング 9 DDRB = B11110001; //pinMode(50-53,13,OUTPUT); 10 DDRA = B00000000; //pinMode(22-29,INPUT); 11 DDRC = B00000000; //pinMode(30-37,INPUT); 12 DDRL = B00000000; //pinMode(42-49,INPUT); 13 DDRG = B00001000; //pinMode(39-41,4,OUTPUT); 14 SD.begin(4);//SDカードモジュールのCS(Card Select)ピン // このデバイスはいまは使っていませんが端子を接続した状態で存在しています。 15 Serial.begin(9600);//シリアル通信 16 17 // 困っている部分 18 Serial.println(PinDivisionString(InterpretPinDivision(info1))); 19 // PINA がシリアルモニタに出力される。問題なし。 20 Serial.println(PinDivisionString(InterpretPinDivision(info2))); 21 // PINA がシリアルモニタに出力される。問題なし。 22 Serial.println(PinDivisionString(InterpretPinDivision(info3))); 23 // PINA などがシリアルモニタに出力される。PINCを指定したつもりなので何か間違ってる。またPINCが出力される場合もあって値が不安定。 24 Serial.println(PinDivisionString(InterpretPinDivision(info4))); 25 // PING などがシリアルモニタに出力される。問題なし。 26 Serial.println(PinDivisionString(InterpretPinDivision(info5))); 27 // PINC がシリアルモニタに出力される。PINLを指定したつもりなので何か間違っている。 28} 29 30String PinDivisionString(uint8_t pinDiv) 31{ 32 if( pinDiv == PINA) 33 { 34 return "PINA"; 35 } 36 else if(pinDiv == PINC) 37 { 38 return "PINC"; 39 } 40 else if(pinDiv == PING) 41 { 42 return "PING"; 43 } 44 else if(pinDiv == PINL) 45 { 46 return "PINL"; 47 } 48 else 49 { 50 return "PINX"; 51 } 52} 53 54volatile uint8_t InterpretPinDivision(PinPorts info) 55{ 56 if( info.pinDivision == 'a') 57 { 58 return PINA; 59 } 60 else if( info.pinDivision == 'c') 61 { 62 return PINC; 63 } 64 else if( info.pinDivision == 'g') 65 { 66 return PING; 67 } 68 else if( info.pinDivision == 'l') 69 { 70 return PINL; 71 } 72} 73
マイコンなどの知識がないため適切な言葉を選択して質問できていないかもしれませんが、どうかご教授いただきたいです。宜しくお願いいたします。
発生している問題・エラーメッセージ
PINAなどと定義されている定数?が変数や構造体に思ったとおりに格納できていないように見える。
構造体にPINXのXとなる部分の1文字をchar型で持つ ↓ InterpretPinDivision関数の引数にcharを与え、内部で指定したかったPINXを選択してvolatile uint8_t型として返す処理を行う ↓ 確認としてPinDivisionString関数の引数にuint8_t型としてInterpretPinDivision関数の戻り値を与え、実際に定数PINA,PINC...などと比較して合致したPINXがどれかを文字列にして返す
といった処理を行っているのですが、PinDivisionString関数の戻り値が指定したかったPINXと異なるPINXを指定してしまっているような結果にななります。
また、PINCを指定した場合に最終的にPINCと一致する場合があったりPINAと一致する場合があったりと、値が不安定になっているようにみえます。
- 値が変動する。
- 想定した値が入っていないようにみえる。
試したこと
volatile uint8_t
はArduino1.8.9が型変換の例外が発生したことを通知したことがあり、その際に知りました。
volatile
修飾子については調べても「ポインタの親戚かな?」くらいの認識しか持てていません。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
- Arduino MEGA
- Arduino 1.8.9
- Windows 7 64bit
回答2件
あなたの回答
tips
プレビュー