Currently working on understanding shift registers and traing to display binary number from 65535 to 0 on a 16 LED's. Below you can see schematics I am using.

Used topology The code I am using is

int latchPin = 8;
int clockPin = 12;
int dataPin = 11;
int numberToDisplay=65535;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);

void loop() {

    digitalWrite(latchPin, LOW);

    shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);  

    digitalWrite(latchPin, HIGH);

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
    uint8_t i;

    for (i = 0; i < 16; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
            digitalWrite(dataPin, !!(val & (1 << (15 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);        

Problem is when I change numberToDisplay from 0 to 225, everything works and LEDs are lighted correspondingly (if numberToDisplay=225 all red lights are on). But if numbers are bigger than 225 everything just stops working and nothing lights up.

Thank you in advance


3 Answers 3


Your problem is entirely that you declare val to be uint8_t, instead of uint16_t. You are truncating your data to 8 bits before displaying it. One other note, the 74HC595 has a maximum total drive current of 50mA. Your circuit will draw around 90mA for each of the 74HC595's if all of the LEDs are on. You may want to change the resistors to something bigger (510 Ohm, for example) to avoid this problem. Of course that will make the LEDs dimmer, so it's a tradeoff. Here's your project in 123D Circuits. You can simulate it in the browser and look at the code running in the Arduino there.

enter image description here


notice the uint8_t val. You are truncating the 16-bit number back to 8 bit.

One way of fixing this is to split the 16-bit number before calling shiftOut.

shiftOut(dataPin, clockPin, MSBFIRST, highByte(numberToDisplay));  
shiftOut(dataPin, clockPin, MSBFIRST, lowByte(numberToDisplay));  
  • Great, havent thought about it. Maybe I could change uint8_t val to byte val in this way there could be any lenght of bits, or it don't work that way?
    – Austris
    Commented Oct 22, 2015 at 12:54
  • uint8_t val byte are identical (at least in AVR-C), so that won't help.
    – Gerben
    Commented Oct 22, 2015 at 16:08

I agree with Gerben. But Byte datatype will not help you, since Byte type is an unsigned 8-bit type (the same as uint8_t). Why don't you try this header:

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint16_t val)

Or follow Gerbens idea, just using out of the box shiftOut routine. It shifts 8-bit variables, so you shouldn't need to re-implement the routine.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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