Desesperado con 2x 74HC595

Pretendo manejar 16 leds por medio de dos 74HC595 "en cascada". Como el sketch en el que está incluido el código es muy largo, he hecho una versión reducida que es la que os muestro.

Le asigno a cad led el valor de una posición en un número binario y, jugando con eso, le doy valor a una variable que mando por medio de ShiftOut al t4HC595.

El problema viene cuando utilizo el valor 1 para intentar encender el primer led de la serie. Todo funciona correctamente encendiendo los leds que pretendo pero cuando incluyo el led 1 no se enciende ninguno ni funciona nada.

No creo que sea el hadrware porque cuando invierto la asignación de posiciones, ese led y esa línea del chip funciona. Sólo se produce el fallo cuando mando el valor 1. He pensado que pudiera ser algún tipo de overflow, pero tampoco porque, incluso mandando valores pequeños, al mandar el 1 "casca".

¿Podéis ayudarme? ¿Qué hago mal?.

Saludos.

#define srRESET 30
#define srENABLE 99
#define srDATA 26
#define srCLOCK 29
#define srLATCH 28

#define LED0 1    // valor equivalente en decimal al LED0
#define LED1 2    // valor equivalente en decimal al LED1
#define LED2 4    // valor equivalente en decimal al LED2
#define LED3 8    // valor equivalente en decimal al LED3
#define LED4 16   // valor equivalente en decimal al LED4
#define LED5 32   // valor equivalente en decimal al LED5
#define LED6 64   // valor equivalente en decimal al LED6
#define LED7 128  // valor equivalente en decimal al LED7

#define LED8 256  // valor equivalente en decimal al LED8
#define LED9 512  // valor equivalente en decimal al LED9
#define LED10 1024  // valor equivalente en decimal al LED10
#define LED11 2048  // valor equivalente en decimal al LED11
#define LED12 4096  // valor equivalente en decimal al LED12
#define LED13 8192  // valor equivalente en decimal al LED13
#define LED14 16384 // valor equivalente en decimal al LED14
#define LED15 32768 // valor equivalente en decimal al LED15

long E, C, T;

void setup ()
{
  Serial.begin(9600);
  pinMode(srRESET, OUTPUT);
  pinMode(srENABLE, OUTPUT);
  pinMode(srDATA, OUTPUT);   // pin establecido como salida
  pinMode(srCLOCK, OUTPUT);  // pin establecido como salida
  pinMode(srLATCH, OUTPUT); // pin establecido como salida

  E = 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 + 32768;
  C = 0 + 2 + 4 + 8 + 16;
  T = E + C;
}

