Multiplexar datos que vienen de varias placas de Arduino.

Bien ahora mucho mejor.
Lo unico que no has dicho es si para manejar esos displays empleas 7 + 4 + 4 o usas alguno especial como un MAX7219.

Evidentemente desconoces de algunos elementos que simplifican las cosas.
Mira esto, si usas un MAX7219 o 2 (1 x grupo) ya bajas las conexiones a 3 pines nada mas para los dos displays. Luego hablamos del software.
Los leds mismo truco pero usando los 74HC595 que manejan 8 salidas cada uno asi que necesitas para 23+24 = 47 salidas x 2 = 94 salidas / 8 = 12 integrados que totalizarían 96 posibles salidas.
Hasta aca llevamos 3 para displays mas 3 mas para estos leds, los 94 leds.

Nos faltan los sensores ultrasónicos.

Acá necesitamos 2 pines x sensor, pero en realidad se pueden hacer 2 cosas interesantes:

  1. Que todos los pines de salida que emiten el pulso sean el mismo lo que reduce a 47 lecturas digitales o
  2. Puedes usar multixplexores analógicos como el 4052 eligiendo que sensor vas a leer

    Exsiten otras variantes x ejemplo con el 4051

O sea que de este modo necesitas 48/4 = 12 integrados y 24 pines digitales para esos 12 integrados mas 2 pines extra para decodificar que llave analógica usarás.

En conclusión...

2 + 1 (ChipSelect MAX7219) + 1 (ChipSelect diferente para los 595) +12 + 2 pines digitales = 18 pines digitales si no me olvido de algo.

Podrias usar un NANO/UNO o bien un Mega.

1 o 2 MAX7219
12 74hc595
12 CD4052

Puede haber algun error porque no he verificado lo dicho, pero rondará estos números.

Solo son ideas, tambien puedes hacerlo con varios Arduinos pero no en serie. Salvo que un MEGA con 4 puertos se comunique con 4 Megas si hiciera falta.

Bueno, esto se pone interesante cada vez más.

Te cuento, por ahora el proyecto va a realizarse en las 2 partes, izquierda y derecha, es decir, hablemos de 24 leds y 24 sensores inicialmente, que sería el lado izquierdo vamos a trabajarlos de forma independiente y el lado derecho sería una copia exacta del otro circuito y todo lo demás. Lo trabajaré así por solicitud del dueño del sitio y la verdad me parece más fácil así por cuestiones de distancias entre los 2 lados.

Físicamente tengo 4 arduino Mega, los sensores y los leds, lo demás es casi imposible conseguirlos en mi ciudad, dado el caso tocará pedirlos desde la capital.

La idea de simplificar las cosas me parece excelente, así se facilita todo, creo que por ahora la opción sería simplificar los leds con el 74HC595, los display inicialmente con 7 + 4 y usar en los sensores el mismo pulso de salida, voy a experimentar a ver como me va, ya que es fin de semana y no hay comercio funcionando.

Claro, nesecitaría una idea del código, ¿Cómo hago para usar el mismo pulso de salida para todos los sensores ultrasónicos? ¿Simplemente se toma ese pin de salida y se coloca en paralelo con los demás o hay otra opción?

Iré trabajando y a medida que vaya avanzando comentaré como voy, quiero estar seguro que así como voy alcancen los pines para los 24 puestos iniciales, estaré atento a toda sugerencia.

Vamos a desarrollar la idea del multiplexor.

Tienes dos opciones válidas :

  1. puedes usar el CD4051 que es un multiplexor de 1 a 8
  2. o el 4052 que es 2 a 4. Te expliqué el 2 a 4.

Ahora vamos con el 4051 1 a 8.

Tienes 1 pin bidireccional que puede direccionarse a 8 pines o a la inversa.

Estos son los pines de un HC SR04
5V Supply
Trigger Pulse Input
Echo Pulse Output
0V Ground

Entonces supongamos que como dices 24 sensores. Podrias usar 3 CD 4051 que van a direccionar el pin Trigger de cada sensor Ultrasónico. Y el pin Echo será común a un pin de modo que como son 24 veremos que consumo tiene eso para el pin Arduino.

