Problems with Arduino replacing IO-Warrior in LED-Matrix

Hi everybody,

my first post in which im strongly requesting your help, even though it is a bit to read... :astonished:
I have some Problems with my Arduino controlling an mixture of LEDs and 7-Segment displays arranged in an Matrix. I am really desperate about it because I have tested a lot of arrangements and switching the code. But nothing really helped. So any help, tips or comments are appreciated!!

The facts:
As i said, I have some LEDs and 7-Segment displays arranged in an matrix. The matrix is controlled by the MIC5891 latched shift register as the source input driver and the MIC5821 as the current sink output driver. (see attached drawing)
The shift registers were before controlled via an IO-Warrior, who shifted the bytes via a serial connection to the registers.
The Matrix was operated in a multiplexing mode by the IO-Warrior.
The Matrix was powered via an external 12V 600mA power supply. The 5V supply for the Micrel Shift registers are supplied by an external power supply. The arrangement was working very fine during the last 7 years. But now it was time to modernize it.

The trial:
To test my idea, I exchanged the IO-Warrior40-Mod Chip with an Arduino Uno R3. To be precise, I removed the IO-Warrior chip from its socket and only connected the OE, CLK, Data and Latch Pin to the Arduino. Then I shifted some Bytes to the MIC shift registers. (see attached code)

My observations:
The LEDs and 7-Segment displays are displaying the right things. But they are glowing very dark.
When I tried to change the delay, e.g. slow it down, the LEDs and 7-Seg start to glow brighter, but they start to flicker (well, they should be, because I am lowerig the refresh rate an the persistance of vision is not applicable any more). But you have an display like an old flickering CRT-Display. So unusable to me.

What am I doing wrong? I changed nothing on the power supply. I just changed the way, the shift registers are getting their 0s and 1s. Why are the LEDs so dark when I use the Arduino???
I even tried it with an SPI connection....same problem.
I've tried it with an constantly tied high latch pin and an constantly tied low OE pin.....no improvement.
I've tried to change the digitalWrite() function, because i have read it could be to slow under some conditions...no improvement
I've even put the IO-Warrior back in its socket and tried to run it, because i thought, i've might broken something....but everything worked fine....

Why can't I change the one Microcontroller(IO-Warrior) with another one(Arduino Uno) and everything works...this seems not logical to me... :~

One of the Codes I used:

const int LATCH     = 10;          //Latch/Strobe
const int OE        = 12;          //OE (Output Enable)
const int DOUT      = 11;          //Data
const int CLK       = 9;           //Clock


int delayMicrosecondstime=16383;

void setup()
{
  pinMode(CLK,OUTPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(DOUT, OUTPUT);
  pinMode(OE, OUTPUT);

  //7-Segment Display Init
  digitalWrite(LATCH,LOW);
  digitalWrite(LATCH,HIGH);
  digitalWrite(OE,HIGH);

}              
void loop() {
  /*
This is an version with the Latch pin constantly tied high
*/
  digitalWrite(OE,HIGH);
  //digitalWrite(LATCH,HIGH);
 
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //X
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //a
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //B
   shiftOut(DOUT, CLK, MSBFIRST, B01011011); //c
   shiftOut(DOUT, CLK, MSBFIRST, B00000010); //d
   
   
 // digitalWrite(LATCH, LOW);
  digitalWrite(OE, LOW);
  
  delayMicroseconds(delayMicrosecondstime);
  
  digitalWrite(OE,HIGH);
//  digitalWrite(LATCH,HIGH);
 
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //X
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //a
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //B
   shiftOut(DOUT, CLK, MSBFIRST, B01001111); //c
   shiftOut(DOUT, CLK, MSBFIRST, B00000100); //d
   
   
//  digitalWrite(LATCH, LOW);
  digitalWrite(OE, LOW);
  
  delayMicroseconds(delayMicrosecondstime);
 
  digitalWrite(OE,HIGH);
//  digitalWrite(LATCH,HIGH);
 
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //X
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //a
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); //B
   shiftOut(DOUT, CLK, MSBFIRST, B00111111); //c
   shiftOut(DOUT, CLK, MSBFIRST, B00001000); //d
   
//  digitalWrite(LATCH, LOW);   
  digitalWrite(OE, LOW);   
  
  delayMicroseconds(delayMicrosecondstime);

  /*
and so on 
and so on....
*/
}

Why on earth would you be holding the latch high and gating the enable? No wonder it is dim.

Common sense suggests the opposite.

And - why are you not using MAX7219s which perform all of the multiplexing for you?

Hi Paul,

thank you for your posting! I am sorry, my topic is a bit complicated. I try to explain it.

Besides the other alternatives, with the configuration where the latch is permanently tied high and the Output Enalble is tied low, I tried to test the shift registers. I wanted to see if they are getting the bytes in right manner.
At my fitst runs, I tried it the normal way with latch only high when data is coming and OE high when the outputs should be active.
But it also did not improve the intensity of the LEDs.