void loop()
{
  Serial.print("   C= "); Serial.print(C);
  Serial.print("   E= "); Serial.print(E);
  Serial.print("   T= "); Serial.println(T);

  digitalWrite(srRESET, LOW);
  delayMicroseconds(100);
  digitalWrite(srRESET, HIGH);

  digitalWrite(srLATCH, LOW);
  shiftOut(srDATA, srCLOCK, MSBFIRST, (E >> 8));
  shiftOut(srDATA, srCLOCK, MSBFIRST, C);
  digitalWrite(srLATCH, HIGH);
  delay(500);
}`

Su publicacion se MUEVE a su ubicacion actual ya que es mas adecuada.

Si adjuntas el código para saber pues como ayudar, en tu texto donde puedo ver como estas enviando el comando shiftout() y como se que tiene la variable led1 y valor 1 si te fijas en la referencia Documentación shiftOut()
el comando utiliza un formato establecido y el orden de los bits pueda ser tu error

shiftOut(dataPin, clockPin, bitOrder, value)

¿Dónde encuentro las normas para subir código con la pregunts?

tienes que pegarlo con la etiqueta code

Moderador:
Por favor, lee las Normas del foro y edita tu código/error usando etiquetas de código.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en (<CODE/>)


Donde encuentras las normas? en el primer hilo de cualquier sección

Ok. Gracias. Pido disculpas por los errores. He buscado en Faqs y en otros sitios y no he sabido verlo.

Disculpas de nuevo.

#define srENABLE 99
...
pinMode(srENABLE, OUTPUT);

¿Qué placa usas que tiene pin digital nro. 99?

Y por cierto, aunque asumimos que es una Mega, estaría bueno saber qué placa usas.

Yo pienso que es como declaras el valor LED 0

#define LED0 1 // valor equivalente en decimal al LED0
y seguidamente añades 0 al registro sin definirlo previamente
C = 0 + 2 + 4 + 8 + 16;
Por ende yo creo que tu registro debe empezar con #define LED0 0

LED0   0  
LED1   2  
LED2   4  
LED3   8	
LED4   16	
LED5   32	
LED6   64	
LED7   128	
LED8   256	
LED9   512	
LED10  1024	
LED11  2048	
LED12  4096	
LED13  8192	
LED14  16384	
LED15  32768

Pensalo en binario

LED0  0b0000000000000001 // 1
LED1  0b0000000000000010 // 2
LED2  0b0000000000000100 // 4
// etc.

El bit indica cuál LED se enciende.
Sería 2^n, donde n es el 'indice' del LED.

Si definiese

LED0  0

El LED siempre estaría apagado.

Agrego: Igual no está usando esas definiciones. Jaja

Agrego-2:

long E, C, T;

debería ser

unsigned long E, C, T;

para no tener posibles problemas con el signo (bit 15). No aseguro que pueda haberlos pero no está de más prevenirlos.

Gracias por vuestro interés. Iré por partes:
Efectivamente utilizo un MEGA. También tengo que decir que a la salida de los 74HC595 tengo dos ULN2803.

Se que el código esta muy desaliñado pero se trata de un extracto que saqué del código general (casi 800 líneas) para hacer pruebas al ver que no funcionaba.

Lo del pin 99 es una convención que tengo yo para indicarme que aun no está conectado o no se donde lo conectaré definitivamente. En el código general está debidamente comentado.

Los #define LEDxx los h dejado como cchuleta del valor de la posición de cada led pero no los uso en las pruebas porque me es más cómodo poner el valor diectamente (otra cosa es en el código general donde los llamo desde distintos sitios).

Lo de usar valores decimales en lugar de binarios me funciona bien.

Lo del valor 0 como primer sumando de la variable C es para hacer pruebas. Sea cual sela la combinación de leds funciona si tengo el 1 apagado (o sea en 0) pero, cuando en una combunación que funciona, le añado el 1 dejan de encenderse TODOS los leds.

Lo de unsigned long C, lo tenía así pero lo quité en una de las pruebas porque ya no sabía que más buscar. También he probado a mandar dos veces la variable T que es la suma de E+C y se comporta exactamente igual.

Ya no se que más probar,

La referencia a binario fue para @migueratto :wink:

Hice la simulación en wokwi y no encontré problemas.
El error debe estar en otra parte del código.

@Lluis_tgn, ¿El código que has puesto falla? Creo que deberías de poner de ejemplo un código funcional que reproduzca el problema y de el fallo que quieres solucionar. Hablas de que cuando mandas el 1 "casca" y no veo que estés mandando un 1 en el código que has puesto de ejemplo.

Mi consejo es que compiles y ejecutes en tu montaje un pequeño programa que reproduzca el fallo y ese programa es el que pongas en el foro. Porque tal vez la línea en la que "pones el 1" es la que falla y esa, al menos yo, no la veo en el código que has puesto.

Otra cosa, cuando trabajes con "bits, te recomeniendo no sumar (+) sino utilizar el operador OR de bits (|)

En lugar de:

  E = 256 + 512 + 1024 + 2048 + 4096 + 8192 + 16384 + 32768;
  C = 0 + 2 + 4 + 8 + 16;
  T = E + C;

Es mejor poner:

  E = 256 | 512 | 1024 | 2048 | 4096 | 8192 | 16384 | 32768;
  C = 0 | 2 | 4 | 8 | 16;
  T = E | C;

¿Porqué? Pues porque si "repites" la suma de un bit este se pone a cero y afecta al siguiente bit de la izquierda, que a su vez puede afectar al siguiente...

Ejemplos:
1 + 1 es 2, mientras que 1 | 1 es 1.
3 + 7 es 10 mientras que 3 | 7 es 7.

Otro detalle, no confundir | con ||. El operador OR de bits es | mientras que || es el operador lógico OR.
3 + 5 es 8.
3 | 5 es 7.
3 || 5 es 1.

void setup() {
  Serial.begin(9600);
  Serial.println(3 + 5);
  Serial.println(3 | 5);
  Serial.println(3 || 5);
}

void loop() {
}

Resultado del programa anterior:



8
7
1

Prueba a definir los valores de los led como valor entero:
en vez de

#define LED8 256 // valor equivalente en decimal al LED8

int LED8 = 256;

bit 31?

No, 15 porque hablo del bit 15 de los literales definidos en las macros.

Saludos

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.