El único problema que veo es que el sensor tiene un ángulo de 15 y que debes evitar que el mismo puso disparado en los 24 sensores genere un echo residual en algun sensor.
Bueno en este punto me doy cuenta que la idea presenta problemas posibles como perder pulsos muy próximos.
Y si lo haces barriendo o sea que cada vez que quieras medir una distancia deberás disparar su trigger.
Asi que olvidemos x ahora la opción de un solo pulso de disparo. Y Tendremosque considerar que tenemos 2 pines multiplexados para cada sensor.

NUEVA IDEA!!!
Hay una técnica muy interesante que usa diodos para separar el uso de multiples botones/pulsadores y acá podriamos usar lo mismo. Un diodo 1n4148 o 1n914 sale de cada ECHO de los HC-SR04 y se unen en sus cátodos y requerirán una R de 10k a GND.
Ese punto común va a una interrupción del Arduino pin2 o 3 son las disponibles. En teoría entonces un pulso dispara a todos los sensores y el que vaya respondiendo dará su respuesta o se acumula en un array.
Hay que probar la idea.

Hola,

Después de una semana de probar varias cosas he adelantado el proyecto basándome en tus ideas.
Coloqué en los trigger los cátodos de los diodos 1N4148 y en el punto común una resistencia de 10K a gnd y funciona muy bien, así utilizo un sólo pulso para todos los sensores reduciendo los pines a 24.
Lo de los leds opté por usar una sóla salida pero no usando leds RGB sino de los normales en paralelo pero invirtiendo su polaridad, cada uno con su resistencia, uno va a gnd y el otro a 5V, así cuando tengo un = en la salida se prende el led verde y cuando tengo un 1 se prende el led rojo, reduciendo los pines a 24, mas los 24 de los triggers, tengo 48 pines hasta ahora.
Claro, debo aclarar que sólo llevo conectado en la protoboard sólo 4 sensores y los 8 leds.

Lo del multiplexado ya lo empezé, he tomado un código y lo he ido modificando hasta lograr que me muestyre los datos, por ahora los display los muestran, pero empiezo con un delay de 1000 y se ven bien, claro uno por uno, pero a medida que voy reduciendo el delay, sólo uno de los disolays me queda con una intensidad buena y no parpadea, los demás si.

Quiero aclarar, no soy muy experto en el tema de la programación, pero poco a poco voy entrando en esto, creo que ese es el único detalle que debo resolver, por lo demás pieso que todo está bien.

Hasta ahora uso del pin 2 al 10, para los sensores y los leds.
Los pines desde el 43 hasta el 53 para el multiplexado.
Pines 50 al 53 para los transistores de los comunes de los displays.

Este es el código que usé, como lo dije, lo encontré en la web para un reloj con displays 7 segmentos.

int ocup=0;
int disp=0;
long duracion1, distancia1, duracion2, distancia2, duracion3, distancia3, duracion4, distancia4;


byte Digit[10][8] =
  {  { 1,1,1,1,1,1,0,0 },    // 0
     { 0,1,1,0,0,0,0,0 },    // 1
     { 1,1,0,1,1,0,1,0 },    // 2
     { 1,1,1,1,0,0,1,0 },    // 3
     { 0,1,1,0,0,1,1,0 },    // 4    
     { 1,0,1,1,0,1,1,0 },    // 5
     { 1,0,1,1,1,1,1,0 },    // 6
     { 1,1,1,0,0,0,0,0 },    // 7
     { 1,1,1,1,1,1,1,0 },    // 8
     { 1,1,1,0,0,1,1,0 }     // 9
   };

