Arduino付き2ビット加算器

だから私はブレッドボード、4つのスイッチ、3つのLEDとArduinoを使って2ビットの加算器を作ることを任されました。問題は、(少なくとも私のコードでは)競合する2つのことを加算器が実行することです。1つ目は、1つのスイッチをオンにすると1つのライト(001)しか点灯しないことです。 00、これは1つのスイッチだけがオンになることを意味し、(私のコードが述べているように)それはちょうど中間のもの(010)ではなく両方に対応するライトをつけることになります。私はそれが私のifステートメントの最初のビットと関係があるという事実を知っています、ここにコードがあります:

int A0Pin = 12;
int A1Pin = 11;
int B0Pin = 10;
int B1Pin = 9;

int LED0Pin = 6;
int LED1Pin = 5;
int LED2Pin = 4;

void setup()
{
  pinMode(A0Pin, INPUT);
  pinMode(A1Pin, INPUT);
  pinMode(B0Pin, INPUT);
  pinMode(B1Pin, INPUT);

  pinMode(LED0Pin, OUTPUT);
  pinMode(LED1Pin, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
}

void loop()
{
  int b1Value = digitalRead(A0Pin);
  int b2Value = digitalRead(A1Pin);
  int b3Value = digitalRead(B0Pin);
  int b4Value = digitalRead(B1Pin);

  digitalWrite(LED0Pin, LOW);
  digitalWrite(LED1Pin, LOW);
  digitalWrite(LED2Pin, LOW);

  if (b1Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
  }
  if (b2Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
  }
  if (b3Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
  }
  if (b4Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
  }
  if(b1Value == HIGH && b3Value == HIGH )
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,LOW);
  }
  if(b2Value == HIGH && b4Value == HIGH )
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,HIGH);
  }
  if(b2Value == HIGH && b3Value == LOW && b4Value == LOW)
  {
   digitalWrite(LED0Pin,LOW);
   digitalWrite(LED1Pin,HIGH);
   digitalWrite(LED2Pin,LOW);
  }
  if(b1Value == LOW && b2Value == LOW && b4Value == HIGH)
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,LOW);
  }
  if(b1Value == HIGH && b2Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,LOW);
  }
  if(b3Value == HIGH && b4Value == HIGH)
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,LOW);
  }
  if(b1Value == HIGH && b2Value == HIGH && b4Value == HIGH)
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,HIGH);
   }
  if(b2Value == HIGH && b4Value == HIGH && b2Value == HIGH)
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,HIGH);
  }  
  if(b1Value == HIGH && b2Value == HIGH && b3Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,HIGH);
  }
   if(b3Value == HIGH && b4Value == HIGH && b1Value == HIGH)
  {
    digitalWrite(LED0Pin,HIGH);
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,HIGH);
  }
  if(b1Value == HIGH && b2Value == 
     HIGH && b3Value == HIGH && b4Value == HIGH)
  {
    digitalWrite(LED0Pin,LOW);
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,HIGH);
  }
  delay(10);
}

最適化の欠如を言い訳してください(それは私が問題を解明した後に来ることができます)、最適化についてのどんな助けも大いに感謝されるでしょう、しかし今のところ私はちょうど01 + 00 don ' 1つのスイッチだけがオンになっているために混乱してしまい、両方のライトがオンになっているか1つだけになっていますが、誤っています。私はTinkercadでそれを作りました:

回路図:

Circuit diagram

01 + 01 = 010

01 + 01 = 010

最初のスイッチだけ(01 + 00 = 001)

最初のスイッチだけ(01 + 00 = 001)

2つ目のスイッチを入れるだけで、10 + 00 = 010と誤解された(またはその逆)

2つ目のスイッチを入れるだけで、10 + 00 = 010と誤解された(またはその逆)

