Check Gate Logic with Arduino

Bom dia a todos, estou desenvolvendo uma aplicação para facilitar a minha vida como professor e de meu estagiário, trata-se do seguinte, usando dois arduinos em master/slave, sendo o master ligado ao pc via usb, através da comunicação serial pretendo desenvolver uma aplicação desktop para o futuro, no momento a idéia é que o master envia via i2c para o slave qual porta lógica testar.

o problema: algo que ainda não consegui ver no código esta fazendo com que o teste não ocorra.
em anexo o source do slave e do master, juntamente como schematic da montagem, peço ajuda para concluir este projeto. nos source deixei pronto somente para testar o 7400, depois q funcionar implanto os outros testes.

master_writer.ino (2.25 KB)

slave.ino (8.68 KB)

Desculpa a pergunta idiota, mas porque queres dois Arduinos a fazer isto?

Um dos problemas que vejo é não estares a limitar o numero de caracteres que são lidos. Ou seja:

  if (Serial.available()){
    int sr = Serial.parseInt();
    if (sr == 7400){f = 1; p = 1; b = 4;}

Se receberes o 7, o primeiro if é verdadeiro. Dessa forma, o sr será 7 em vez de 7400.
Para tal, creio que é melhor fazeres algo como:

if (Serial.available()>=4){//existem pelo menos 4 caracteres

Porque é que tens mais um pino para ligar/desligar o outro Arduino? O I2C pode acordar o outro lado sem precisares duma "sincronização" destas.

No código do slave eu trocaria todos os estados dos pinMode por uma matriz multidimensional para poupar código... ou fazer código mais bonito.

O mesmo se aplicaria ao código para testar. Dessa forma não tinhas de repetir código da forma que estás a fazer.

Se definires o que queres dizer com "o teste não ocorra", ajudaria imenso a pelo menos saber onde olhar... a comunicação funciona entre ambos os Arduinos?
Eu vejo que ambos têm a porta série utilizada, logo isto deve ser possível de testar... Por outro lado o facto de usares dois Arduinos para isto abre imensas possibilidades de problemas sem benefício algum.

Ahh, eu também não confio na função ParseInt... mas tu lá sabes.

obrigado pelas dicas, pensei em usar um Mega, mas estou sem um no momento e tenho 22 Unos.

  • Vou tirar o parseInt para testar;
  • Errei no desenho, o pino 2 do master esta no reset no slave;
  • vou implantar a matriz, realmente nem passou pela minha cabeça. valeu!
  • Tive uma ideia para tirar o Master.
    vou colocar em prática se der certo ou não volto a relatar!.

O facto de teres 22 Unos não explica usares dois Arduinos para a função de um.

Tenta explicar ao certo onde é que o programa pára ou não faz o que pretendes para ser mais simples de testar.

de fato foi vacilo meu tentar usar 2 arduino, estou implantando apenas com um.
Identifiquei meu erro, estava eu setando as ios do arduino com o mesmo formato da porta. assim esta eu usando input do arduino ligado a input do 7400... :o :o kkkk assim não ia mesmo, estou implantando agora as suas ideias, assim que ter algo mais concreto mostro aqui o source para mais sugestões. vlw :smiley:

Então, reformulei com um Arduino Uno, mexi no código, mas ainda esta dando erro, pois ele esta dizendo que todos os CI que tenho estão com problemas! isso não é verdade!!!
segue o código:

/*
Dado armazenado na memoria: (byte 0)
7400, 7408, 7432, 7486, 7409                 == 1;
7402                                         == 2;
7404, 7405, 7406, 7407, 7416, 7417, 7414     == 3;
7420, 7421, 7422                             == 4;
7430                                         == 5;

Dado armazenado na memoria: (byte 1)
  "00" = 1
  "02" = 2
  "04" = 3
  "05" = 4
  "06" = 5
  "07" = 6
  "08" = 7
  "09" = 8
  "14" = 9
  "16" = 10
  "17" = 11
  "20" = 12
  "21" = 13
  "22" = 14
  "30" = 15
  "32" = 16
  "86" = 17                               

*/
#include <EEPROM.h>


bool p7400[4][3] = {{0,0,1},{0,1,1},{1,0,1},{1,1,0}};
bool p7408[4][3] = {{0,0,0},{0,1,0},{1,0,0},{1,1,1}};
bool p7402[4][3] = {{0,0,1},{0,1,0},{1,0,0},{1,1,0}};
byte fLogic = 0;
byte pLogic = 0;
bool e[4];
byte f, p = 0;
int b = 0;
//PARA INPUT = 1, PARA OUTPUT = 0
bool ports[5][12] = {{1,1,0,1,1,0,0,1,1,0,1,1}, 
                     {0,1,1,0,1,1,1,1,0,1,1,0},
                     {1,0,1,0,1,0,0,1,0,1,0,1},
                     {1,1,0,1,1,0,0,1,0,1,1,1},
                     {1,1,1,1,1,1,0,0,0,1,1,0}};
//MODELOS SUPORTADOS
String ci[17] = {"00", "02", "04", "05", "06", "07", "08", "09", "14", "16", "17", "20", "21", "22", "30", "32", "86"};

void setup() {
  Serial.begin(9600);           //debug
  Serial.println("RESETEI");
  fLogic = EEPROM.read(0);    //LE O PRIMEIRO BYTE DA MEMORIA E GUARDA
  pLogic = EEPROM.read(1);    //LE O SEGUNDO BYTE DA MEMORIA E GUARDA
  Serial.println("f: " + String(fLogic));
  Serial.println("p: " + String(pLogic));
  if (fLogic && pLogic){
    for (int i = 2;i<=13;i++){
      if (ports[fLogic][i]){
        pinMode(i, OUTPUT);
      }else{
        pinMode(i, INPUT);
      }
    }
  }
}

void loop() {
  if (Serial.available()){
    String c = String(Serial.parseInt());
    Serial.println("CC: " + c);
    w_EEPROM(c);
  }
  if (EEPROM.read(2) == 1){
    if (fLogic == 1 && pLogic == 1){test("7400");}
    if (fLogic == 2 && pLogic == 2){test("7402");}
  }
}

void w_EEPROM(String pPort){
  String p = pPort.substring(2);
  if (p == "00"){EEPROM.write(0, 1);EEPROM.write(1, 1);}
  if (p == "02"){EEPROM.write(0, 2);EEPROM.write(1, 2);}
  if (p == "04"){EEPROM.write(0, 3);EEPROM.write(1, 3);}
  if (p == "05"){EEPROM.write(0, 3);EEPROM.write(1, 4);}
  if (p == "06"){EEPROM.write(0, 3);EEPROM.write(1, 5);}
  if (p == "07"){EEPROM.write(0, 3);EEPROM.write(1, 6);}
  if (p == "08"){EEPROM.write(0, 1);EEPROM.write(1, 7);}
  if (p == "09"){EEPROM.write(0, 1);EEPROM.write(1, 8);}
  if (p == "14"){EEPROM.write(0, 3);EEPROM.write(1, 9);}
  if (p == "16"){EEPROM.write(0, 3);EEPROM.write(1, 10);}
  if (p == "17"){EEPROM.write(0, 3);EEPROM.write(1, 11);}
  if (p == "20"){EEPROM.write(0, 4);EEPROM.write(1, 12);}
  if (p == "21"){EEPROM.write(0, 4);EEPROM.write(1, 13);}
  if (p == "22"){EEPROM.write(0, 4);EEPROM.write(1, 14);}
  if (p == "30"){EEPROM.write(0, 5);EEPROM.write(1, 15);}
  if (p == "32"){EEPROM.write(0, 1);EEPROM.write(1, 16);}
  if (p == "86"){EEPROM.write(0, 1);EEPROM.write(1, 17);}
  for (int i = 0;i<17;i++){
    String t1 = ci[i];
    if (p == t1){
      //Serial.println("BYE");
      EEPROM.write(2, 1);
      delay(100);
      software_Reset();
    }
  }
}

void software_Reset(){
  asm volatile ("  jmp 0");  
}

void test(String pPorta){
  String p = pPorta.substring(2);
  bool result[4][4];
  bool final[16];
  int incr = 0;
  for (int i=0;i<4;i++){
    if (p == "00"){
      digitalWrite(2, p7400[i][0]);
      delay(1);
      digitalWrite(3, p7400[i][1]);
      delay(1);
      digitalWrite(5, p7400[i][0]);
      delay(1);
      digitalWrite(6, p7400[i][1]);
      delay(1);
      digitalWrite(9, p7400[i][1]);
      delay(1);
      digitalWrite(10, p7400[i][0]);
      delay(1);
      digitalWrite(12, p7400[i][0]);
      delay(1);
      digitalWrite(13, p7400[i][1]);
      delay(1);
      result[i][0] = digitalRead(4);
      delay(1);
      result[i][1] = digitalRead(7);
      delay(1);
      result[i][2] = digitalRead(8);
      delay(1);
      result[i][3] = digitalRead(11);
      delay(1);
    }
    if (p == "02"){
      digitalWrite(3, p7402[i][0]);
      delay(1);
      digitalWrite(4, p7402[i][1]);
      delay(1);
      digitalWrite(7, p7402[i][0]);
      delay(1);
      digitalWrite(7, p7402[i][1]);
      delay(1);
      digitalWrite(8, p7402[i][1]);
      delay(1);
      digitalWrite(9, p7402[i][0]);
      delay(1);
      digitalWrite(11, p7402[i][0]);
      delay(1);
      digitalWrite(12, p7402[i][1]);
      delay(1);
      result[i][0] = digitalRead(2);
      delay(1);
      result[i][1] = digitalRead(5);
      delay(1);
      result[i][2] = digitalRead(10);
      delay(1);
      result[i][3] = digitalRead(13);
      delay(1);
      }
    }
  
  for (int i = 0;i<4;i++){
    for (int ii = 0;ii<4;ii++){
      if (p == "00"){
        if (!p7400[i][2] == result[i][ii]){
          final[incr] = 1;
          delay(20);
        }else{
          final[incr] = 0;
          delay(20);
      }
      if (p == "02"){
        if (!p7400[i][2] == result[i][ii]){
          final[incr] = 1;
          delay(20);
        }else{
          final[incr] = 0;
          delay(20);
        }
        incr++;
        }
      }
    }
  }
  for (int i = 0;i<16;i++){
    if (!final[i]){
      Serial.println("Erro no Teste: " + String(i));
    }else {
      Serial.println("Sucesso no Teste: " + String(i));
    }
  }
  EEPROM.write(2, 0);
}

Eu penso que o programa está muito complexo. Nos primeiros pots, não percebi o que se pretendia, mas agora penso que o objectivo seja testar circuitos lógicos. Penso que deve haver formas mais simples de fazer isso.
Outra coisa que me chamou a atenção foram estas duas linhas:

        if (!p7400[i][2] == result[i][ii]){
        if (!p7400[i][2] == result[i][ii]){

De certeza que é isto que quer fazer? Para que serve o not (!) naquela posição? De certeza que no 2º caso também devia ser "p7400"?

Por exemplo, não dá para fazer isto de forma mais simples?

    if (p == "00"){
      digitalWrite(2, p7400[i][0]);
      delay(1);
      digitalWrite(3, p7400[i][1]);
      delay(1);
      digitalWrite(5, p7400[i][0]);
      delay(1);
      digitalWrite(6, p7400[i][1]);
      delay(1);
      digitalWrite(9, p7400[i][1]);
      delay(1);
      digitalWrite(10, p7400[i][0]);
      delay(1);
      digitalWrite(12, p7400[i][0]);
      delay(1);
      digitalWrite(13, p7400[i][1]);
      delay(1);
      result[i][0] = digitalRead(4);
      delay(1);
      result[i][1] = digitalRead(7);
      delay(1);
      result[i][2] = digitalRead(8);
      delay(1);
      result[i][3] = digitalRead(11);
      delay(1);
    }

Não gosto muito do objecto String, mas aí, para já não me vou meter.

o segundo é

if (!p7402[i][2] == result[i][ii]){

OK. Mas o "not" está correcto? Qual é a ideia?

é apenas a lógica que fiz, poderia ser diferente, nesta se o tabela verdade estiver diferente da liga, conta um erro.

ternho esta saida mesmo sem um CI na soquete!
Screen_Teminal

Também não acho normal este "incr++" estar neste local:

for (int i = 0;i<4;i++){
    for (int ii = 0;ii<4;ii++){
      if (p == "00"){
        if (!p7400[i][2] == result[i][ii]){
          final[incr] = 1;
          delay(20);
        }else{
          final[incr] = 0;
          delay(20);
      }
      if (p == "02"){
        if (!p7400[i][2] == result[i][ii]){
          final[incr] = 1;
          delay(20);
        }else{
          final[incr] = 0;
          delay(20);
        }
        incr++;
        }
      }
    }
  }

O que diz?

EDIT: Encontrei outra coisa com que não concordo:

     digitalWrite(3, p7402[i][0]);
      delay(1);
      digitalWrite(4, p7402[i][1]);
      delay(1);
      digitalWrite(7, p7402[i][0]);
      delay(1);
      digitalWrite(7, p7402[i][1]);
      delay(1);
      digitalWrite(8, p7402[i][1]);
      delay(1);
      digitalWrite(9, p7402[i][0]);
      delay(1);
      digitalWrite(11, p7402[i][0]);
      delay(1);
      digitalWrite(12, p7402[i][1]);
      delay(1);
      result[i][0] = digitalRead(2);
      delay(1);
      result[i][1] = digitalRead(5);
      delay(1);
      result[i][2] = digitalRead(10);
      delay(1);
      result[i][3] = digitalRead(13);
      delay(1);

Aparece duas vezes o digitalWrite(7, ...). Um deles não devia escrever na porta 6?

EDIT2: Outra ideia. E se cada vez que é feito:

          final[incr] = 1;

ou

          final[incr] = 0;

também escrever para a porta serial o que está escrevendo no array?

Ainda melhor: E se a cada "digitalRead(x)" escrever na serial o que foi lido?

Assim consegue perceber melhor onde é a falha.