void setup() {
 Serial.begin(9600); // inicia el puerto serial a 9600 baudios
 pinMode(2, OUTPUT); // define el pin 2 como salida (trigger)
 pinMode(3, INPUT); // define el pin 3 como entrada (echo1)
 pinMode(4, OUTPUT);  // define el pin 4 como salida (Leds1)
 pinMode(5, INPUT);  // define el pin 5 como entrada (echo2)
 pinMode(6, OUTPUT); // define el pin 6 como salida (leds2)
 pinMode(7, INPUT); // define el pin 7 como entrada (echo3) 
 pinMode(8, OUTPUT);  // define el pin 8 como salida (leds3)
 pinMode(9, INPUT);  // define el pin 9 como entrada (echo4) 
 pinMode(10, OUTPUT);  // define el pin 10 como salida (leds4)

 for (int i= 43; i<54; i++)
       pinMode(i, OUTPUT);
}

void loop() {
  digitalWrite(2, LOW);
  delayMicroseconds(2);
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion1 = pulseIn(3, HIGH); // capturamos la duración del pulso
  distancia1 = (duracion1/2)/29; // calcula la distancia en cms

 
  if (distancia1 >=1 && distancia1 <=49){
     digitalWrite(4, LOW);
    }
     
  if (distancia1 >=50 && distancia1 <=499){
     digitalWrite(4, HIGH);
    }
     
   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion2 = pulseIn(5, HIGH); // capturamos la duración del pulso
  distancia2 = (duracion2/2)/29; // calcula la distancia en cms

 

  if (distancia2 >=2 && distancia2 <=49){
     digitalWrite(6, LOW);
  }

  if (distancia2 >=50 && distancia2 <=499){
     digitalWrite(6, HIGH);
  }

  
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion3 = pulseIn(7, HIGH); // capturamos la duración del pulso
  distancia3 = (duracion3/2)/29; // calcula la distancia en cms


  if (distancia3 >=2 && distancia3 <=49){
     digitalWrite(8, LOW);
  }

  if (distancia3 >=50 && distancia3 <=499){
     digitalWrite(8, HIGH);
  }

   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion4 = pulseIn(9, HIGH); // capturamos la duración del pulso
  distancia4 = (duracion4/2)/29; // calcula la distancia en cms

 
  if (distancia4 >=2 && distancia4 <=49){
     digitalWrite(10, LOW);
  }

  if (distancia4 >=50 && distancia4 <=499){
     digitalWrite(10, HIGH);
  }

  if (digitalRead(4)==0){
    ocup=ocup+1;}
  if (digitalRead(4)==1){
    disp=disp+1;}

  if (digitalRead(6)==0){
    ocup=ocup+1;}
  if (digitalRead(6)==1){
    disp=disp+1;}

  if (digitalRead(8)==0){
    ocup=ocup+1;}
  if (digitalRead(8)==1){
    disp=disp+1;}  

  if (digitalRead(10)==0){
    ocup=ocup+1;}
  if (digitalRead(10)==1){
    disp=disp+1;}  
      
 
   int k = disp * 100 + ocup ;
    CalculaDigitos(k) ;

}

void Display(int pos, int N)
{  digitalWrite(50,LOW);      // Apaga todos los digitos
   digitalWrite(51,LOW);
   digitalWrite(52,LOW);
   digitalWrite(53,LOW);    
  
    for (int i= 0 ; i<8 ; i++)
             digitalWrite(i+43 , Digit[N][i]);
             
    digitalWrite(50 + pos, HIGH); // Enciende el digito pos
 
 delay(1);
 ocup=0;
 disp=0;

}

void CalculaDigitos(int Num)
{
  
  int Digit0 = ocup %10 ;
  int Digit1 = (ocup % 100) / 10 ;
  int Digit2 = disp %10 ;
  int Digit3 = (disp % 100) / 10 ;
  
  Display(3 , Digit3);
  Display(2 , Digit2);
  Display(1 , Digit1);
  Display(0 , Digit0);

 }

Aquí encontré el código.

Creo que el error puede estar en esta parte,

for (int i= 0 ; i<8 ; i++)
            digitalWrite(i+43 , Digit[N][i]);
            
   digitalWrite(50 + pos, HIGH); // Enciende el digito pos

delay(1);
ocup=0;
disp=0;

cuando cambio el 50 por 51 ó 52, esa salida funciona bien y los demás displays parpadean, espero que puedas ayudarme con esta duda.

