0
\$\begingroup\$

Problem:
Driving 74HC154 Decode with Atmega328 using Arduino software.
Decoder Outputs Y0 – Y10 (pins 1 – 11) seem to be picking up signals from each other.
The outputs are not random noise. Changing which output pins are being turned on changes which output pins have the spurious output signal. This is occurring with the 74HC154 outputs not connected to a circuit and also when connected to an LED array. Since 74HC154 is being used to turn PNP transistors on and off, the spurious signals are incorrectly turning on PNP transistors.

Test Setup: Breadboard with Atmega328 running Arduino software. Breadboard

Nexperia 74HC154 Pinout and 74HC154 Truth Table enter image description here

Example 1: Arduino Code:

//Inputs into 74HC154 pins 20-23

int InputA0 = 4;

int InputA1 = 5;

int InputA2 = 2;

int InputA3 = 3;

void setup()

{

pinMode(InputA0, OUTPUT);

pinMode(InputA1, OUTPUT);

pinMode(InputA2, OUTPUT);

pinMode(InputA3, OUTPUT);

}

void loop()

{

//Output Y0

digitalWrite(InputA0, LOW); 

digitalWrite(InputA1, LOW); 

digitalWrite(InputA2, LOW);

digitalWrite(InputA3, LOW); 


delay(1);  

//Output Y7

digitalWrite(InputA0, HIGH);

digitalWrite(InputA1, HIGH);

digitalWrite(InputA2, HIGH); 

digitalWrite(InputA3, LOW); 


delay(1);  

}

Outputs Y0 and Y7 look great. Output Y6 should be off, but has 5 volt short spikes/bursts. These spikes seem to line up with Y0 and Y7 transitions from High to Low. Same with Y3 and Y4 - Spikes..why?

Outputs Y2 and Y5 are off as they should be with no spikes.

Images 1-4 Images 5 - 8

Outputs with spikes: Y1, Y3, Y4, Y6, Outputs without spikes: Y2, Y5, Y8, Y9, Y10

Now the interesting part:

Example 2:

Turn off Y0 and turn on only Y1 and Y7

//Output Y1 

digitalWrite(InputA0, HIGH); 

digitalWrite(InputA1, LOW); 

digitalWrite(InputA2, LOW);

digitalWrite(InputA3, LOW); 


delay(1);

//Output Y7

digitalWrite(InputA0, HIGH);

digitalWrite(InputA1, HIGH);

digitalWrite(InputA2, HIGH); 

digitalWrite(InputA3, LOW); 


delay(1); 

Spikes now on: Y3, Y5

No spikes on: Y0, Y2, Y4, Y6, Y8, Y9, Y10

IMages 9 -12

So Y3 kept the spikes, and spikes went away on Y4 and Y6. Y5 which had no spikes, now has spikes.

Finally, this one may have a clue in it.

Example 3:

Turn on only Y4, Y7 and Y8

//Output Y4

digitalWrite(InputA0, LOW); 

digitalWrite(InputA1, LOW); 

digitalWrite(InputA2, HIGH);

digitalWrite(InputA3, LOW); 


delay(1);  

//Output Y7

digitalWrite(InputA0, HIGH); 

digitalWrite(InputA1, HIGH); 

digitalWrite(InputA2, HIGH);

digitalWrite(InputA3, LOW); 


delay(1);  

//Output Y8

digitalWrite(InputA0, LOW);

digitalWrite(InputA1, LOW);


digitalWrite(InputA2, LOW); 

digitalWrite(InputA3, HIGH); 


delay(1);  

The clue is that spikes appear in Y4 only when BOTH Y7 and Y8 are also on.

Y4 does not have spikes if only Y7 OR Y8 are on:

Images 13 - 14

Images 15 - 16

Spikes appear to be related to internal switching within 74HC154.

Question: Are these spikes internal to the chip? Is there any way to eliminate them?

Is this an issue with the Nexperia 74HC154?

\$\endgroup\$
  • \$\begingroup\$ your example 2 does a sequence Y1, Y3, Y7 ...... example 3 does a sequence Y4,Y5,Y7,Y6,Y4,Y0,Y8 \$\endgroup\$ – jsotola Apr 28 at 2:02
  • \$\begingroup\$ How wide are the 'spikes'? \$\endgroup\$ – Bruce Abbott Apr 28 at 2:38
1
\$\begingroup\$

You have encountered the well known phenomenon of glitching in multi-bit logic transitions.

Your problem is especially severe, because your Arduino code changes the controlling word one bit at a time, using the very slow digitalWrite() function for each bit in turn. You could substantially reduce the glitching if you used bits from the same ATmega GPIO port, and wrote them all at once by writing directly to the port register.

However, even changing all the input bits to a logic function at exactly the same time does not mean that the output will change cleanly from one state to another. For this reason, systems which must avoid spurious outputs rely on synchronous logic whereby the output of a combinatorial function is held in a register, and the time when the inputs change is purposefully separated from the time when the register is clocked to latch a new result, permitting the glitchy transition to complete and settle before "anything looks at" the result. So adding a register to the output could be a complete solution.

Another option workable in some cases is to use an explicit enable pin to disable all outputs, then change the control word, wait an instant, and re-enable the outputs. If your application does not require that some output always be active, this can be a simple fix.

Another solution for output demultiplexing is to use something like an I2C I/O expander, where you clock data into the peripheral chip's registers, but the new value only appears on that chip's output pins when the transfer operation is fully completed.

\$\endgroup\$
  • \$\begingroup\$ Great information! \$\endgroup\$ – RickH Apr 28 at 1:00
0
\$\begingroup\$

You should get a lot from Chris' answer, but just to add a suggestion you could use a 74HC374 latch which has both the synchronous nature and the output enabling ability. You connect the inputs of the 374 to the outputs from the micro, then once all the bits are written to the ports you clock the 374 to transfer the whole word to it's outputs which you then connect to the decoder. Depending on how many LEDs you need you could eliminate the decoder and use the 374 outputs directly or add another 374 with it's own clock to get the 16 outputs. This scheme would allow any combination of the LEDs to be on at once if that would be nice for your application.

\$\endgroup\$
  • \$\begingroup\$ Followed Chris's advice using Latch HIGH/LOW to Disable/Enable Decoder outputs. Connected Atmega pin 15 to Decoder pin 19 E1. Set Atmega Pin 15 to output as latchPin. Modified code to have latchPin HIGH just before Decoder digitalWrites and latchpin LOW just after all four Decoder digitalWrites. The latchpin LOW digital writes takes long enough to allow the A0-A3 Digital Writes to settle out. This solved the spurious signal problem! I re-ran my 3 examples and all look perfect. \$\endgroup\$ – RickH Apr 28 at 11:20
0
\$\begingroup\$

You write the chip input one bit at a time so the output just follows the input. In fact it does exactly what your program tells it to do and that way causes pulses. But even if you changed all inputs at the same time, it might have short spikes because of how signals have propagation delays inside the chip. For this reason there are the enable pins that can disable the chip to stable state when changing the inputs.

\$\endgroup\$
  • \$\begingroup\$ Yes now I see that each digitalWrite was changing each bit independently and changing outputs based on the combination of A0-A3 at that instant! Makes perfect sense now. As you said, the chip was doing what the software told it to do! Thanks so much. \$\endgroup\$ – RickH Apr 28 at 11:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.