Carlosのアイコン画像
Carlos 2021年02月26日作成 (2021年12月09日更新) © MIT
製作品 製作品 閲覧数 23599
Carlos 2021年02月26日作成 (2021年12月09日更新) © MIT 製作品 製作品 閲覧数 23599

Arduinoを使った7セグ2桁カウンター

概要

Arduino Uno2桁7セグメントLEDを使い、0~99までカウントする装置の作り方を説明する。カウントアップ、カウントダウン、リセット機能を備えている。また、さらなる小型化を目指すため、ArduinoからAVRマイコンへ移植した。

実際は...
アミューズメント会社からUFOキャッチャーで景品を取るごとに景品獲得数をカウントする装置を作って欲しいという案件があった。完成し、連絡したが返事が来ない。結局、案件はなかったことに。大切な時間をかけて作ったカウンターを無駄にしたくないのでelchikaに投稿することにした。

Markdownを使うのは初めてであり、elchikaに記事を書くのも初めてである。

材料

  • Arduino Uno
  • AVRマイコン(ATtiny2313)
  • AVRライター(AVRWRT3)
  • 電源 (単三電池2本)
  • 2桁7セグメントLEDアノードコモン
  • タクトスイッチ 3つ
  • 抵抗330Ω 10個

材料について
・電池ではなくブレッドボード用電源モジュールでもいい
・AVRライターは何でもいい(多分)

使用ソフト

  • Arduino IDE
  • Microchip Studio
  • AVRWRT(デジットホームページより)

Microchip Studioについて
・12月頃にAtmel StudioからMicroship Studioへ名称が変更した。

2桁7セグメントLEDのピン配置

キャプションを入力できます

7セグの種類
カソードコモンでもいいが多少プログラムの書き換えが必要

配線

Arduino版

ソースコード

Arduino_conter.ino

//a : 13 //b : 11 //g : 10 //f : 9 //d : 8 //e : 6 //dp : 5 //c : 4 //A1 :12 //A2 :7 // LEDをオン・オフする際の出力 #define DIGIT_ON LOW #define DIGIT_OFF HIGH #define SEGMENT_ON HIGH #define SEGMENT_OFF LOW const int up_button = 19; //カウントアップボタン const int down_button = 18; //カウントダウンボタン const int reset_button = 17; //リセットボタン //チャタリング防止用変数 int old_val1 = 1;  int old_val2 = 1; int old_val3 = 1; int up = 0; int down = 0; int reset = 0; int i = 0; const int digitPins[] = {5,4}; // ディジット(アノード)に接続するArduinoのピン const int segmentPins[] = {13,12,11,10,9,8,7,}; // セグメントに接続するArduinoのピン const int numberOfDigitPins = sizeof(digitPins) / sizeof(digitPins[0]); // ディジットの数 const int numberOfSegmentPins = sizeof(segmentPins) / sizeof(segmentPins[0]); // セグメントの数 // 数字と表示させるセグメントの関係 const int digits[] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00100111, // 7 0b01111111, // 8 0b01101111, // 9 }; // 数字を表示する void displayNumber(int n) { // digits[n]の各ビットを調べて対応するセグメントを点灯・消灯する for (int i = 0; i < numberOfSegmentPins; i++) { digitalWrite(segmentPins[i], digits[n] & (1 << i) ? SEGMENT_OFF : SEGMENT_ON); } } // セグメントをすべてオフにする void clearSegments() { for (int j = 0; j < numberOfSegmentPins; j++) { digitalWrite(segmentPins[j], SEGMENT_OFF); } } // 4桁の数字を表示する void displayNumbers(int n) { for (int i = 0; i < numberOfDigitPins; i++) { // 右の桁からディジットを選択する digitalWrite(digitPins[i], DIGIT_ON); // ディジットをオンにする displayNumber(n % 10); // 10で割った余りを求めて、1の位を求め、表示する delay(12); // 12ms停止 clearSegments(); // セグメントをすべてオフにする digitalWrite(digitPins[i], DIGIT_OFF); // ディジットをオフにする n /= 10; // 10で割り、次に表示する数字を、1の位に移す } } // setup() は,最初に一度だけ実行される void setup() { pinMode(up_button, INPUT_PULLUP ); pinMode(down_button, INPUT_PULLUP ); pinMode(reset_button, INPUT_PULLUP ); for (int i = 0; i < numberOfDigitPins; i++) { pinMode(digitPins[i], OUTPUT); // digitPinsを出力モードに設定する digitalWrite(digitPins[i], DIGIT_OFF); } for (int i = 0; i < numberOfSegmentPins; i++) { pinMode(segmentPins[i], OUTPUT); // segmentPinsを出力モードに設定する } Serial.begin( 9600 ); } //loop() は繰り返し実行される void loop() { up = digitalRead(up_button); down = digitalRead(down_button); reset = digitalRead(reset_button); //以下チャタリング防止のプラグラム if((up == 0) && (old_val1 == 1)){ if(i == 99){ i = 0; } else{ i++; } }else if((i != 0) && (down == 0) &&(old_val2 == 1)){ i--; }else if((reset == 0) &&(old_val3 == 1)){ i = 0; } displayNumbers(i); old_val1 = up; old_val2 = down; old_val3 = reset; }