ANalizando el código. LUego te doy mi devolución.

Esta parte

HC_SR04
Pin 2, trigger
Pin 3, echo
Pin 4, led rojo (1 - 49 cms)
Pin 4, led verde (50 - 499 cms)
 
Distancia = (Duración/2)/29 
Vel Sonido = 340 m/s
Vel Sonido =(1/29 cm)/us*/

No corresponde a ún código de modo que edita lo que posteaste para que se entienda.

Faltan #includes, faltan definiciones de pines.... verifica. o danos el enlace de donde copiaste.

MI sugerencia es que uses la librería SevenSeg entonces ella se encarga via un timer y los pines correspondientes al multiplexado de los 4 displays y tu solo chequeas usando tu código los sensores ultrasónicos y actualizas las variables.
Este es un ejemplo simple

#include <SevenSeg.h>

SevenSeg disp(11,7,3,5,6,10,2); // pines para segmentos

const int numOfDigits=4;
int digitPins[numOfDigits]={12,9,8,13}; // pines para digitos.

void setup() {
  
  disp.setDigitPins(numOfDigits, digitPins);

}  

void loop() {

    disp.write(13.28);  // presenta un valor con decimal

}

Este es el código que usé, como lo dije, lo encontré en la web para un reloj con displays 7 segmentos

int ocup=0;
int disp=0;
long duracion1, distancia1, duracion2, distancia2, duracion3, distancia3, duracion4, distancia4;


byte Digit[10][8] =
  {  { 1,1,1,1,1,1,0,0 },    // 0
     { 0,1,1,0,0,0,0,0 },    // 1
     { 1,1,0,1,1,0,1,0 },    // 2
     { 1,1,1,1,0,0,1,0 },    // 3
     { 0,1,1,0,0,1,1,0 },    // 4   
     { 1,0,1,1,0,1,1,0 },    // 5
     { 1,0,1,1,1,1,1,0 },    // 6
     { 1,1,1,0,0,0,0,0 },    // 7
     { 1,1,1,1,1,1,1,0 },    // 8
     { 1,1,1,0,0,1,1,0 }     // 9
   };

void setup() {
 Serial.begin(9600); // inicia el puerto serial a 9600 baudios
 pinMode(2, OUTPUT); // define el pin 2 como salida (trigger)
 pinMode(3, INPUT); // define el pin 3 como entrada (echo1)
 pinMode(4, OUTPUT);  // define el pin 4 como salida (Leds1)
 pinMode(5, INPUT);  // define el pin 5 como entrada (echo2)
 pinMode(6, OUTPUT); // define el pin 6 como salida (leds2)
 pinMode(7, INPUT); // define el pin 7 como entrada (echo3)
 pinMode(8, OUTPUT);  // define el pin 8 como salida (leds3)
 pinMode(9, INPUT);  // define el pin 9 como entrada (echo4)
 pinMode(10, OUTPUT);  // define el pin 10 como salida (leds4)

 for (int i= 43; i<54; i++)
       pinMode(i, OUTPUT);
}

