編集履歴一覧に戻る
Carlosのアイコン画像

Carlos が 2021年02月26日12時59分47秒 に編集

初版

タイトルの変更

+

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

タグの変更

+

Arduino

+

AVR

+

7segment

+

電子工作

+

秋葉原2021

本文の変更

+

## 概要 **Arduino Uno**と**2桁7セグメントLED**を使い、0~99までカウントする装置の作り方を説明する。カウントアップ、カウントダウン、リセット機能を備えている。また、さらなる小型化を目指すため、ArduinoからAVRマイコンへ移植した。 実際は... ~~アミューズメント会社からUFOキャッチャーで景品を取るごとに景品獲得数をカウントする装置を作って欲しいという案件があった。完成し、連絡したが返事が来ない。結局、案件は**なかったこと**に。大切な時間をかけて作ったカウンターを無駄にしたくないので**elchika**に投稿することにした。~~ ## 材料 ![キャプションを入力できます](https://camo.elchika.com/c56ff2ba3e8cf168f4a23c083fbdaa8379feddde/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64383262366631652d643539362d343966352d613861622d3864623166313665326435372f30366436393463302d303763382d346333622d623333362d343865613961313933666233/) - Arduino Uno - AVRマイコン(ATtiny2313) - AVRライター(AVRWRT3) - 電源 (単三電池2本) - 2桁7セグメントLEDアノードコモン - タクトスイッチ 3つ - 抵抗330Ω 10個 ## 使用ソフト - Arduino IDE - Microchip Studio - AVRWRT ## 2桁7セグメントLEDのピン配置 # Arduino版 ## 配線 ![Arduino版](https://camo.elchika.com/5347be824c62b29e3a5d898cdd2ec43c7995ee25/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64383262366631652d643539362d343966352d613861622d3864623166313665326435372f36323733323735342d646631372d346665312d613264312d636335623534363566643361/) ## ソースコード ```c++: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版 ## ATtiny2313のピン配置 ![キャプションを入力できます](https://camo.elchika.com/29b56ee21b326e2be736a41c9a809bd8e20ff377/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64383262366631652d643539362d343966352d613861622d3864623166313665326435372f36363235333638652d393937352d343133382d613064302d306633383135356536346438/) [MIcrochip社 ATtiny2313サイト](https://www.microchip.com/wwwproducts/en/ATtiny2313) ## 配線 ![キャプションを入力できます](https://camo.elchika.com/ad42801dca865464bbebbb558392a6fc8185eebe/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64383262366631652d643539362d343966352d613861622d3864623166313665326435372f61383732643835372d353539322d343130372d393335642d303761316336353034663031/) ## ソースコード ```c: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; } ```