I would love to use the MAX7219. I even bought one to test it. But the problem is, all LEDs are common Anode.... :frowning:

Data Sheet MIC5821: http://www.micrel.com/_PDF/mic5821.pdf
Data Sheet MIC5891: http://www.micrel.com/_PDF/mic5891.pdf

FulliGonzales:
At my first runs, I tried it the normal way with latch only high when data is coming and OE high when the outputs should be active.
But it also did not improve the intensity of the LEDs.

The outputs should always be enabled - unless perhaps you want to use some form of PWM brightness control. That's exactly what the latches are for - they hold the current data until you have shifted in all the next set at which point the switch from the last pattern to the next is immediate with no break.

FulliGonzales:
I would love to use the MAX7219. I even bought one to test it. But the problem is, all LEDs are common Anode.

So what has that to do with anything?

Hey Paul,

thank you again for your answer and your help! :slight_smile:

Paul__B:
they hold the current data until you have shifted in all the next set at which point the switch from the last pattern to the next is immediate with no break.

If I understand you right, you mean . it like this way, e.g? Right? :

const int LATCH     = 10;          //Latch/Strobe
const int OE        = 12;          //OE (Output Enable)
const int DOUT      = 11;          //Data
const int CLK       = 9;           //Clock

int delayMicrosecondstime=16383;