void loop() {
  digitalWrite(2, LOW);
  delayMicroseconds(2);
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion1 = pulseIn(3, HIGH); // capturamos la duración del pulso
  distancia1 = (duracion1/2)/29; // calcula la distancia en cms

 
  if (distancia1 >=1 && distancia1 <=49){
     digitalWrite(4, LOW);
    }
     
  if (distancia1 >=50 && distancia1 <=499){
     digitalWrite(4, HIGH);
    }
     
   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion2 = pulseIn(5, HIGH); // capturamos la duración del pulso
  distancia2 = (duracion2/2)/29; // calcula la distancia en cms

 

  if (distancia2 >=2 && distancia2 <=49){
     digitalWrite(6, LOW);
  }

  if (distancia2 >=50 && distancia2 <=499){
     digitalWrite(6, HIGH);
  }

 
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion3 = pulseIn(7, HIGH); // capturamos la duración del pulso
  distancia3 = (duracion3/2)/29; // calcula la distancia en cms


  if (distancia3 >=2 && distancia3 <=49){
     digitalWrite(8, LOW);
  }

  if (distancia3 >=50 && distancia3 <=499){
     digitalWrite(8, HIGH);
  }

   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion4 = pulseIn(9, HIGH); // capturamos la duración del pulso
  distancia4 = (duracion4/2)/29; // calcula la distancia en cms

 
  if (distancia4 >=2 && distancia4 <=49){
     digitalWrite(10, LOW);
  }

  if (distancia4 >=50 && distancia4 <=499){
     digitalWrite(10, HIGH);
  }

  if (digitalRead(4)==0){
    ocup=ocup+1;}
  if (digitalRead(4)==1){
    disp=disp+1;}

  if (digitalRead(6)==0){
    ocup=ocup+1;}
  if (digitalRead(6)==1){
    disp=disp+1;}

  if (digitalRead(8)==0){
    ocup=ocup+1;}
  if (digitalRead(8)==1){
    disp=disp+1;} 

  if (digitalRead(10)==0){
    ocup=ocup+1;}
  if (digitalRead(10)==1){
    disp=disp+1;} 
     
 
   int k = disp * 100 + ocup ;
    CalculaDigitos(k) ;

}

void Display(int pos, int N)
{  digitalWrite(50,LOW);      // Apaga todos los digitos
   digitalWrite(51,LOW);
   digitalWrite(52,LOW);
   digitalWrite(53,LOW);   
 
    for (int i= 0 ; i<8 ; i++)
             digitalWrite(i+43 , Digit[N][i]);
             
    digitalWrite(50 + pos, HIGH); // Enciende el digito pos
 
 delay(1);
 ocup=0;
 disp=0;

}

void CalculaDigitos(int Num)
{
 
  int Digit0 = ocup %10 ;
  int Digit1 = (ocup % 100) / 10 ;
  int Digit2 = disp %10 ;
  int Digit3 = (disp % 100) / 10 ;
 
  Display(3 , Digit3);
  Display(2 , Digit2);
  Display(1 , Digit1);
  Display(0 , Digit0);

 }

y este es el enlace de donde lo saqué.

Estoy usando displays de cátodo común y como lo dije funciona, pero 3 de ellos parpadean y la luminosidad es bastante baja.

Hola,
Como comenté, no soy experto en programación y algunas cosas no entiendo, perdón por mi ignorancia.

Este ejemplo simple no lo entiendo mucho:

#include <SevenSeg.h>

SevenSeg disp(11,7,3,5,6,10,2); // pines para segmentos

const int numOfDigits=4;
int digitPins[numOfDigits]={12,9,8,13}; // pines para digitos.

void setup() {
 
  disp.setDigitPins(numOfDigits, digitPins);

} 

void loop() {

    disp.write(13.28);  // presenta un valor con decimal

}

En qué parte debo insertar la parte del còdigo donde hago las lecturas de los sensores y la actualizaciòn de las variables?
osea, esta parte:

digitalWrite(2, LOW);
  delayMicroseconds(2);
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion1 = pulseIn(3, HIGH); // capturamos la duración del pulso
  distancia1 = (duracion1/2)/29; // calcula la distancia en cms

 
  if (distancia1 >=1 && distancia1 <=49){
     digitalWrite(4, LOW);
    }
    
  if (distancia1 >=50 && distancia1 <=499){
     digitalWrite(4, HIGH);
    }
    
   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion2 = pulseIn(5, HIGH); // capturamos la duración del pulso
  distancia2 = (duracion2/2)/29; // calcula la distancia en cms

 

  if (distancia2 >=2 && distancia2 <=49){
     digitalWrite(6, LOW);
  }

  if (distancia2 >=50 && distancia2 <=499){
     digitalWrite(6, HIGH);
  }

 
  digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion3 = pulseIn(7, HIGH); // capturamos la duración del pulso
  distancia3 = (duracion3/2)/29; // calcula la distancia en cms


  if (distancia3 >=2 && distancia3 <=49){
     digitalWrite(8, LOW);
  }

  if (distancia3 >=50 && distancia3 <=499){
     digitalWrite(8, HIGH);
  }

   digitalWrite(2, HIGH); // genera el pulso de 10 us
  delayMicroseconds(10);
  digitalWrite(2, LOW);

  duracion4 = pulseIn(9, HIGH); // capturamos la duración del pulso
  distancia4 = (duracion4/2)/29; // calcula la distancia en cms

 
  if (distancia4 >=2 && distancia4 <=49){
     digitalWrite(10, LOW);
  }

  if (distancia4 >=50 && distancia4 <=499){
     digitalWrite(10, HIGH);
  }

  if (digitalRead(4)==0){
    ocup=ocup+1;}
  if (digitalRead(4)==1){
    disp=disp+1;}

  if (digitalRead(6)==0){
    ocup=ocup+1;}
  if (digitalRead(6)==1){
    disp=disp+1;}

  if (digitalRead(8)==0){
    ocup=ocup+1;}
  if (digitalRead(8)==1){
    disp=disp+1;}

  if (digitalRead(10)==0){
    ocup=ocup+1;}
  if (digitalRead(10)==1){
    disp=disp+1;}
    
 
   int k = disp * 100 + ocup ;
    CalculaDigitos(k) ;

al parecer debo reemplazar los pines para segmentos y dígitos por los que uso.

Perdón por la intromisión. Pero es importante usar displays a leds ? Podés usar un LCD ? Si fuera así podés poner uno de 4 lineas de 20 caracteres ( en el que mostrás mucha más información que los de 7 segmentos) y manejás todo el display I2C con 2 salidas. Así liberarías mas pines de tu Arduino.

Pablo, todas las opiniones y sugerencias son bienvenidas y agradezco mucho el interés en ayudar.

Definitivamente si debo usar los displays, por petición del cliente y además el tamaño de la información mostrada debe ser bien grande.

Creo que el problema que tengo en el multiplexado no es del código, ya he probado con otros y se presenta el mismo problema de inestabilidad, me atrevo a pensar que los sensores ultrasónicos generan algún tipo de interferencia o ruido el cual hace que se presenta dicha situación.

Voy a tratar de montar en una tarjeta los sensores y los leds, y en la otra manejar el multiplexado pero tengo que investigar un poco sobre la comunicación I2C para poder enviar los datos desde el maestro hacia el esclavo.

Pero yo te sugerí que pruebes el uso de una librerìa que resolverà el problema de multiplexado del display.
Ni siquiera la has probado porque volviste a poner un còdigo similar al primero.

Intenta por esa vìa, la librerìa usa TIMER y te libera del manejo y control del display y solo te tienes que enfocar en el resto.

Hola Surbyte,

Te comenté que no entendí mucho el ejemplo simple que me enviaste, en qué parte debo insertar la parte de la lectura de los sensores y actualización de las variables.

#include <SevenSeg.h>

SevenSeg disp(11,7,3,5,6,10,2); // pines para segmentos

const int numOfDigits=4;
int digitPins[numOfDigits]={12,9,8,13}; // pines para digitos.

void setup() {
 
  disp.setDigitPins(numOfDigits, digitPins);

}

void loop() {

    disp.write(13.28);  // presenta un valor con decimal

}

Supongo que debo cambiar los pines que están en el ejemplo por los que estoy usando para los displays, pero en la parte del void loop no se que teno que agregar disp.write(13.28); que significa?. Si cargo este ejemplo en mi tarjeta, que sucede? sale algo en los displays?
Podrías enviarme un ejemplo para un solo sensor o algo que después pueda continuar solo, te lo agradecería mucho.

Ahh disculpa ahora lo leo.
Ya te ayudo con el tema.

SevenSeg disp(11,7,3,5,6,10,2); // pines para segmentos

Estos son los segmentos desde a b c d e f g y dp cuenta y verás.

int digitPins[numOfDigits]={12,9,8,13}; // pines para digitos.