AVR版

今思うと PICマイコンでもよかったが、家にAVRライターが転がってたのでAVRマイコンを使用することにした。しかし、ネット・書籍とも情報が少なくArduinoからAVRへの移行に苦戦した。簡単なやり方がありらしいが、今回はゼロから書くことにした。

ATtiny2313のピン配置

キャプションを入力できます
MIcrochip社 ATtiny2313サイト

配線

キャプションを入力できます

ソースコード

avr_counter

/* PINS No. a :PD0 b :PD1 c :PD2 d :PD3 e :PD4 f :PD5 g :PD6 A1 :PB0 A2 :PB1 up_btn :PB2 down_btn :PB3 rst_btn :PB4 */ #include <avr/io.h> #include <util/delay.h> //チャタリング防止用変数 int old_val1 = 1; int old_val2 = 1; int old_val3 = 1; int up = 0; int down = 0; int reset = 0; int i = -1; const int digitPins[] = { 0b00000010, //1桁目 0b00000001, //2桁目 }; const int digits[] = { 0b11000000, //0 0b11111001, //1 0b10100100, //2 0b10110000, //3 0b10011001, //4 0b10010010, //5 0b10000010, //6 0b11011000, //7 0b10000000, //8 0b10010000, //9 }; // 2桁の数字を表示する void displayNumbers(int n) { for (int i = 0; i < 2; i++) { // 右の桁からディジットを選択する PORTB = digitPins[i]; // ディジットをオンにする PORTD = digits[n % 10]; // 10で割った余りを求めて、1の位を求め、表示する _delay_ms(12); // 12ms停止 PORTD = 0b00000000; // セグメントをすべてオフにする PORTB = 0b00000000; // ディジットをオフにする n /= 10; // 10で割り、次に表示する数字を、1の位に移す } } int main(void) { DDRD = 0b11111111; //PIN D DDRB = 0b00000011; //PIN B PORTD = 0b11111111; //ループ while(1){ if((PINB&0b00000100)==0b00000000){ //UPボタン up = 1; }else{ up = 0; } if((PINB&0b00001000)==0b00000000){ //DOWNボタン down = 1; }else{ down = 0; } if((PINB&0b00010000)==0b00000000){ //RESETボタン reset = 1; }else{ reset = 0; } if((up == 0) && (old_val1 == 1)){ if(i == 99){ i = 0; } else{ i++; } }else if((i != 0) && (down == 0) &&(old_val2 == 1)){ i--; }else if((reset == 0) &&(old_val3 == 1)){ i = 0; } displayNumbers(i); //数字iを表示 old_val1 = up; old_val2 = down; old_val3 = reset; } return 0; }

##動作映像

ここに動画が表示されます

今後

キャプションを入力できます
オープンソースPCB-CAD 【Kicad】を使って、回路設計までできた。今後、中国の基盤発注業者【Electrow】に基盤の発注を注文をしようかと思う。それについての記事も書こうかな?

感想

Fritzingを使うのも初めてなので、回路図がとても汚い...
製作にあたってわからないことがあればコメントください。

1
  • Carlos さんが 2021/02/26 に 編集 をしました。 (メッセージ: 初版)
  • Carlos さんが 2021/02/26 に 編集 をしました。
  • Opening
    yyyのアイコン画像 yyy 2021/10/23

    コメント失礼いたします。arduino版の実際に組んだ回路図を見せていただけないでしょうか。自分が組んだところ上手く作動しなくて困っています。

    Carlosのアイコン画像 Carlos 2021/11/17

    返事が遅れてすみません、回路は解体してしまいました。
    配線図のとおりに組んでもらうと動くはずですが...

    1 件の返信が折りたたまれています
  • Carlos さんが 2021/12/09 に 編集 をしました。
ログインしてコメントを投稿する

投稿者の人気記事