1
追加された 編集された
ビュー: 1
ru de
ここで要点が(論理ポートを使って)古典的な方法で加算器を書くことであれば、理想的には if はまったく表示されず、代わりにほとんどビット演算子だけが表示されるはずです。代わりに、マイクロコントローラに実際に適した方法で加算器を実装したい場合、明らかな方法は入力を2つの unsigned 変数に読み込み、それらを + </で合計することです。 >演算子をコード化し、結果を出力に書き出します。
追加された 著者 Matteo Italia,
サンプル入力、希望する出力、現在の出力の組み合わせを見せてください。それはあなたがあなたのコードの振る舞いに関して嫌いなことを示しています。ただし、 else if を使用し、 if の順序を逆にすることをお勧めします。あるいは、各 if についてすべての入力を考慮に入れてください。
追加された 著者 Yunnosch,
ビット演算子 ^については、すでに学びましたか。
追加された 著者 Yunnosch,
うーん、コンプ科学はあなたがXORゲートとANDゲートから半加算器を作ることについて学ぶところであるべきです。 circuitstoday.com/half-adder-and-full-adder おそらくその詳細レベルではないでしょう。
追加された 著者 Yunnosch,
私はあなたが暗黙のうちに2つの調整された符号なしのintに標準の + 演算子を使用することを許可されていないと思いますか?
追加された 著者 Yunnosch,
はい、 + &Coを使用することは許可されていますか、それともそれらを使用することは禁止されていますか?
追加された 著者 Yunnosch,
sum = switch0 * 1 + switch1 * 2 + switch2 * 1 + switch3 * 2; はどうですか。次に、 sum に設定されているビットに基づいてLEDを点灯します。
追加された 著者 Yunnosch,
@Yunnosch私はそれらが何であるかわかりません、それはcomp sciが前提条件ではない工学コースです、また私は写真を加えるために編集するつもりです
追加された 著者 Professor Doctor Doctor,
それはかなりオープンエンドです(そうはい)、私は論理的に見てそれをやっています
追加された 著者 Professor Doctor Doctor,
はい、許可されています、申し訳ありませんが明確になっている必要があります
追加された 著者 Professor Doctor Doctor,
@Yunnosch私はそれを実装しようとしました、しかし、私はそれを正しくやったとは思いません、あなたはそれがどのように見えるかの少し下にあなたに正当化できますか?
追加された 著者 Professor Doctor Doctor,

4 答え

まあ、まず第一に:あなたが選んだものよりもはるかに良いアプローチがあります。しかし、この答えはあなたのアプローチに固執し、あなたのコードが失敗する理由を説明します。

私があなたのアプローチの背後にある考えを言うことができる限り:

1)入力がHIGHの場合(つまり、すべてのLEDを点灯させることから始める場合)をカバーします。 1ケース

2)ちょうど1入力が高い場合をカバー4件

3)正確に2つの入力が高い場合をカバーしてください。 6件

4)正確に3つの入力が高い場合をカバーしてください。 4件

5)4つの入力すべてがハイの場合をカバーしてください。 1ケース

ステップ5はステップ4よりも優先され、ステップ4はステップ3よりも優先されるため、このアプローチは有効です。例えば、あなたが間違った出力を設定したとしても。ステップ4、ステップ5で修正されます(すべての入力がHIGHの場合)。

それでは、あなたのコードの何が問題になっていますか?

The problem is that you don't cover all cases. For instance you never cover b1 and b4 both being HIGH.

また、ここにタイプミスがあります。

if(b2Value == HIGH && b4Value == HIGH && b2Value == HIGH)
   ^^^                                   ^^^

さらに、あなたのコードはあなたがここで行うように決してLOWをチェックしてはいけません:

if(b2Value == HIGH && b3Value == LOW && b4Value == LOW)

LOW値は、ifステートメントの優先順位によって暗黙的に処理されます。

合計で15のifステートメントを初期化したものが必要です。

