Arduino Logic Gates

Hello!

I have a logical gate with 3 inputs: a, b and c and an output "y".

How can I simplify this code:

#define DI0 2
#define DI1 3
#define DI2 4

int a = 0; // input logic gate
int b = 0; // input logic gate
int c = 0; // input logic gate
int y = 0;

void setup(){
  pinMode(DI0, INPUT_PULLUP);
  pinMode(DI1, INPUT_PULLUP);
  pinMode(DI2, INPUT_PULLUP);
}
void loop(){
  a = digitalRead(DI0);
  b = digitalRead(DI1);
  c = digitalRead(DI2);

  if ( a == HIGH && b == HIGH && c == HIGH ) {
       y = 0;
  }
  if ( a == HIGH && b == HIGH && c == LOW ) {
       y = 1;
  }
  if ( a == HIGH && b == LOW && c == HIGH ) {
       y = 2;
  }
  if ( a == HIGH && b == LOW && c == LOW ) {
       y = 3;
  }
  ...
  if ( a == LOW && b == LOW && c == LOW ) {
       y = 7;
  }

}

Do you understand binary?

I know to read binary
1001 1001 = hex 99

And in my program:
if(a==1 && b==1 && c==1){ // to me the input logic is inverted 111 = 0
// it is right 111 = 7
y=0;
}

But I'm not interested in this. I want 101 at y = 0;
The important thing is if you can simplify the code.
Thank you!

I want 101 at y = 0;

?

if ( a == HIGH && b == HIGH && c == HIGH ) {
       y = 0;
  }

But I'm not interested in this. I want 101 at y = 0;

There is a bit of a conflict between those two statements.

If you want:
111 = 0
110 = 1
101 = 2
100 = 3
011 = 4
etc.

Using the bitWrite function.

// change the states of a, b, c  and run 
boolean a = HIGH; // input logic gate
boolean b = LOW; // input logic gate
boolean c = LOW; // input logic gate
int y = 0;

void setup()
{
   Serial.begin(115200);
   bitWrite(y, 0, !a);
   bitWrite(y, 1, !b);
   bitWrite(y, 2, !c);
   Serial.print(" the value of y = ");
   Serial.println(y);
}

void loop()
{
}

If this is not what you want, please present a full truth table.

Sometimes I'm confused what "simplify the code" means. Do you mean:

  1. Rewrite the code to use fewer lines,
    or:
  2. Write the code so the compiler generates "better" code,
    or:
  3. Make the code easier to read?

The first goal doesn't always promote the third goal, and usually the compiler does a pretty good job on 2 regardless of the exact nature of the other two. Because so much time in code development is spent testing and debugging, I'd lean towards #3, not #1.

ok ok! It was just an example of the logic of the entrance.
In fact, according to counting circuits: (binary) 101 = (hex) 5;
A logic gate may be different.

Let's resume. Modified Code:

...
if ( a == 0 && b == 0 && c == 0 ) {
      y = 0;
 }
 if ( a == 0 && b == 0 && c == 1 ) {
      y = 1;
 }
 if ( a == 0 && b == 1 && c == 0 ) {
      y = 2;
 }
 if ( a == 0 && b == 1 && c == 1 ) {
      y = 3;
 }
 ...
 if ( a == 1 && b == 1 && c == 1 ) {
      y = 7;
 }

}

So, use the bitWrite solution, without the inversion.

Change

bitWrite(y, 0, !a);
   bitWrite(y, 1, !b);
   bitWrite(y, 2, !c);

To

bitWrite(y, 0, a);
   bitWrite(y, 1, b);
   bitWrite(y, 2, c);

Am I wasting my time?

econjack:
...
3) Make the code easier to read?

The first goal doesn't always promote the third goal, and usually the compiler does a pretty good job on 2 regardless of the exact nature of the other two. Because so much time in code development is spent testing and debugging, I'd lean towards #3, not #1.

Indeed, option 3 is ok, but I wanted to simplify the code.

void loop() 
{
  y = (!digitalRead(DI0) * 4) + (!digitalRead(DI1) * 2) + (!digitalRead(DI2));
}

If you want it faster, use the bottom three pins in a port:

void loop() 
{
  // On an UNO, use a=Pin 10, b=Pin 9, c=Pin 8
  y = (~PINB) & 0x07;
}

Then I'd use John's last solution. Of course, come back a month later and you'll probably spend a little time remembering what it means and, as John carefully points out, that solution may not be portable.

y = a & b & c;     // a gate has a single output

boolrules:

y = a & b & c;     // a gate has a single output

Only if you COMPLETELY ignore what the OP is trying to achieve...
Regards,
Ray L.

va_cristi:
I have a logical gate with 3 inputs: a, b and c and an output "y".

Just because he's confused doesn't mean I'm confused.

johnwasser:
Using the ifs:
Sketch uses 2322 bytes (7%) - Global variables use 196 bytes (9%)
Using this code:

void loop() 

{
  y = (!digitalRead(DI0) * 4) + (!digitalRead(DI1) * 2) + (!digitalRead(DI2));
}



Resulted:
Sketch uses 2104 bytes (7%) - Global variables use 190 bytes (9%)

And using this code


void loop()
{
  // On an UNO, use a=Pin 10, b=Pin 9, c=Pin 8
  y = (~PINB) & 0x07;
}



Resulted:
Sketch uses 1872 bytes (6%) - Global variables use 190 bytes (9%)

Thanks for your help, Mr. John!

My code looks like this:

// Using Arduino NANO
// Control of two pumps

#define DI0 A0
#define DI1 A1
#define DI2 A2

int a = 0;
int b = 0;
int c = 0;

int y = 0;

int AI0 = A6;
int AI1 = A7;

int di = 0;
int ai0 = 0;
int ai = 0;

int vin0 = 0;
float volt0 = 0.0;

int timer1_counter;

void setup() {
  Serial.begin(9600);

  pinMode(DI0, INPUT_PULLUP);
  pinMode(DI1, INPUT_PULLUP);
  pinMode(DI2, INPUT_PULLUP);

  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Timer 1
  // initialize timer1
  noInterrupts();           // disable all interrupts
  TCCR1A = 0;
  TCCR1B = 0;

  timer1_counter = 15624;   // 34286  preload timer 65536-16MHz/256/2Hz
  // 15624 1Hz / 8192
  TCNT1 = timer1_counter;   // preload timer
  TCCR1B |= (1 << CS12);    // 256 prescaler
  TIMSK1 |= (1 << TOIE1);   // enable timer overflow interrupt
  interrupts();
  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}

ISR(TIMER1_OVF_vect)        // interrupt service routine
{
  TCNT1 = timer1_counter;   // preload timer

  vin0 = analogRead(AI0);

  //  if ( menu == 1) {
  volt0 = vin0 * (5.0 * 11 / 1023);

  if ( volt0 >= 1.2 ) {
    ai0 = 1;
  }
  if ( volt0 <= 0.8 ) {
    volt0 = 0;
    ai0 = 0;
  }
  if ( volt0 >= 10 ) {
    volt0 = 9.99;
  }
}

void loop() {
//  a  = digitalRead(DI0);
// b  = digitalRead(DI1);
// c  = digitalRead(DI2);

  // On an UNO, use a=Pin 10, b=Pin 9, c=Pin 8
  //y = (~PINB) & 0x07;

  //y = (!digitalRead(DI0) * 4) + (!digitalRead(DI1) * 2) + (!digitalRead(DI2));


  di = (!digitalRead(DI0) * 8) + (!digitalRead(DI1) * 4) + (!digitalRead(DI2) * 2) + (ai0);

  Serial.print(ai0);
  Serial.print(" | ");
  Serial.print(di);
  Serial.print(" | ");
  if (di == 0) {
    Serial.println("Pumps OFF");
  }
  if (di == 1) {
    Serial.println("Pump1 ON");
  }
  if (di == 2) {
    Serial.println("Pumps OFF");
  }

  if (di == 3) {
    Serial.println("Pump2 ON");
  }

  if (di == 4) {
    Serial.println("Pumps OFF");
  }

  if (di == 5) {
    Serial.println("Pump1 ON/Pump2 ON");
  }

}