web-dev-qa-db-ja.com

pinMode OUTPUTにあるピンをデジタルで読み取るにはどうすればよいですか?

非常に単純なテスト sketch があります。このテストでは、ピンをHIGHに設定し、digitalReadでその状態を読み取ろうとしています。これが私のスケッチです。

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    delay(1000);

    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH);
    delay(1000);

    pinMode(3, INPUT);
    Serial.println(digitalRead(3));
}

シリアルモニターの結果:

0
0
0
0

PinModeを変更すると、HIGHにならないようになります。したがって、ピンをHIGHモードでOUTPUTに設定してからINPUTモードに変更すると、ピンはLOWに変更されます。したがって、digitalReadは常に0を返します。pinModeを変更しないと、ピンを読み取ることができません。それでは、値を失わずにOUTPUTモードにあるピンの現在の設定をどのように読み取ることができますか?

29
Bazzz

この場合、データレジスタ自体にアクセスするだけです。

PORTBおよびPORTDレジスタには、探しているピンデータが含まれています。私はついにそれを理解するためにArduinoにアクセスできました。 bitRead(PORTD, pin)を使用します。

Serial.println(bitRead(PORTD,3)); //Reads bit 3 of register PORTD which contains the current state (high/low) of pin 3.

リファレンス ビット読み取り操作 詳細については。

32
MikeRags

あなたのスケッチは

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    delay(1000);

    pinMode(3, OUTPUT);
    digitalWrite(3, HIGH);
    delay(1000);

    // pinMode(3, INPUT); // get rid of this line
    Serial.println(digitalRead(3));
}

それで全部です。次に、ピンの状態を読み取ります。この状態は、「HIGH」です。 pinModeをinputに設定すると、接続されているものに応じて入力を読み取ります。入力ピンに「HIGH」を書き込むと、内部プルアップがアクティブになります。入力モードに設定する前にHIGHを書き込んでも、入力モードに設定した後にHIGHを書き込んでもかまいません。もちろん、出力ピンに対して高すぎる負荷を駆動している場合を除きます(たとえば、グランドへのスイッチ)。そして、これはおそらくピンを殺すでしょう。

ローを書き込んでピンをローに設定すると、フロートが発生し、予測できない動作が発生する可能性があります。

32
Udo Klein
digitalWrite(3,HIGH);
digitalRead(3);
4
msj003

以前の回答は、arduino-プラットフォーム間の互換性がないため、好きではありませんでした。ピン参照表からアクセスする必要があります。次の式がトリックを行います。

_bool value = (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
_

理解を深めるためにそれを分解しましょう

digitalPinToPort(pin)は、選択したハードウェアでピンが割り当てられているgpioバンク[ポート]を検索します

portOutputRegister(...)は、探している値を含むポートへのポインターを提供します。 *ポインターを逆参照し、そのポートに割り当てられている8つのピンすべての完全な値を提供します。それはまだユニークに有用ではありませんが、あなたが探しているビットはそこにあります。

&digitalPinToBitMask(pin)は、ピンに関心のあるビットのみを選択し、他のすべてのビットはゼロになります。

0!=は、結果の式がゼロであるか、他の何かであるかどうかをテストします。ゼロの場合、そのピンの出力はゼロです。それ以外の場合、出力は1です。

3
user2825128

pinMode()関数でsetup()を選択したままにして、digitalWrite()およびdigitalRead()関数を試してください。

setup()はコントローラーの起動時に実行され、loop()は実行を継続する関数になります。

int pin22 = 22;
void setup()
{
  Serial.begin(9600);
  pinMode(pin22,output);
}

void loop()
{
  digitalWrite(pin22,HIGH);
  digitalRead(pin22);
  digitalWrite(pin22,LOW);
  digitalRead(pin22);
}
2
AMPS

どうしてそんなことをしたいのですか?ピンが本当に高いことを検証するためにこれを行っている場合、外部回路からの高いピンに短絡がある可能性があるため、これはあなたにそれを確認しません。別のピンを入力として設定し、出力ピンを新しい入力ピンに接続して、その値を読み取ります。内部レジスタを読み取ると、実際のピン値ではなく、コントローラがピンに配置しようとしているものが常に返されます。

2
Karim

さまざまな目的で4つの異なるLEDをフラッシュするルーチンを作成しましたが、フラッシュする前に初期状態を保持したかったため、定常状態からコードで何かが発生していることがわかりますので、これをフラッシュコードと呼びます。ピン番号、フラッシュ回数、フラッシュ時間を送信します。

inline void Flash (byte pinNum, byte times, byte flashSpeed)
  {
    bool state;                     // Local var for State of pin
    state = digitalRead(pinNum);    // Read the current state as set elsewhere
    int x;                          // Local var for repeat flash
    for (x = 0; x < times; x++)
      {
        digitalWrite(pinNum, HIGH); // Turn on LED
        delay(flashSpeed);
        digitalWrite(pinNum, LOW);  // Turn off LED
        delay(flashSpeed * 2);      //  leave off twice as long as on
      }                             //  due to persistence of Vision   
    digitalWrite(pinNum, state);    // Restore the original state of the LED
  }
0
KeyWizard

出力ピンの状態の個別のブールマップを保持します。

マイクロコントローラのGPIOピンが入力として設定されている場合、その値は、読み取られたときに、外部に接続されているものに依存します。それは一種のポイントです。

0
Martin James

デフォルト入力をHIGHに設定しようとしていますか?
プルアップレジスタをアクティブにする場合:

void setup() 
{
    Serial.begin(9600);
}

void loop() 
{
    delay(1000);

    pinMode(3,INPUT);         // default mode is INPUT  
    digitalWrite(3, HIGH);    // Turn on the internal pull-up resistor, default state is HIGH  

    delay(1000);
    Serial.println(digitalRead(3));
}

DigitalWrite からの抜粋:

ピンがINPUTとして設定されている場合、digitalWrite()でHIGH値を書き込むと、内部20Kプルアップ抵抗が有効になります。

0
ssapkota