Found program to operate MM5451 but don't understand it all.

I found a person on youtube who was nice enough to figure out how to program the MM5451 and give a video of it, but the program doesn’t do what I need for my project. I want to light up individual LEDs in sequence for all 35 possible outputs. He programmed it to show how it works for 8 LEDs and one 7 segment. Here’s the program he came up with:

/*

See File mm5451_demo.py

for driving common anode displays

brightness control eliminates need for resistors

Vcc 4.75 - 11V

7-segment common anode display connected bits 1-8

8 LEDs bits 9-16 common anodes

msb
PGFEDCBA
0b00111111 - 0
0b00000110 - 1
0b01011011 - 2
0b01001111 - 3
0b01100110 - 4
0b01101101 - 5
0b01111101 - 6
0b00000111 - 7
0b01111111 - 8
0b01100111 - 9
*/

#define CLK 2 // to MM5451 pin 21
#define dataBit 3 // to MM5451 pin 22

// 7-segment display code array
byte segCode = {
0b00111111, 0b00000110, 0b01011011,
0b01001111, 0b01100110, 0b01101101,
0b01111101, 0b00000111, 0b01111111,
0b01100111 };

void setup() {
pinMode(CLK, OUTPUT);
pinMode(dataBit, OUTPUT);
digitalWrite(CLK, 0);
digitalWrite(dataBit, 0);
}

// the loop routine runs over and over again forever:
void loop() {

for (int myCount = 0; myCount <= 255; myCount++) {
// start bit
digitalWrite(dataBit, 1);
pulseCLK();
// the “+ 0x80” turns on DP
ssrWriteLSB(segCode[myCount % 10]); // MOD myCount = 0-9
ssrWriteMSB(myCount); // eight LEDs binary count 0-255
zeroWrite(21); // pad remaining bits with 0s
delay(500);
}

} // end loop

void pulseCLK() {
digitalWrite(CLK, 1);
digitalWrite(CLK, 0);
}

// LSB out first!
void ssrWriteLSB(byte value) {
for(int x =0; x < 8; x++) {
byte temp = value & 0x01;
if (temp == 0x01) digitalWrite(dataBit, 1); // data bit HIGH
else digitalWrite(dataBit, 0); // data bit LOW
pulseCLK();
value = value >> 0x01; // shift right
}
}

// MSB out first!
void ssrWriteMSB(byte value) {
for(int x =0; x < 8; x++) {
byte temp = value & 0x80;
if (temp == 0x80) digitalWrite(dataBit, 1); // data bit HIGH
else digitalWrite(dataBit, 0); // data bit LOW
pulseCLK();
value = value << 0x01; // shift left
}
}

void zeroWrite(byte num1) {
digitalWrite(dataBit, 0); // data bit LOW
for(int x = 0; x < num1; x++) pulseCLK();
}

I see how he has different routines for the individual LEDs and for the 7 segment. What i don’t understand is how the main subroutines for LSB and MSB work. I believe the LSB and MSB routines can be condensed into one that will light up all 35 led’s
I also believe that the byte “value” is MyCount which is from 0 to 255. But what is happening to the byte value when it’s added to hex 80 which is decimal 128. I have tried adding these bytes all different ways to see what pattern is causing a clock bit to be pulsed out but I can’t figure it out. Any help here would be greatly appreciated.

Thanks,
Bryan

One question. Do you have an MM5451 in front of you?

I believe the LSB and MSB routines can be condensed into one that will light up all 35 led's

If the one function takes a second argument to define what to and the byte with, that is true.

But what is happening to the byte value when it's added to hex 80 which is decimal 128.

There is no ADDing going on. There is ANDing going on, which is something completely different. You need to look up the bitwise and operator to see what it does.

I have tried adding these bytes all different ways

So, stop. Adding is not what needs to happen.

Yes to the person asking if I have an MM5451 in front of me. It's on my breadboard and working.

To those telling me about ANDing, I realized the difference between adding and anding after i read the operator definition again.

What I see happening is the following:

byte temp = 0 & 0x80 (decimal 128 or binary 00000001)
which to me looks like this
00000000
00000001

The anding of the above is 0 and 0 is not 128 so the bit is LOW

For byte temp = 1 & 0x80
I see:
10000000
00000001

The anding of the above is 0 again which is also not 128 so the bit is low

So far the bits both low don't match what's coming out of the pins. The
pins are bits 9 thru 16, and the LSB is 16 so the count is going
1
01
11
001
etc.

