Go Down

Topic: Decodificador BCD a Decimal (Especial) (Read 6577 times) previous topic - next topic

surbyte

Ya veo el error. El error no esta en la matriz y en la definición de salidas.
sino acá

Code: [Select]
  valorBCDAnt = valorBCD;
  for (int i=0; i<=10; i++) {
      if (i== valorBCD)
        digitalWrite(Salidas[i], HIGH);
      else
        digitalWrite(Salidas[i], LOW);
  }

cuando valorBCD = 0 intenta poner en 1 la salida 0 y eso no esta bien
Tu agregaste una salida que no sirve.
Luego lo miro y corrijo el problema

surbyte

Bueno no se para que hice la matriz y luego no la usé.. algo me pasó al momento de programarlo y olvidé el elemento clave.
esta modificación contempla la matrix que acabo de postear sin la salida extra que tu pones
Usa esta matriz.. no confundas con la tuya.

Code: [Select]
//                     BCDA BCDB BCDC BCDD WARC  BAND
const byte Entradas[6] = {   8,   9,  10,  11,  12,   13};
//-----------------------------
//                          160m 80m 40m 30m  20m 17m 15m 12m 10m  6m
const byte Salidas[10]    = { A5, A4, A3, A2,  2,  3,  4,  5,  6,  7};
const byte matrix[11][10] = {
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},   // 0                   
                            {  1,  0,  0,  0,  0,  0,  0,  0,  0,  0},   // 1
                            {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0},   // 2
                            {  0,  0,  1,  0,  0,  0,  0,  0,  0,  0},   // 3
                            {  0,  0,  0,  1,  0,  0,  0,  0,  0,  0},   // 4
                            {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0},   // 5
                            {  0,  0,  0,  0,  0,  1,  0,  0,  0,  0},   // 6
                            {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0},   // 7
                            {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0},   // 8
                            {  0,  0,  0,  0,  0,  0,  0,  0,  1,  0},   // 9
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1}};  // 10
                     

//-------------------------------
int valorBCD, valorBCDAnt=0;
//----------------------------
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  for (int i=0; i<6; i++) {
      pinMode(Entradas[i], INPUT);
  }
//-------------------------------
  for (int i=0; i<10; i++) {
      pinMode(Salidas[i], OUTPUT);
  } 
}


void loop(){
 
  valorBCD = LeerBCDDecimal();
  if (valorBCD != valorBCDAnt)
      Serial.println(valorBCD);
  valorBCDAnt = valorBCD;
  for (int i=0; i<=10; i++) {
      digitalWrite(Salidas[i], matrix[valorBCD][i]);
  }
         
}

int LeerBCDDecimal(){
 
   int ValorDecimal;

   byte datA = digitalRead(Entradas[0]);
   byte datB = digitalRead(Entradas[1]);
   byte datC = digitalRead(Entradas[2]);
   byte datD = digitalRead(Entradas[3]);

   ValorDecimal = (datD << 3) + (datC <<2) + (datB << 1) + datA;
   byte WARC = digitalRead(Entradas[4]);
   byte BAND = digitalRead(Entradas[5]);


   if (WARC && BAND) {
     switch (ValorDecimal) {
         case 4:
         case 6:
         case 8:
                 ValorDecimal = 7;   // revisar
                 break;
         case 5:
         case 7:
         case 9:
                 ValorDecimal = 8;
                 break;
         default:
                 break;
     }
   }

   return ValorDecimal;
}

CX6DRA

#32
Mar 04, 2016, 02:48 am Last Edit: Mar 04, 2016, 03:04 am by CX6DRA
Hola Surbyte, como estas?

Acabo de probar el nuevo codigo, y tiene un pequeño bug a partir del bcd de entrada = 1011 hasta 1111.

Con 1011, quedan activas todas las salidas.
Con 1100, quedan activas 160, 80, 40, 30, 20 y 17.
Con 1101, quedan activas todas las salidas.
Con 1110, 160, 40, 20, 15 y 12.
Con 1111, quedan activas 160 y 10.

Lo que hice, fue poner la matriz de 17x10 de esta manera:

Code: [Select]
//                          160m 80m 40m 30m  20m 17m 15m 12m 10m  6m
const byte Salidas[10]    = { A5, A4, A3, A2,  2,  3,  4,  5,  6,  7};
const byte matrix[17][10] = {
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},   // 0                   
                            {  1,  0,  0,  0,  0,  0,  0,  0,  0,  0},   // 1
                            {  0,  1,  0,  0,  0,  0,  0,  0,  0,  0},   // 2
                            {  0,  0,  1,  0,  0,  0,  0,  0,  0,  0},   // 3
                            {  0,  0,  0,  1,  0,  0,  0,  0,  0,  0},   // 4
                            {  0,  0,  0,  0,  1,  0,  0,  0,  0,  0},   // 5
                            {  0,  0,  0,  0,  0,  1,  0,  0,  0,  0},   // 6
                            {  0,  0,  0,  0,  0,  0,  1,  0,  0,  0},   // 7
                            {  0,  0,  0,  0,  0,  0,  0,  1,  0,  0},   // 8
                            {  0,  0,  0,  0,  0,  0,  0,  0,  1,  0},   // 9
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  1},   //10
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0},
                            {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0}};
                     


Quizas no sea lo correcto, pero "funciona" jaja.


Y aqui:

Code: [Select]
if (WARC && BAND) {
     switch (ValorDecimal) {
         case 4:
         case 6:
         case 8:
                 ValorDecimal = 7;   // revisar
                 break;
         case 5:
         case 7:
         case 9:
                 ValorDecimal = 8;
                 break;
         default:
                 break;
     }


WARC y BAND, son independientes entre si, tanto puede estar una activa, la otra, las dos juntas, o ninguna. Lo que SIEMPRE, WARC maneja sus salidas y BAND las propias, NUNCA deberian intercambiarse entre si.



Gracias por tu tiempo.

surbyte

A ver.. tu pusiste una tabla hasta 1010 si mal recuerdo. Bloquea el resto.
no hace falta ampliar la matriz. Un poco de analisis y un if en la función LeerBCDDecimal(){
hubiera controlado todo lo que supere 1010
recordemos tu tabla




tomas en cuenta los casos que no dijiste que ocurrirían por eso cuando se pone una tabla hay que pensar en todo.


usa esto que es mas correcto que lo que has hecho. Aunque soluciones hay muchas



Code: [Select]
if (WARC && BAND) {
     switch (ValorDecimal) {
         case 4:
         case 6:
         case 8:
                 ValorDecimal = 7;   // revisar
                 break;
         case 5:
         case 7:
         case 9:
                 ValorDecimal = 8;
                 break;
         case 11:
         case 12:
         case 13:
         case 14:
         case 15: ValorDecimal = 0; // esta simple instrucción resuelve todo
                  break;
         default:
                 break;
     }



CX6DRA

Bueno Surbyte, muchas gracias nuevamente.

Como tu dices, el error fue mio al no contemplar los casos "no deseados" en la tabla de verdad. Hice una pequeña modificacion el codigo que me propusiste, y "saque" los casos no deseados del "IF", para que no dependa de este, me diras tu si lo que hice es correcto.


Code: [Select]
if (WARC && BAND) {
     switch (ValorDecimal) {
         case 4:
         case 6:
         case 8:
                 ValorDecimal = 7;   // revisar
                 break;
         case 5:
         case 7:
         case 9:
                 ValorDecimal = 8;
                 break;
         default:
                 break;
         
     }
   }
     switch (ValorDecimal) {
         case 11:
         case 12:
         case 13:
         case 14:
         case 15:
                 ValorDecimal = 0;
                 break;
         default:
                 break;
     }

   return ValorDecimal;
}
     }


Trabajare ahora, en independizar WARC de BAND. Les comento.

Gracias.
[/quote]

surbyte

Aclaro que ambas soluciones funcionan pero: mi solución es mucho mas elegante. Todo resuelto en un paso no en dos como vos proponés.
No entiendo porque desdoblaste lo que te propuse?

CX6DRA

Aclaro que ambas soluciones funcionan pero: mi solución es mucho mas elegante. Todo resuelto en un paso no en dos como vos proponés.
No entiendo porque desdoblaste lo que te propuse?
Hola, probe tu solución claro que si, y aunque no lo creas, el resultado era el mismo.

Luego me di cuenta que quedaba atado al If + &&, por eso lo puse por fuera de este.

Gracias.

surbyte

ahhh ahora te comprendo y tienes razón.
Entonces bloqueemos antes para ser mas correctos
Bloquea cuando formamos ValorBCD

Code: [Select]
ValorDecimal = (datD << 3) + (datC <<2) + (datB << 1) + datA;[color=#222222][/color]
if (ValorDecimal > 10) ValorDecimal = 0;

y elimina lo que yo sugerí antes dentro del switch y tu switch extra.
Ahora si todo valor por encima de 10 no existe, asi que devuelve 0.

Go Up