/*
  Simulação de 6 portas lógicas com Franzininho DIY

  Projeto adaptado do exemplo do site:
  https://dronebotworkshop.com/basic-logic/

  Notas:
    - Use as teclas A e B com o foco no editor de diagramas
      para interagir com as entradas.

    - Pressione a tecla CTRL enquanto clica no botão para
      manter o botão pressionado, solte a tecla CTRL e clique no botão para liberar. 
*/

#include <TinyDebug.h>

#define Serial Debug

// Define as entradas booleanas
boolean inA;
boolean inB;

// Define as saídas booleanas
boolean outXNOR;
boolean outXOR;
boolean outNOR;
boolean outOR;
boolean outNAND;
boolean outAND;

// Define os botões
int pbA = 0;
int pbB = 1;

// Define os LEDs de saída lógica
int ledXNOR = 5;
int ledXOR = 5;
int ledNOR = 3;
int ledOR = 3;
int ledNAND = 2;
int ledAND = 2;

// Define os LEDs de entrada lógica
int ledA = 4;
int ledB = 4;

unsigned long timerPrint = 0;

void setup() {
  // Inicializa o monitor serial
  Serial.begin();

  // Define os botões de pressão como entradas
  pinMode(pbA, INPUT_PULLUP);
  pinMode(pbB, INPUT_PULLUP);

  // Define os LEDs como saídas
  pinMode(ledXNOR, OUTPUT);
  pinMode(ledXOR, OUTPUT);
  pinMode(ledNOR, OUTPUT);
  pinMode(ledOR, OUTPUT);
  pinMode(ledNAND, OUTPUT);
  pinMode(ledAND, OUTPUT);
  pinMode(ledA, OUTPUT);
  pinMode(ledB, OUTPUT);
}

void loop() {
  // Leia os botões e atribuí valores aos booleanos de entrada
  inA = digitalRead(pbA) == LOW;
  inB = digitalRead(pbB) == LOW;

  // Exibe as entradas do botão de pressão nos LEDs
  digitalWrite(ledA, inA);
  digitalWrite(ledB, inB);

  // Computa as saídas lógicas
  outXNOR = !(inA ^ inB);
  outXOR = inA ^ inB;
  outNOR = !(inA | inB);
  outOR = inA | inB;
  outNAND = !(inA & inB);
  outAND = inA & inB;

  if ((millis() - timerPrint) >= 1000) {
    timerPrint = millis();
    // Exibe os resultados
    Serial.print("IN-- A:");
    Serial.print(inA);
    Serial.print(" B:");
    Serial.print(inB);
    Serial.print(" --- OUT-- AND:");
    Serial.print(outAND);
    Serial.print(" NAND:");
    Serial.print(outNAND);
    Serial.print(" OR:");
    Serial.print(outOR);
    Serial.print(" NOR:");
    Serial.print(outNOR);
    Serial.print(" XOR:");
    Serial.print(outXOR);
    Serial.print(" XNOR:");
    Serial.println(outXNOR);
  }

  digitalWrite(ledAND, outAND);
  digitalWrite(ledOR, outOR);
  digitalWrite(ledXOR, outXOR);
}