void setup()
{
  pinMode(CLK,OUTPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(DOUT, OUTPUT);
  pinMode(OE, OUTPUT);
  }
void loop()
{
  digitalWrite(OE,HIGH);
  digitalWrite(LATCH,HIGH);

   shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
   shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
   shiftOut(DOUT, CLK, MSBFIRST, B01011011); 
   shiftOut(DOUT, CLK, MSBFIRST, B00000010); 
   
  digitalWrite(LATCH, LOW);
  digitalWrite(OE, LOW);
  
  delayMicroseconds(delayMicrosecondstime);
//... //repeat all
//...}

I've tried it durig my trials, but it also did not work.
I think, my issue has nothig to do with the order, in which im writing the Latch and OE Pin high/low. I've tried all imaginable sequences of them.... :~

Paul__B:
So what has that to do with anything?

I'm sorry, I don't understand your question? Are you aiming at the common anode thing? The MAX7219 can only drive common Kathode 7-Segment displays in a relieable way....

FulliGonzales:
If I understand you right, you mean . it like this way, e.g? Right? :

const int LATCH     = 10;          //Latch/Strobe

const int OE        = 12;          //OE (Output Enable)
const int DOUT      = 11;          //Data
const int CLK       = 9;           //Clock

int delayMicrosecondstime=16383;

void setup()
{
  pinMode(CLK,OUTPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(DOUT, OUTPUT);
  pinMode(OE, OUTPUT);
  }
void loop()
{
  digitalWrite(OE,HIGH);
  digitalWrite(LATCH,HIGH);

shiftOut(DOUT, CLK, MSBFIRST, B00000000);
   shiftOut(DOUT, CLK, MSBFIRST, B00000000);
   shiftOut(DOUT, CLK, MSBFIRST, B00000000);
   shiftOut(DOUT, CLK, MSBFIRST, B01011011);
   shiftOut(DOUT, CLK, MSBFIRST, B00000010);
   
  digitalWrite(LATCH, LOW);
  digitalWrite(OE, LOW);
 
  delayMicroseconds(delayMicrosecondstime);
//... //repeat all
//...}




I've tried it during my trials, but it also did not work.
I think, my issue has nothing to do with the order, in which I'm writing the Latch and OE Pin high/low. I've tried all imaginable sequences of them.... :~

Output Enable needs to be set low in the "setup" function and never changed anywhere else in your code. Even simpler, just tie it to ground.

FulliGonzales:
I'm sorry, I don't understand your question? Are you aiming at the common anode thing? The MAX7219 can only drive common Cathode 7-Segment displays in a reliable way....

The MAX7219 drives an 8 by 8 matrix. A matrix is what you already have in your diagram. You just connect the matrix you have, to the MAX7219. It really does not care how the matrix looks as long as you connect the cathodes to the cathode drivers and the anodes to the anode drivers. Much simpler than what you have, only one resistor required per matrix.

Hello Paul,

Thank you, now I understand you.
I tried to constantly tie the OE pin to Ground...no effect.. still faintly glowing LEDs.

Thank you for your idea with the MAX7219, I never thought about it this way. I have only read, that they are for common kathode....
I will try it the next days on my breadboard.
Nevertheless, to use MAX7219 would imply a new design and etching new circuit board. I would like to avoid it as long as possible.
So maybe there is another solution to my problem.... :~

OK, I have looked at your circuit and your code. You have all the anode drivers essentially in parallel as far as the data stream goes, and the data ripples through to the chain of cathode drivers. You are multiplexing by anode drivers, consistent with using common anode 7-segment displays. I was for a moment puzzled that you were shifting five bytes of data in your last example but that clearly applies to sending cathode data to five matrices, followed by the anode select.

OK, that seems to make sense so far; I can't spot the problem. I gather you have by now, removed any reference to OE in the "loop" code, and that there is no extra delay function at the end of the loop that you have not illustrated. I can't see the point in using "delayMicroseconds()"; I would at least use "delay(10) " at each step for testing purposes.

In fact, to start with, I would try this stripped code:

const int LATCH     = 10;          //Latch/Strobe
const int OE        = 12;          //OE (Output Enable)
const int DOUT      = 11;          //Data
const int CLK       = 9;           //Clock

void setup()
{
  pinMode(CLK,OUTPUT);
  pinMode(LATCH,OUTPUT);
  pinMode(DOUT, OUTPUT);
  pinMode(OE, OUTPUT);
  digitalWrite(OE, LOW);
  digitalWrite(CLK, LOW);

// Practical loop skeleton:

  shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
  shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
  shiftOut(DOUT, CLK, MSBFIRST, B00000000); 
  shiftOut(DOUT, CLK, MSBFIRST, B01011011); 
  shiftOut(DOUT, CLK, MSBFIRST, B00000010); 
  digitalWrite(LATCH,HIGH);
  digitalWrite(CLK, LOW);           // timing trick
  digitalWrite(LATCH, LOW);
  delay(10)
}
void loop()
{

}

If this lights up some LEDs nicely, I suggest you replicate this structure into your original code.

Hi Paul,
once again thank you for your input! :slight_smile:

Paul__B:
I can't see the point in using "delayMicroseconds()"; I would at least use "delay(10) " at each step for testing purposes.

At my first trials, I used the "delay()" function but recognized, that i needed a more detailed timing, because with a lot LEDs switched on they started to flicker and get dim @ delay(1);. So I discovered the "delayMicroseconds()" function. With this function I could implement a delay below 1ms. But it didn't help either. :disappointed_relieved:

Paul__B:
I gather you have by now, removed any reference to OE in the "loop" code, and that there is no extra delay function at the end of the loop that you have not illustrated.

Done! Thanks this was a good advice. Now I could adress the LEDs more stable. But still flickering and dim

But your code didn't work. All LEDs are dark. I still have to investigate why. I'm writing some feedback tomorrow....need some sleep now.... :sleeping:

After a few days some news:

I couldn't find out, why your code isn't working, Paul. I think it has something to do with the sequence the MIC5821/MIC5891 work.
I post a excerpt from the Datasheet:

Serial data present at the input is transferred into the shift register on the rising edge of the CLOCK input pulse. Additional CLOCK pulses shift data information towards the SERIAL DATA OUTPUT. The serial data must appear at the input prior to the rising edge of the CLOCK input waveform.
The 8 bits present in the shift register are transferred to the respective latches when the STROBE is high (serial-to-parallel conversion). The latches will continue to accept new data as long as the STROBE is held high. Most applications where the latching feature is not used (STROBE tied high) require the OUTPUT ENABLE input to be high during serial data entry.
Outputs are active (controlled by the latch state) when the OUTPUT ENABLE is low. All Outputs are low (disabled) when the OUTPUT ENABLE is high. OUTPUT ENABLE does not affect the data in the shift register or latch.

so maybe the digitalWrite(CLK, LOW); isn't working and the digitalWrite(LATCH,HIGH); must be executed before the data shifting starts. But it is only a assumption by me...

Nevertheless I'm going to try to unse a timer interrupt to shift the data and set the OE and LATCH pin. Maybe this will help.

Meanwhile maybe there are some other ideas, which might help me? Any advices are appreciated! Thanks! :slight_smile:

FulliGonzales:
so maybe the digitalWrite(CLK, LOW); isn't working and the digitalWrite(LATCH,HIGH); must be executed before the data shifting starts. But it is only a assumption by me...

No, the import of this is that the function is a latch, and not a D-type flip flop. A latch passes through all the data while "open", and retains the last data when it "closes" while a D-type flip flop locks in the data at the moment it is clocked, and only at that moment, no other. So you do not want the latch to be "open" as you are shifting data as the display would then be changing as you do so.

I begin to wonder in fact, whether the faint lights you were seeing were in fact, the data as it shifts through the register with the latch open whilst my more correct code shows nothing because the data is not being shifted in correctly before the latch is opened. Personally I would be writing my own shift routines rather than using "shiftOut" in order to understand exactly what was happening. I am not in a position to pen such routines for you just at this moment as I am limited by my little netbook!

FulliGonzales:
Nevertheless I'm going to try to use a timer interrupt to shift the data and set the OE and LATCH pin. Maybe this will help.

Interrupts are not going to improve things, just cause more problems. I have explained that OE is once set (LOW) and never changed since all it does is turn off the LEDs otherwise.