SSブログ

Digisparkで複数のタクトスイッチを扱う [Arduino]

Digisparkは使用できるピンが少ないので工夫が必要。
analogRead()で複数のタクトスイッチを扱う方法が、以下のページです。

I/Oピン一つで読めるキーパッドの設計サービス
https://synapse.kyoto/tool/ResDiv/page001.html

抵抗分圧により複数のボタンの識別をしています。
ライブラリもあるようですが、ブラックボックス化したくないので自作します。
抵抗値の計算もできますが、大まかな値を確認し、自分が持っている抵抗(E6系列中心でまちまち)でもできるよう、エクセルで分圧の計算もしました。

 Vout= Vcc × (R2+R3+…+Rn) / (R1+R2+…+Rn)

閾値は、それぞれの分圧の中間値として、それを10ビット(0~1023)の値に換算しました。
resvoldiv.png
あと、analogRead()は遅いらしいので、すべてのボタンは押されたときの電圧がdigitalRead()のLow判定電圧未満としておき、digitalRead()でLowになったら、あらためてanalogRead()で値を読むということにしました。

digitalRead()のLow判定電圧ですが、

Arduino Unoの入力スレッショルド電圧を測ってみる(閾値電圧) | のぶらぼ
https://nobulabo.com/arduino-uno-threshold-level/

「HIGH⇒LOW(VIL)は2.2V、LOW⇒HIGH(VIH)は2.6V、その差であるヒステリシス電圧は0.4Vであることがわかりました。」
とありました。

ATtiny25/V / 45/V / 85/V のデータシート
https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf

186, 187ページの「22.7 Pin Threshold and Hysteresis」の項目をみるとVcc 5Vのとき
HIGH⇒LOW(VIL)は2.25V、LOW⇒HIGH(VIH)は2.5V あたりです。

タクトスイッチが押されたとき(HIGH⇒LOW)を確認したいので、分圧電圧を2.25V未満に抑えることにしました。



押されたボタン(SW1~SW4)の番号の回数分 LEDを点滅させるスケッチです。
// Check multiple buttons with one pin for digispark
//
//   Vcc--R1--+----+-R2-+-R3-+-R4-+      (R1:4.7k, R2:680, R3,R4:1k)
//            |   sw1  sw2  sw3  sw4
//            P2   +----+----+----+----GND
//
const uint16_t Vth[] = {0,  64, 199, 320};  // threshold (intermediate value between voltages -> 10bit)

void setup() {
  pinMode(2, INPUT);                        // P2:Buttons (D2/A1)
  pinMode(1, OUTPUT);                       // P1:Built-in LED (D1)
}

void loop() {
  uint8_t  btn=0;                           // pressed button number (0 if none are pressed)
  uint16_t val;                             // variable to store the value read
  if( !digitalRead(2) ) {                   // Read Button number
    delay(10);                                              // chattering control
    val = analogRead(1);                                    // read the input pin
    for(btn=1; btn<sizeof(Vth)>>1 && val>Vth[btn]; btn++);  // Advance the btn until the Vth is exceeded
    while( !digitalRead(2) );                               // Wait until the button is released 
  }
  for(; btn; btn--) {                       // Blinks the LED for the number of button numbers
    digitalWrite(1, HIGH);
    delay(100);
    digitalWrite(1, LOW);
    delay(200);
  }
}

タグ:Digispark
nice!(0)  コメント(0) 

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。