Esto para los digitos.. ahora solo hay que verificar si esta para CATODO COMUN o ANODO COMUN en cuyo caso habra que poner una etiqueta para que cambie o invierta.

Este simple comando

 disp.write(13.28);  // presenta un valor con decimal

presentaría 13.28 en tu display

En tu caso

disp.write(distancia1);

luego de calculada debería ser suficiente para que la muestre.

Hola,

Estuve probando la librería SevenSeg y me fue muy bien, leyendo un poco la guía encontré la forma de controlar los displays de forma separada y de configurar si es cátodo o ánodo común.

Los displays se ven más estables, por ahora estoy trabajando con 2 sensores para entender un poco mejor la librería y sucede que cuando los 2 espacios están desocupados o llenos, los displays salen correctamente, pero cuando hay uno lleno y otro desocupado empieza a parpadear con un pulso de unos 100 milisegundos cada un segundo aproximadamente. Al parecer el código está bien, pruebo las lecturas de los pines digitales de forma manual y sale todo bien.

Creo que la opción de un solo pulso para todos los sensores debe generar algún tipo de error o inestabilidad, voy a probar usando pulsos para cada sensor a ver como me va, lo malo es que usaría muchos pines y no van a alcanzarme, tocará usar la opción de los registros de desplazamiento para reducir pines.

Cualquier sugerencia o idea será bienvenida, gracias a este foro he ido superando situaciones poco a poco.

sucede que cuando los 2 espacios están desocupados o llenos, los displays salen correctamente, pero cuando hay uno lleno y otro desocupado empieza a parpadear con un pulso de unos 100 milisegundos cada un segundo

No te comprendo.

dos espacios desocupados? Cuales espacios?

Ahhh disculpa, lo que pasa es que tengo el proyecto montado en protoboard a escala, cuando digo espacios desocupados o llenos, me refiero a que es como si un carro estuviese parqueado (lleno) o está disponible, recuerda que es un parqueadero, claro que realmente lo que hago es acercar un objeto al sensor para indicar que está lleno ese espacio.

Hola,

Después de varias semanas de investigación y solucionando situaciones que se han presentado a lo largo de este proyecto, he ido ordenando todo y llegando a conclusiones.

La parte de los sensores se encuentra aparentemente solucionada, me toca usar muchos pines de esta forma he obtenido los mejores resultados, utilizo 2 pines por cada sensor, serìan 24, pero es un Arduino Mega y puedo usar mas pines.

La parte de los displays utilizo dos 74HC595 y una librería llamada TimerOne, esto lo saque de un tutorial en la web donde utilizo 5 pines y puedo utilizar hasta 8 displays.

Para los leds estoy utilizando también el 74HC595, tanto para los rojos como para los verdes, pero aquí me encuentro con la situación de hasta ahora he podido controlar 8 leds que son las salidas del primer registro de desplazamiento, para esto uso valores decimales para representar cada led, por lo menos, para encender el primer led coloco el número 1, para el segundo el número 2, para el tercero el 4, y asì sucesivamente hasta el octavo que serìa el valor de 128.

Algo así:

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, 128);  
  digitalWrite(latchPin, HIGH);