だからあなたのコードは次のようになります。

 //Handle 1 case with no input high
  digitalWrite(LED0Pin, LOW);
  digitalWrite(LED1Pin, LOW);
  digitalWrite(LED2Pin, LOW);

 //Handle 4 cases with exactly 1 input being high
  if (b1Value == HIGH)
  {
      ...
  }
  else if (b2Value == HIGH)
  {
      ...
  }
  else if (b3Value == HIGH)
  {
      ...
  }
  else if (b4Value == HIGH)
  {
      ...
  }

 //Handle 6 cases with exactly 2 input being high
  if(b1Value == HIGH && b2Value == HIGH )
  {
    ...
  }
  else if(b1Value == HIGH && b3Value == HIGH )
  {
    ...
  }
  else if(b1Value == HIGH && b4Value == HIGH)
  {
    ...
  }
  else if(b2Value == HIGH && b3Value == HIGH)
  {
    ...
  }
  else if(b2Value == HIGH && b4Value == HIGH)
  {
    ...
  }
  else if(b3Value == HIGH && b4Value == HIGH)
  {
    ...
  }

 //Handle 4 cases with exactly 3 input being high
  if(b1Value == HIGH && b2Value == HIGH  && b3Value == HIGH)
  {
      ...
  }
  else if(b1Value == HIGH && b2Value == HIGH  && b4Value == HIGH)
  {
      ...
  }
  else if(b1Value == HIGH && b3Value == HIGH  && b4Value == HIGH)
  {
      ...
  }
  else if(b2Value == HIGH && b3Value == HIGH  && b4Value == HIGH)
  {
      ...
  }

 //Handle 1 cases with exactly 4 input being high
  if(b1Value == HIGH && b2Value == HIGH && b3Value == HIGH && b4Value == HIGH)
  {
      ...
  }

上記はコードが機能しない理由とその修正方法を説明しています。

しかしあなたが見ることができるようにアプローチは非常に誤りがちである(すなわちそれはケースを見逃すことがとても簡単である)。それに加えて、それはまた悪いパフォーマンスを持っています。だから私はもっと簡単なアプローチをお勧めします。

int temp = 2 * digitalRead(A1Pin) +
               digitalRead(A0Pin) +
           2 * digitalRead(B1Pin) +
               digitalRead(B0Pin);

output0 = (temp & 1) == 1;
output1 = (temp & 2) == 2;
output2 = (temp & 4) == 4;
2
追加された

ピンのラベルは、 A1PinA0Pin などです。変数名も同じ規則に従います。 a1Valuea0Value </これは if 文を理解しやすくします。

それなら、 if ステートメントについて体系的になる必要があります。 4つの入力では、16通りの組み合わせがあり、それぞれに if ステートメントが必要です。また、すべての if ステートメントで every の入力値を確認する必要があります。

最初の2つの if ステートメントは

if (a1Value == LOW && a0Value == LOW && b1Value == LOW && b0Value == LOW)
{
    digitalWrite(LED0Pin,LOW);  //0 + 0 = 0
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
}
else if a1Value == LOW && a0Value == LOW && b1Value == LOW && b0Value == HIGH) 
{
    digitalWrite(LED0Pin,HIGH); //0 + 1 = 1
    digitalWrite(LED1Pin,LOW);
    digitalWrite(LED2Pin,LOW);
}

そして最後の if ステートメントは

else if (a1Value == HIGH && a0Value == HIGH && b1Value == HIGH && b0Value == HIGH)
{
    digitalWrite(LED0Pin,LOW);  //3 + 3 = 6
    digitalWrite(LED1Pin,HIGH);
    digitalWrite(LED2Pin,HIGH);
}

あと13行あります。

もちろん、これを実行する方法は他にもありますが、私はあなたが始めたことを終わらせるのを手伝うだけでよいと思いました。

コードが機能したら、コードレビューに投稿して、最適化方法に関するさまざまな提案を得ることができます。

1
追加された

それはむしろあなたが全加算器をシミュレートするのか、それをエミュレートするのかを任されているかどうかによって異なります。あなたがそれをエミュレートしているならば、あなたはピンが(少なくともほとんどの変種のために)AVRポートに割り当てられているという事実を使うことができます。

