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

K が 2020年05月02日18時58分49秒 に編集

コメント無し

記事種類の変更

+

製作品

本文の変更

# はじめに Arduinoとタクトスイッチ(入力)、LED(出力)を使って簡単な足し算ができる計算機を作ってみました。 完成した計算機はこんな感じです。2進数2bit同士の足し算をすることができます。 ![製作した2bit加算器](https://camo.elchika.com/237e1574ffbac34acd514cf000a236b3a126389d/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f33613430313133352d373738622d343131382d386436352d653366643135666535636263/) 今回の投稿ではまず加算器を作る為に必要な論理回路、半加算器、全加算器について簡単に説明し、最終的にはArduinoを使って2bit加算器を実装するところまでやっていきたいと思います。 # 論理回路 コンピュータは様々な計算や処理を行いますが、それらの多くは論理演算によって実行されています。論理演算とは、「ある事柄が〇(つまり1)か×(つまり0)か」を判断する演算です。この論理演算を行う回路のことを論理回路と言います。ここでは基本的な3つの論理回路(AND, OR, NOT)と、加算器を作る為に必要なXOR回路の説明をしたいと思います。 ## AND(論理積) 2つの入力が共に1である時に1を返します。それ以外の時は0を返します。 |入力a|入力b|出力| |:---:|:---:|:---:| |0|0|0| |0|1|0| |1|0|0| |1|1|1| ![AND(論理積)](https://camo.elchika.com/5bbf01098724519d355a5bc6567ab08e6f029459/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f36363834623631352d663737652d343632302d613535362d616438353139646233666463/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:AND(論理積) int AND(int a,int b){ int c = a and b; return c; } ``` ## OR(論理和) 2つの入力の少なくともどちらか一方が1である時、1を返します。共に0である時は0を返します。 |入力a|入力b|出力| |:---:|:---:|:---:| |0|0|0| |0|1|1| |1|0|1| |1|1|1| ![OR(論理和)](https://camo.elchika.com/ed2c352c683ad1e1bf34755874b0bbff62f8bccb/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f36383466363666622d313166352d343737342d626638362d333735623235313139353630/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:OR(論理和) int OR(int a,int b){ int c = a or b; return c; } ``` ## NOT(否定) 入力が0であれば反対の1を出力し、入力が1であれば反対の0を出力します。 |入力|出力| |:---:|:---:|:---:| |0|1| |1|0| ![NOT(否定)](https://camo.elchika.com/e20fe911b0f3acfcfbedf39a4f457f08f7b37ece/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f62316265613630322d353930612d343032612d386630312d306234653438316365386566/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:NOT(否定) int NOT(int a){ int b = not(a); return b; } ``` ## XOR(排他的論理和) 2つの入力が異なる時に1を返します。同じ時は0を返します。 |入力a|入力b|出力| |:---:|:---:|:---:| |0|0|0| |0|1|1| |1|0|1| |1|1|0| ![XOR(排他的論理和)](https://camo.elchika.com/c923fc4a94b77e583bfbbffd70de886576c5df22/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f62633534303137392d663935622d343965662d383137642d373239613066653639363564/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:XOR(排他的論理和) int XOR(int a,int b){ int c = a^b; return c; } ``` # 半加算器 半加算器は、2進数1桁の足し算をする回路です。計算結果は1桁目をSで、2桁目をCで出力します。ちなみに、Sは英語で「合計」を表す「Sum」の頭文字で、Cは英語で「桁上がり」を表す「Carry」の頭文字です。 ![半加算器](https://camo.elchika.com/e4ade5b27ee79bb429640926cbf742afafed806b/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f61323335303065622d386635612d346436332d613437372d336530636232323763353739/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:半加算器 //AND(論理積) int AND(int a,int b){ int c = a and b; return c; } //XOR(排他的論理和) int XOR(int a,int b){ int c = a^b; return c; } //半加算器 int HALF_ADDER(int a,int b,int *C,int *S){ *C = AND(a,b); *S = XOR(a,b); } ``` # 全加算器 2桁以上の2進数を足し算すると、2桁目以上の桁では、下の桁からの桁上がりを足さなければならない場合があります。このような、下の桁からの桁上がりを加算できる加算器を全加算器といいます。1桁目には桁上がりがないので半加算器を使い、2桁目以上の足し算には全加算器を使います。 ![全加算器](https://camo.elchika.com/48874f95787a7974b39de60185248e37002c2682/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f38393735656464332d333634362d343435322d383961352d366535373938336432393438/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:全加算器 //AND(論理積) int AND(int a,int b){ int c = a and b; return c; } //OR(論理和) int OR(int a,int b){ int c = a or b; return c; } //XOR(排他的論理和) int XOR(int a,int b){ int c = a^b; return c; } //半加算器 int HALF_ADDER(int a,int b,int *C,int *S){ *C = AND(a,b); *S = XOR(a,b); } //全加算器 int FULL_ADDER(int a,int b,int c, int *C,int *S){ int half_adder_carry1,half_adder_sum1; int half_adder_carry2,half_adder_sum2; HALF_ADDER(a,b,&half_adder_carry1,&half_adder_sum1); HALF_ADDER(c,half_adder_sum1,&half_adder_carry2,&half_adder_sum2); *C = OR(half_adder_carry1,half_adder_carry2); *S = half_adder_sum2; } ``` # 2bit加算器 半加算器1つと全加算器1つを組み合わせることで2bit加算器ができます。2bit同士の2入力で最大3bitまでの出力をします。下の図ではS0が1の位、S1が2の位で、Cが最大の3の位の出力となります。 ![2bit加算器](https://camo.elchika.com/c45c5da15afe112070733d86209941ee9c2d2f43/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f62663333636436392d386230352d346237342d396632622d343231313661333335656536/)   ([論理回路エディタ](https://www.belltree.tokyo/logic-circuit-editor/)を用いて作成) Arduino言語でコードにしてみるとこのようになります。 ```arduino:2bit加算器 //AND(論理積) int AND(int a,int b){ int c = a and b; return c; } //OR(論理和) int OR(int a,int b){ int c = a or b; return c; } //XOR(排他的論理和) int XOR(int a,int b){ int c = a^b; return c; } //半加算器 int HALF_ADDER(int a,int b,int *C,int *S){ *C = AND(a,b); *S = XOR(a,b); } //全加算器 int FULL_ADDER(int a,int b,int c, int *C,int *S){ int half_adder_carry1,half_adder_sum1; int half_adder_carry2,half_adder_sum2; HALF_ADDER(a,b,&half_adder_carry1,&half_adder_sum1); HALF_ADDER(c,half_adder_sum1,&half_adder_carry2,&half_adder_sum2); *C = OR(half_adder_carry1,half_adder_carry2); *S = half_adder_sum2; } //2進数2桁同士の足し算 int FULL_ADDER_2BIT(int a1,int a0,int b1,int b0,int *result_2,int *result_1,int *result_0){ int half_adder_carry,half_adder_sum; int full_adder_carry1,full_adder_sum1; HALF_ADDER(a0,b0,&half_adder_carry,&half_adder_sum); FULL_ADDER(a1,b1,half_adder_carry,&full_adder_carry1,&full_adder_sum1); *result_2 = full_adder_carry1; *result_1 = full_adder_sum1; *result_0 = half_adder_sum; } ``` # Arduinoを使った2bit加算器 ここまで、論理回路から2bit加算器まで順番に解説をしてきました。それでは、この章ではいよいよArduinoで2bit加算器を実装してみたいと思います。 ## 使用したもの ・[Arduino Uno R3](http://akizukidenshi.com/catalog/g/gM-07385/) ・[ジャンパワイヤ](http://akizukidenshi.com/catalog/g/gC-05159/) ・[ブレッドボード](http://akizukidenshi.com/catalog/g/gP-05294/) ・[赤色LED×3](http://akizukidenshi.com/catalog/g/gI-11655/) ・[10kΩ抵抗×7](http://akizukidenshi.com/catalog/g/gR-25103/) ・[タクトスイッチ×4](http://akizukidenshi.com/catalog/g/gP-03646/) ※上記は全て秋葉原にある秋月電子さんで購入することができます。筆者もそこで購入しました。 ## 回路図 計算機の配線図です。配線図は[Fritzing](https://fritzing.org/home/)を用いて作成しました。 ![計算機の配線図](https://camo.elchika.com/4da61e656f357231c2f70b6dbe2518fedb0f2f24/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f37346566393138372d326164312d343964372d393931322d3863373135366234353136392f36616434306136342d613963322d346662342d396266352d613061666231623963383236/) それぞれのタクトスイッチはGNDにプルダウンしているので、スイッチが押されたときは「HIGH」、押されていないときは「LOW」がArduinoに入力されます。 ## プログラム 計算機のプログラムです。[Arduino](https://www.arduino.cc/)の統合開発環境である[Arduino IDE](https://www.arduino.cc/en/Main/Software)を用いて作成しました。 簡単にプログラムの説明をします。 まず最初に、タクトスイッチの入力データを受け取るデジタルI/Oピンと、使用するLEDのデジタルI/Oピンの番号を定数で宣言します。 setup()関数内ではタクトスイッチが接続されているデジタルI/Oピンをそれぞれ入力に設定し、LEDが接続されているデジタルI/Oピンをそれぞれ出力に設定します。 loop関数内ではそれぞれのタクトスイッチの入力を読み取り、自作したFULL_ADDER_2BIT関数で足し算を実行します。計算結果はdigitalWrite関数で出力されます。 ```arduino:制御プログラム //入力a const int input_a0 = 4; //入力aの1桁目 const int input_a1 = 5; //入力aの2桁目 //入力b const int input_b0 = 6; //入力bの1桁目 const int input_b1 = 7; //入力bの2桁目 //出力 const int output_0 = 10; //出力の1桁目 const int output_1 = 11; //出力の2桁目 const int output_2 = 12; //出力の3桁目 void setup(){ //タクトスイッチが接続されているそれぞれのピンを入力に設定 pinMode(input_a0,INPUT); pinMode(input_a1,INPUT); pinMode(input_b0,INPUT); pinMode(input_b1,INPUT); //LEDが接続されているそれぞれのピンを出力に設定 pinMode(output_0,OUTPUT); pinMode(output_1,OUTPUT); pinMode(output_2,OUTPUT); } void loop(){ //それぞれのタクトスイッチから入力を受け取る int state_a0 = digitalRead(input_a0); int state_a1 = digitalRead(input_a1); int state_b0 = digitalRead(input_b0); int state_b1 = digitalRead(input_b1); int result_0,result_1,result_2; FULL_ADDER_2BIT(state_a1,state_a0,state_b1,state_b0,&result_2,&result_1,&result_0); //足し算をする関数を実行 //計算結果を出力 digitalWrite(output_0,result_0); digitalWrite(output_1,result_1); digitalWrite(output_2,result_2); } //AND(論理積) int AND(int a,int b){ int c = a and b; return c; } //OR(論理和) int OR(int a,int b){ int c = a or b; return c; } //XOR(排他的論理和) int XOR(int a,int b){ int c = a^b; return c; } //半加算器 int HALF_ADDER(int a,int b,int *C,int *S){ *C = AND(a,b); *S = XOR(a,b); } //全加算器 int FULL_ADDER(int a,int b,int c, int *C,int *S){ int half_adder_carry1,half_adder_sum1; int half_adder_carry2,half_adder_sum2; HALF_ADDER(a,b,&half_adder_carry1,&half_adder_sum1); HALF_ADDER(c,half_adder_sum1,&half_adder_carry2,&half_adder_sum2); *C = OR(half_adder_carry1,half_adder_carry2); *S = half_adder_sum2; } //2進数2桁同士の足し算 int FULL_ADDER_2BIT(int a1,int a0,int b1,int b0,int *result_2,int *result_1,int *result_0){ int half_adder_carry,half_adder_sum; int full_adder_carry1,full_adder_sum1; HALF_ADDER(a0,b0,&half_adder_carry,&half_adder_sum); FULL_ADDER(a1,b1,half_adder_carry,&full_adder_carry1,&full_adder_sum1); *result_2 = full_adder_carry1; *result_1 = full_adder_sum1; *result_0 = half_adder_sum; } ``` ## 動かし方 プログラムの書き込みが成功したら、実際にタクトスイッチを押してみてください。計算結果がLEDで出力されると思います! # おわりに 今回Arduinoを使って簡単な足し算ができる計算機を作ってみました。 足し算などの複雑な処理が論理回路の組み合わせでできるなんて、本当にロマンがありますね! 今回学んだことを生かして、次はArduinoで簡単な引き算ができる計算機を作ってみたいと思います。 また、質問や疑問点、ここを直したほうがいいよ等有りましたら、コメントよろしくお願いします。 # Author

-

[Twitter ID : __nk0917](https://twitter.com/__kei0917)

+

[Twitter ID : __kei0917](https://twitter.com/__kei0917)