Arduinoで入出力を高速化する方法

スポンサーリンク
スポンサーリンク

Arduinoは遅すぎて処理が追いつかない、クソじゃねーか!ってことで標準入出力を高速化しましょう。レジスタからピンを操作すれば複数のピンを同時に制御することも出来ます。

デジタル出力(digitalWrite)を高速化

まずは普通のLチカ

void setup() {
  pinMode(8, OUTPUT);
}
void loop() {
  digitalWrite(8,HIGH);
  delay(500);
  digitalWrite(8,LOW);
  delay(500);
}

同じ処理をavrっぽく書くと処理を高速化することが出来ます。

void setup() {
  DDRB |= 0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をOUTPUT
}
void loop() {
  PORTB |= 0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をHIGH
  delay(500);
  PORTB &= ~0b00000001;//ポートBの0番ピン(Arduinoの8番ピン)をLOW
  delay(500)
}

DDRB,DDRDでポートB,ポートCの入力,出力を決めます。二進数で表すと0b00000000の右から0番ピン、1番ピンの順で対応しています。0は入力、1は出力

Arduino UnoではdigitalWrite(pin,HIGH)は以下のように対応しています。

Arduinoレジスタ表記
digitalWrite(0, HIGH ) PORTD |= 0b00000001
digitalWrite(1, HIGH ) PORTD |= 0b00000010
digitalWrite(2, HIGH ) PORTD |= 0b00000100
digitalWrite(3, HIGH ) PORTD |= 0b00001000
digitalWrite(4, HIGH ) PORTD |= 0b00010000
digitalWrite(5, HIGH ) PORTD |= 0b00100000
digitalWrite(6, HIGH ) PORTD |= 0b01000000
digitalWrite(7, HIGH ) PORTD |= 0b10000000
digitalWrite(8, HIGH ) PORTB |= 0b00000001
digitalWrite(9, HIGH ) PORTB |= 0b00000010
digitalWrite(10, HIGH ) PORTB |= 0b00000100
digitalWrite(11, HIGH ) PORTB |= 0b00001000
digitalWrite(12, HIGH ) PORTB |= 0b00010000
digitalWrite(13, HIGH ) PORTB |= 0b00100000

digitalWrite(pin,LOW)については以下の表のようになります。

Arduinoレジスタ表記
digitalWrite(0,LOW) PORTD &= ~ 0b00000001
digitalWrite(1, LOW ) PORTD &= ~ 0b00000010
digitalWrite(2, LOW ) PORTD &= ~ 0b00000100
digitalWrite(3, LOW ) PORTD &= ~ 0b00001000
digitalWrite(4, LOW ) PORTD &= ~ 0b00010000
digitalWrite(5, LOW ) PORTD &= ~ 0b00100000
digitalWrite(6, LOW ) PORTD &= ~ 0b01000000
digitalWrite(7, LOW ) PORTD &= ~ 0b10000000
digitalWrite(8, LOW ) PORTB &= ~ 0b00000001
digitalWrite(9, LOW ) PORTB &= ~ 0b00000010
digitalWrite(10, LOW ) PORTB &= ~ 0b00000100
digitalWrite(11, LOW ) PORTB &= ~ 0b00001000
digitalWrite(12, LOW ) PORTB &= ~ 0b00010000
digitalWrite(13, LOW ) PORTB &= ~ 0b00100000

Arduino Uno以外は異なるので、arduinoとavr のピン対応を調べてから書きましょう。

複数のピンを同時に操作

レジスタから操作すると複数のピンを同時に変更できます。以下は2番ピンから13番ピンを全て使ったLチカのスケッチです。ただし、全てのピンにLEDをつけると電流が流れすぎるので大きな抵抗を使いましょう。

void setup() {
  DDRD |= 0b11111100;//ポートDの2~7番ピンをOUTPUT
  DDRB |= 0b00011111;//ポートBの0~4番ピンをOUTPUT
}
void loop() {
  PORTD |= 0b11111100;//ポートDの2~7番ピンをHIGH
  PORTB |= 0b00011111;//ポートBの0~4番ピンをHIGH
  delay(500);
  PORTD &= ~0b11111100;//ポートDの2~7番ピンをLOW
  PORTB &= ~0b00011111;//ポートBの0~4番ピンをLOW
  delay(500)
}

デジタル入力(digitalRead)を高速化

bool state = 0;
void setup() {
  DDRB = 0b00000000;//ポートBを全てINPUT
}
void loop() {
  state = (PINB>>1) & 0b00000001;//state = digitalRead(9)と同じ
}
digitalReadレジスタ表記
digitalRead(0)PIND & 0b00000001
digitalRead(1) (PIND>>1) & 0b00000001
digitalRead(2) (PIND>>2) & 0b00000001
digitalRead(3) (PIND>>3) & 0b00000001
digitalRead(4) (PIND>>4) & 0b00000001
digitalRead(5) (PIND>>5) & 0b00000001
digitalRead(6) (PIND>>6) & 0b00000001
digitalRead(7) (PIND>>7) & 0b00000001
digitalRead(8) PINB & 0b00000001
digitalRead(9) (PINB>>1) & 0b00000001
digitalRead(10) (PINB>>2) & 0b00000001
digitalRead(11) (PINB>>3) & 0b00000001
digitalRead(12) (PINB>>4) & 0b00000001
digitalRead(13) (PINB>>5) & 0b00000001

↓ArduinoでAVRのように表記すれば、処理を高速化したりといろいろ便利なことがあると思います。

コメント