More shift register problems?

After much experimentation, I have finally given up and registered here in the hopes that someone can tell me what I'm doing wrong. So, first post, I'm a super newbie, etc., etc.

I have an (older) Arduino Duemilanove and I'm muddling through controlling a King Electronics MBI5027GN 16-bit LED shift register. The problem that I'm having is that I can't get the very first LED nor the very last LED to light.

I can shift in various patterns and make the other lamps stay lit, but when I try to shift in 1 or 32768, they don't light. The very last lamp (32768) will blink once very quickly rather than staying on if its bit is set.

I'm not sure if this is a problem with my (admittedly cheap) MBI5027 and I should just get a nicer, newer, better shift register, or if I'm doing something entirely wrong. Here is the code I'm running:

int SDIPIN = 0;
int CLKPIN = 1;
int LEPIN = 2;

void setup() {
  pinMode(SDIPIN, OUTPUT);
  pinMode(CLKPIN, OUTPUT);
  pinMode(LEPIN, OUTPUT);
  
  digitalWrite(LEPIN, LOW);
  delay(5000);
}

void shift_out_16(unsigned int v) {
  long n;
  digitalWrite(CLKPIN, LOW);   // be sure CLK is idle at zero
  digitalWrite(LEPIN, LOW);

  for (n=0; n<16; n++)
  {
    if (v >> (15 - n) & 0x1) // most significant bit first
    {
      digitalWrite(SDIPIN, HIGH);
    } else {
      digitalWrite(SDIPIN, LOW);
    }

    digitalWrite(CLKPIN, HIGH);
    digitalWrite(CLKPIN, LOW);
  }
  digitalWrite(LEPIN, HIGH);
}


void loop()
{
  shift_out_16(32769);
  delay(1000);
}

32769 should light the first and last lamps, correct? I have used values like 1056, which lights the sixth and eleventh, and those values work just fine. The lamps are bright, no flicker, everything is great.

So what's up with out 0 and out 15?

OK I have an update here that might help. It turns out that my first LED lamp was actually dead. Now I can light that one fine both by itself and along with any combination of others.

The problem seems to be that whenever the last bit is set, nothing lights up, all of the lamps set to be on just blink once very briefly.

I changed the loop in my program to generate a random number between 1 and 32767, which excludes the highest bit, and it happily blinks all of the lamps on and off. As soon as I increase it to include the final bit, any pattern that has that bit set causes all of the lamps to just blink once quickly.

Bad shift register? I'm leaning toward getting a different one.

Try throwing in a short delayMicroseconds() after each digitalWrite. Or it might be just needed before you throw the latch high.

The datasheet suggests that the latch pin should go up and then low.

So I would rewrite your shift routine as:

void shift_out_16(unsigned int v) {
  unsigned short mask=0x8000; //msb first
  //long n;
  //digitalWrite(CLKPIN, LOW);   // be sure CLK is idle at zero
  digitalWrite(LEPIN, LOW);

  //for (n=0; n<16; n++)
  do {
    digitalWrite(CLKPIN, LOW); //clk low
    //if (v >> (15 - n) & 0x1) // most significant bit first
    if (v & mask)
    {
      digitalWrite(SDIPIN, HIGH);
    } else {
      digitalWrite(SDIPIN, LOW);
    }

    digitalWrite(CLKPIN, HIGH);
    //digitalWrite(CLKPIN, LOW);
    mask = mask >> 1; //shift to the next pin
  } while (mask);
  digitalWrite(LEPIN, HIGH);
  //potentially a delay here. 20ns min per datasheet
  digitalWrite(LEPIN, LOW); //latch data into output registers
}

Or you can simply use shiftOut()

  shiftOut(SDIPIN, CLKPIN, MSBFIRST, v>>8); //send msb
  shiftOut(SDPIN, CLKPIN, MSBFIRST, v); //send lsb
  digitalWrite(LEPIN, HIGH);
  digitalWrite(LEPIN, LOW);

Good news and bad news, folks.

First, dhenry, I love your shift out version so much better than the one I lifted from someone else's sketch. Shifting the mask is really clever and just makes so much more sense to my mind.

Also I really appreciate all of your guys' help interpreting the datasheet, which is a whole new adventure for me.

Unfortunately, none of these tweaks has gotten that last output to light up. I went so far as to delay by 100 milliseconds between changing the latch pin and still no dice. Here is what it looks like now:

void shift_out_16(unsigned int v) {
  unsigned short mask=0x8000; //msb first
  digitalWrite(LEPIN, LOW);

  do {
    digitalWrite(CLKPIN, LOW); //clk low
    if (v & mask)
    {
      digitalWrite(SDIPIN, HIGH);
    } else {
      digitalWrite(SDIPIN, LOW);
    }

    digitalWrite(CLKPIN, HIGH);
    mask = mask >> 1; //shift to the next pin
  } while (mask);

  delay(100);
  digitalWrite(LEPIN, HIGH);
  delay(100);
  digitalWrite(LEPIN, LOW); //latch data into output registers
}

But here is a new piece of data that might help... If I shift out 65535, all of the lamps turn off no matter what. If I then shift out any smaller value, all of the lamps blink on for 100 milliseconds. I must assume this is the 100 milliseconds while the latch pin is high, then it goes low and the new value takes effect.

I'm hoping someone has seen something like this before because I have zero experience so I don't even know what the usual suspects are.

Are you sure that you haven't mixed the OE pin with LE pin?

I reviewed the datasheet again to make sure... SDI, CLK, and LE are immediately below the ground pin on the left top edge; those are the pins connected to the Arduino. I am pretty confident that OE is wired straight to ground.

This behavior is really weird because all of the other lamp outs work perfectly fine in any combinations and overall I'm quite pleased.