El problema se me presenta al encender los 8 leds del siguiente registro, he hecho las conexiones como aparece en la mayoría de los tutoriales( el pin 9 del primero(Q7') al pin 14 del segundo(DS)), los SH y ST en paralelo con los pines del Arduino, OE a gnd y MR a VCC y según mi instinto debería vebir el valor de 256 para que se encienda el primer led del segundo registro, pero no sucede, pero si enciende cuando enciende el primer led del primer registro.

He buscado en la web y no he encontrado un código que se asemeje a lo que necesito, los que encuentro son de efectos varios, secuencias y cosas por el estilo que son muy avanzados para mi.

Sólo necesito saber como activar el segundo registro ya que necesitarìa en total 3 registros para completar los 24 leds que necesito controlar.

Voy a seguir buscando y probando hasta que pueda avanzar, cualquier aporte que puedan hacer será de gran ayuda.

Hay muchos ejemplos de contadores de 4 y 5 digitos en hardware.
TE busco alguno para que veas. Es sumamente fácil de hacer con los 595.

Contador de 5 digitos

Surbyte,

Lo de los displays ya lo tengo listo, lo que me falta es lo de los leds.

El segundo registro se comporta igual que el primero, como si estuvieran en paralelo, ya he revisado las conexiones, cambiado cables, dispositivos y nada que logro que encienda el segundo registro con el valor de 256. Cuando le le doy el valor de 1, entonces enciende el primer led del primer registro y el primer led del segundo registro tambièn.

Parece que los datos fueran iguales en los 2 registros, no pasan de 8 bits y no se comportan como una cascada.

Ahì es donde debo solucionar.

No entiendo algo, dices que los displays funcionan y no funcionan los leds? Pero resulta que funcionalmente son lo mismo, por eso no comprendo.

Ya a esta altura necesiaría ver el programa completo, y un esquema de todo.. mas alla que digas esto esta conectado acá y lo otro allá.
Hay que ver como interactúa todo porque yo te dejé en la parte multiplexada pero ahora ya estamos en otra cosa y sumaste timerOne, displays, etc.

O minimamente hablemos de la situación de los leds que refieres pero entonces se especifico con un programa completo y un esquema para yo poder seguirte.

Bueno, mas bien hablemos por ahora solo de los leds, estoy trabajando los códigos por partes y después los uniré.

El código que tengo para los leds funciona para los primeros 8 leds, pero como comenté, se encienden también los 8 que siguen como si estuvieran en paraleo.

int ocup=0;
int latchPin = 8;    //Pin conectado a ST_CP of 74HC595 
int clockPin = 9;    //Pin conectado a SH_CP of 74HC595 
int dataPin =  10;     //Pin connected to DS of 74HC595 

void setup() {
   pinMode(latchPin, OUTPUT);
   pinMode(clockPin, OUTPUT);
   pinMode(dataPin, OUTPUT);
   pinMode(0, INPUT);
   pinMode(1, INPUT);
   pinMode(2, INPUT);
   pinMode(3, INPUT);  
   pinMode(4, INPUT);
   pinMode(5, INPUT); 
   pinMode(6, INPUT);
   pinMode(7, INPUT);
   pinMode(A0,INPUT);
   pinMode(A1,INPUT);
   pinMode(A2,INPUT);
   pinMode(A3,INPUT);
   pinMode(A4,INPUT);
   pinMode(A5,INPUT);
   pinMode(11,INPUT);
   pinMode(12,INPUT);
 }

void loop() {
 if(digitalRead(0)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+1);
   digitalWrite(latchPin, HIGH); 
   }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH);
  }

if(digitalRead(1)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+2);
   digitalWrite(latchPin, HIGH); 
  }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH); 
  }

if(digitalRead(2)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+4);
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH); 
  }
  
  if(digitalRead(3)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+8);
   digitalWrite(latchPin, HIGH); 
  }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH); 
  } 

 if(digitalRead(4)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+16);
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH); 
 } 

 if(digitalRead(5)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+32);
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH); 
 }

 if(digitalRead(6)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+64);
   digitalWrite(latchPin, HIGH); 
  }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH);
  }

 if(digitalRead(7)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+128);
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH);
  }
   
  if(digitalRead(A0)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+256); 
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH);
 }
}

Cuando llega a esta parte no se eniende ningún led.

if(digitalRead(A0)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup+256); 
   digitalWrite(latchPin, HIGH); 
 }
 else{
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, ocup);
   digitalWrite(latchPin, HIGH);

He visto en la web que hay que agregar una línea para mandar 16 bits, pero no se como, hago algunas modificaciones pero siempre se encienden 2 leds en paralelo.
La línea es algo así:

if(digitalRead(A0)==1){
   digitalWrite(latchPin,LOW);
   shiftOut(dataPin, clockPin, MSBFIRST, (256>>8)); 
   digitalWrite(latchPin, HIGH);

Pero no se cómo agregarla sin que afecte a los primeros 8 bits o si hy que agregarla desde el principio del void loop.