void loop() {
    int a = (PORTB >> 3) & 3;//take the two 'A' bits from the input port and make a number between 0 and 3
    int b = (PORTB >> 1) & 3;//likewise for 'B'
    PORTD = ( a + b ) << 4;  //add them together and shift to light the LEDs
}

7482を持っていなくて、それをエミュレートしたいのであれば、これが私のやり方です。

ロジックを組み合わせて全加算器を作成する方法を実証することを目的としている場合は、半加算器ロジック sum = a xまたはbcarry = a and b を使用して作成します全加算器ロジック sum =(a xまたはb)xまたはc carry =(aとb)または(cと(a xor b))

void loop() {
   //input a as two separate bits
    bool a0 = digitalRead(A0Pin);
    bool a1 = digitalRead(A1Pin);

   //input b as two separate bits
    bool b0 = digitalRead(B0Pin);
    bool b1 = digitalRead(B1Pin);

   //half adder for digit 0 of output sum and carry
    bool s0 = a0 ^ b0;
    bool c0 = a0 & b0;

   //full adder for digit 1 of output sum and carry
    bool s1 = (a1 ^ b1) ^ c0;
    bool c1 = (a1 & b1) | (c0 & (a1 ^ b1));

    digitalWrite(LED0Pin, s0);
    digitalWrite(LED1Pin, s1);
    digitalWrite(LED2Pin, c1);//digit2 of output will be carry from digit 1
}

ここでの違いは、動作していることを示していることと、真理値表を一連のifステートメントに変換するのではなく、加算器が何のためにあるのかを理解したことをインストラクターに伝えることです。あなたは2ビット加算器のためにそれを回避するかもしれません、しかし、あなたは手作業で例えば8ビット加算器のすべての可能な入力と出力を書き出したくありません。

1
追加された

Yunnosch氏のコメントに続いて、これは彼があなたが追加の価値を事前に計算して、それからコードを大いに単純化するLEDにそれを表示することができるということであるという意味です 以下のコードはうまくいくはずです - あるいは少なくともガイドラインとして役立ちます 私はあなたが論理を理解するための例でコメントしました、それが助けを願っています

注:私はArduinoの前にいないので、このコードはテストされていません - しかしそれはコンパイルします

int A0Pin = 12;
int A1Pin = 11;
int B0Pin = 10;
int B1Pin = 9;

int LED0Pin = 6;
int LED1Pin = 5;
int LED2Pin = 4;

void setup()
{
  pinMode(A0Pin, INPUT);
  pinMode(A1Pin, INPUT);
  pinMode(B0Pin, INPUT);
  pinMode(B1Pin, INPUT);

  pinMode(LED0Pin, OUTPUT);
  pinMode(LED1Pin, OUTPUT);
  pinMode(LED2Pin, OUTPUT);
}

void loop()
{
  int b1Value = digitalRead(A0Pin);
  int b2Value = digitalRead(A1Pin);
  int b3Value = digitalRead(B0Pin);
  int b4Value = digitalRead(B1Pin);

 //b1 is set to represent 1 and b2 will represent 2 same with b3 and b4 pair
 //lets assume b1 = 1 b2 = 0 the number is 1
 //b3 is set to 1 and b4 is set to 1
 //input : b2|b1 + b4|b3
 //         0| 1    1| 1
 //sum = 1*1 + 0*2 + 1*1 + 1*2 = 4 - which is represented in binary as b100
  int sum = (b1Value * 1) + (b2Value * 2) + (b3Value * 1) + (b4Value * 2);

  if (sum & 0x1) //binary rep b001 - following the example will result in 0
    digitalWrite(LED0Pin, HIGH);
  else
    digitalWrite(LED0Pin, LOW);

  if (sum & 0x2) //binary rep b010 - following the example will result in 0
    digitalWrite(LED1Pin, HIGH);
  else
    digitalWrite(LED1Pin, LOW);

  if (sum & 0x4) //binary rep b100 - following the example will result in 1
    digitalWrite(LED2Pin, HIGH);
  else
    digitalWrite(LED2Pin, LOW);

  delay(10);
}
1
追加された