🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

Q&A

解決済

2回答

1478閲覧

【Arduino】PINCとPINLの値について

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Arduino

Arduinoは、AVRマイコン、単純なI/O(入出力)ポートを備えた基板、C言語を元としたArduinoのプログラム言語と、それを実装した統合開発環境から構成されたシステムです。

マイコン

マイクロコンピュータの略で、CPUにマイクロプロセッサを用いたコンピュータのこと。家電製品、電磁機器などの制御に用いられています。単体でコンピュータとしての機能を一通り備えています。 現代のパーソナルコンピュータに近く、同時期のメインフレームやミニコンピュータと比べ、小さいことが特徴です。

0グッド

0クリップ

投稿2019/09/17 08:00

編集2019/09/18 07:27

結論

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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/09/17 08:03

具体的にどういう不具合があるのかを説明してくれませんか コードからそれを読み取れというのは面倒でやってられませんw
guest

回答2

0

ベストアンサー

iomxx0_1.h にて

#define PINA _SFR_IO8(0X00) #define PINB _SFR_IO8(0X03) #define PINC _SFR_IO8(0x06) #define PIND _SFR_IO8(0x09) #define PINE _SFR_IO8(0x0C) #define PINF _SFR_IO8(0x0F) #define PING _SFR_IO8(0x12) #define PINH _SFR_MEM8(0x100) #define PINJ _SFR_MEM8(0x103) #define PINK _SFR_MEM8(0x106) #define PINL _SFR_MEM8(0x109)

と定義されています、PINA は変数ではなく ポートA入力レジスタ です
PINA と比較は、ポートA を読みだして比較しているにすぎません

digitalRead 内部構造
https://garretlab.web.fc2.com/arduino/inside/hardware/arduino/avr/cores/arduino/wiring_digital.c/digitalRead.html

投稿2019/09/17 12:01

編集2019/09/17 13:48
koujikuu

総合スコア401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/18 07:24 編集

PINAなどという値があるわけではなくPINAを参照することで直接レジスタの値を読み出す仕組みになっている・・・ということなのでしょうか。 提示していただいたサイトで勉強してみます。ありがとうございます!
guest

0

ざっとみて気のついたところですが、
入力ポート設定のところで内蔵プルアップの設定をしていないように見えます。

そうだとすれば、オープンの端子のレベルは不定になりますんで、値が変動するようにも見えますね

投稿2019/09/17 08:12

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/09/18 00:22

内臓プルアップどころかプルアップ抵抗のことも知りませんでした。 スイッチがある場合はマイコン側に優先して電力が流れ込みHIGH状態として入力されるような状態になる・・・といった説明のあるサイトを見つけました。 常にHIGH状態になるよう設定するものとして理解しました。 早速設定してみます、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問