I don't see this pattern from the program. What am i doing wrong?

i don’t see how the value of temp equals hex 80 in the patterns needed to create data bit highs and lows for the appropriate outputs for the LEDs.

So, create a simple sketch. In setup(), have a for loop that runs from 0 to 255. In the loop, and the index with 0x80 and print the result.

Actually, I think there is something missing from your code. I suspect that value is supposed to be shifted left or right by the value of i before the anding happens.

Paul,
The shifting is done at the end of the subroutine. The last line of code is
value =value << 0x01; //shift left

What do you mean by AND the INDEX? What’s the index?

That program was complete garbage. Small wonder you can’t understand it. Try this:

/*
MM5451 LED IC demo
Routines to write values to all 35 pins of the IC
2015-04-03 aarg
 */

#define MMclockPin 2 // to MM5451 pin 21
#define MMdataPin  3 // to MM5451 pin 22

// demo values:
byte testvalues[] = {0x00, 0xff, 0x00, 0xff, 0x00};

void setup() {
  Serial.begin(9600);
  pinMode(MMclockPin, OUTPUT);
  pinMode(MMdataPin, OUTPUT);
  digitalWrite(MMclockPin, 0);
  digitalWrite(MMdataPin, 0);

  write35bits(testvalues);
  LED_on(testvalues, 2);
  LED_off(testvalues, 13);
}

void loop() {
  // in here you create arrays of LED values
  // similar to byte array testvalues[], above
  // and pass them to write35bits(), set and reset then with LED_on and LED_off.
  // Have fun!
} // end loop


// write 35 bits of LED data to the chip
//
void write35bits(byte values[])   {
  databitWrite(1); // send start bit
  for (int index = 0; index < 35; index++)   {
    byte temp = values[index / 8] & 1 << (index % 8);
    if (temp != 0)
      databitWrite(1); // data bit HIGH
    else
      databitWrite(0); // data bit LOW
  }
//
// debug:
  Serial.println(); //debug print
//
//
}

void LED_on(byte values[], byte num)   {
  values[num / 8] |=  1 << (num % 8);
  write35bits(values);
}

void LED_off(byte values[], byte num)   {
  values[num / 8] &=  ~(1 << (num % 8));
  write35bits(values);
}
void  databitWrite(boolean b)   {
  //  digitalWrite(MMclockPin, 0);
  //  digitalWrite(MMdataPin, b);
  //  digitalWrite(MMclockPin, 1);
  Serial.print(b); //debug print binary string
}

The shifting is done at the end of the subroutine. The last line of code is
value =value << 0x01; //shift left

OK. I missed that. What the & is doing then is masking the first bit. Only the high order bit in the byte ends up being reflected in temp. The other 7 bits are all 0. So, if the high order bit was 0, temp will be 0. If the high order bit was 1, temp will be 0b10000000, or 0x80.

Got your program aarg! Thanks for that! Will have to disect it and see what I can learn from it. running it as is tho turns on all the leds. Don't know if that should happen if you gave a discrete number of test parameters.

Paul, Thank you for that clarification. That makes more sense than anding it the way i was. I'll see how the patterns look when i treat it that way. Perhaps that will help me rewrite it better for my own needs. I am wondering tho if I need to increase MyCount to 32,768 in order to get a counting pattern that works for ALL the bits on the chip.

bgreifinger:
Got your program aarg! Thanks for that! Will have to disect it and see what I can learn from it. running it as is tho turns on all the leds. Don't know if that should happen if you gave a discrete number of test parameters.

Paul, Thank you for that clarification. That makes more sense than anding it the way i was. I'll see how the patterns look when i treat it that way. Perhaps that will help me rewrite it better for my own needs. I am wondering tho if I need to increase MyCount to 32,768 in order to get a counting pattern that works for ALL the bits on the chip.

I put the bit output code all in one function for a reason. One is that you can see the output works with the serial debug. But the other is that you can fix any output issues by changing the code there.

I strongly suspect that there are timing issues with the pulses. The data may be clocked out too fast. So you need to modify it like this:

void  databitWrite(boolean b)   {
  digitalWrite(MMclockPin, 0);
  delay(1);
  digitalWrite(MMdataPin, b);
  delay(1);
  digitalWrite(MMclockPin, 1);
}

Unfortunately, I don't have the hardware to play with. But this is the first thing I would try. If it works, then you can figure out a way to slow it down, but not so drastically.

The LED output should be the same as the serial debug output.