Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

multiplexing algorithm

Status
Not open for further replies.

keny

New Member
Hey I have been digging through the threads here on the site and am not finding quite what I am looking for, which is.....

I'm working on an LED array that is 8 by 32 using 4 latched shift registers. It isn't a premade number display like the examples here, it's a bigger custom sign.

I am not so comfortable using the 595's and may change that but I'd rather keep off of the hardware subject and just get the whole mux thing under my belt.

So like... can someone provide a basic ordered list of how one would multiplex an led array?

--


Thanks for anything you all may have to offer.
 
Last edited:
You should probably post the schematic you're using...

You should be using an interrupt driven display driver with an interval no less than 2-msecs (62.5-Hz refresh rate) to avoid flicker.

Loading the four shift registers in parallel (bit banged 4 channel SPI of sorts) is the tricky part.

I'll try to help if I can but you need to provide more info' (language, schematic)...

<added>

Consider replacing the 74HC595's and transistors with 500-ma MIC5821 serial-to-parallel sinking drivers or 500-ma MIC5891 serial-to-parallel sourcing drivers.
 
Last edited:
I thought about what I wanted to get out of this thread again, and realized that it was a mistake giving you a schematic at all. I am trying to understand the structure of a multiplexed system. Anything I am currently prototyping is absolutely irrelevant to that. Here's my specs: 8x32 led array, with many different colored and sized LED's. let's build some ideas based on software and get out of the hardware environment so I can understand the brains behind the madness.

How do I get to understanding refresh rates and efficiency ratings, without understanding the application of software, is where I am headed. So far, based on your comments, we have an interrupt driven system that uses spi. where do we go from there? cant we build on that? I want to stay close to C programming because I don't quite get assembler.

I guess the projects would be (in this order)

- make scanning software that mux'es a 8x64 LED grid correctly - Still trying to get this right
- make some kind of "interrupt driven input" system to change said display - I need to school on this for sure
- specify hardware required - not a priority yet
- make changes based on the customized needs from different colored LED's. - irrelevant until I know what is correct in software.

Hope this clarifies things, and gets us on track!
Thanks man.
 
I'm not sure I can be of much help Keny. Sorry. But, I suspect there may be a few reasonably good designs with C that you might be able to study.

Good luck on your project and your studies.

Cheerful regards, Mike
 
Hardware is important when it comes to making led signs you have to no what pins need to sink and what is sourcing

I don't know any one that would tell you how to do this and not see the schematic
 
First you'll shift in the HC 595 the active LED's of row 0.
Deactivate RB6.
The next step is to activate OE/RCK to get the shift register information to the outputs.
Then you should switch RB0 active.

Now you can shift in the LED's of row 1.
Deactivate RB0.
Activate OE/RCK.
Then Activate RB1.

Now you can shift in the LED's of row 2.
Deactivate RB1.
Activate OE/RCK.
Then Activate RB2.
And so on until all rows are lighted.
 
Hey wkrug thanks for your input!

So this example of what I have now for the 595 is pretty straight forward. It sends it's first serial string then a second. The first one, LED 1 should be lit. In the second, LED 3 should be lit. As it runs it should alternate back and forth over the program at light speed and I shouldn't see any blinking (good) and somehow there isn't supposed to be bleed between the LED's.



Code:
/*

in this example, which is not anatomically correct, the 595's source current to the LED's directly. The MCU's positive output is hooked up to a 3904 tranny to sink the return to ground. 

RA0 = ; // serial in 595a data for shift register a
RA3 = ; // SCK all 595's clock for shift register
RA4 = ; // RCK all 595's (PWM, OE)clock for shift register display mode

RC1 = ; // sink current bus 1
RC2 = ; // sink current bus 2

*/

for (i = 1; i < 50; i++){


RB4 = 1; // SRCL shift register clear


RA0 = 0; // null

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 8

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 7

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 6

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 5

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 4

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 3

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 2

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 1; // bit 1

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RC2 = 0; //  sink current bus 2
		 // turn off previous iteration

RC1 = 1; //  sink current bus 1
		 // doesn't need to be on until led's are about to display

RA4 = 0; // RCK pulse the storage register clock LOW
RA4 = 1; // RCK

// begin second serial output process


RC1 = 0; // sink current bus 1
		 // maybe here maybe a little later?

RA0 = 0; // null

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 8

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 7

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 6

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 5

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 4

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 1; // bit 3

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 2

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;

RA0 = 0; // bit 1

	RA3 = 1; // SCK clock it
	RA0 = 0;
	RA3 = 0;


RC1 = 0; // sink current bus 1
		 // turn off previous iteration

RC2 = 1; //  sink current bus 2
		 // doesn't need to be on until led's are about to display

RA4 = 0; // RCK pulse the storage register clock LOW
RA4 = 1; // RCK

RC2 = 0; // sink current bus 2


}

The Goal here is to illuminate only two leds. There are 16 LED's in total, 2 buses of 8. The 595 controls the output for each of the 8 led's per bus.

Now, enter the issue I'd like to fix, I made a similar example graphic. see attachment LED Bleed.jpg

For some reason unbeknown to me, Other LED's in the arrangement are illuminating when they shouldn't. If I could fix that I'd be a lot further along.

I have also included pictures on my 2 channel scope readings for the outputs.

----

Aaaand secondly, I have a separate MCU clock configuration question. In building this project I have been working with the MCU's internal RC clock. In trying to see if something was up with my clocks speed, I switched from a PiC182450 to a PIC16684.

According to the datasheets, the two have different internal clock speeds:

PIC16 8 Mhz
PIC18 31.25Mhz

one would think The pic 18 would be faster but apparently, according to my scope this exact program is running significantly faster on the PIC16. So I am guessing something is wrong with my PIC18 config settings. For instance these scope readings are at 1ms on the PIC18 but to get the same scope readings on the PIC 16 I have to turn the time division up to 2µs.

here are my configuration words for the pic 16:
Code:
__CONFIG(FCMDIS & PWRTEN & WDTDIS & INTIO & MCLRDIS & IESODIS & BORDIS & UNPROTECT);
and for the pic 18
Code:
__CONFIG(1, INTIO & CPUDIV1);
__CONFIG(2, BORDIS & PWRTDIS & WDTDIS);
__CONFIG(3, LPT1DIS & MCLREN);
__CONFIG(4, XINSTDIS & STVRDIS & LVPDIS & DEBUGDIS); //& ICPORTDIS

What gives??
 

Attachments

  • LED bleed.jpg
    LED bleed.jpg
    91.9 KB · Views: 229
  • rc1rc2.jpg
    rc1rc2.jpg
    182.8 KB · Views: 193
  • rcksck.jpg
    rcksck.jpg
    220.4 KB · Views: 205
  • sckser.jpg
    sckser.jpg
    240.1 KB · Views: 194
  • 595outab.jpg
    595outab.jpg
    207.4 KB · Views: 212
Last edited:
A better algorithm

ok looks like I managed to get my 8x8 LCD array to work, problem is it isn't cycling through the program at an acceptable speed. Here's some better looking code, and I managed to solve my ambiguous LED's issue by utilizing output enable.

Code:
#include <htc.h>
#define MAIN_C

__CONFIG(1, IESODIS & FCMDIS & INTCLKO & CPUDIV1 & PLLDIV1);
__CONFIG(2, BORDIS & PWRTDIS & WDTDIS);
__CONFIG(3, LPT1DIS & MCLREN);
__CONFIG(4, XINSTDIS & STVRDIS & LVPDIS & DEBUGDIS); 

//Define pins 
#define DATA RA0 // serial data to 595 shift register
#define CLOCK RA3 // SCK to all 595's shift register clock
#define LATCH RA4 // RCK all 595's (PWM, OE)clock for shift register display mode
#define OUTEN RC0 // Output Enable: Enable 0 Disable 1;
#define SCLR RB4 // SCLR Shift Register Clear 0 Clear, 1 don't

#define RTN1 RC1 // sink current bus 1
#define RTN2 RC2 // sink current bus 2
#define RTN3 RC6 // sink current bus 3
#define RTN4 RC7 // sink current bus 4
#define RTN5 RB0 // sink current bus 5
#define RTN6 RB1 // sink current bus 6
#define RTN7 RB2 // sink current bus 7
#define RTN8 RB3 // sink current bus 8
#define HIGH 1
#define LOW 0

// Declare functions

void pulseClock ( void );
void pulseLatch ( void );
// void sendSerial ( void );


void pulseClock()
{
	CLOCK = HIGH; // SCK clock it
	CLOCK = LOW;
}

void pulseLatch()
{
	LATCH = LOW; // RCK pulse the storage register clock LOW
	LATCH = HIGH; // RCK
}

void sendSerial(int serial[])
{

	int i;

	for (i = 0; i <=8; i++){

		DATA = serial[i]; // bit 1
		pulseClock();
	}	


}

void main(void){
//	unsigned char eightBit;

	ADCON1 = 0x0F;			// Turn Off A/D's
	TRISA = 0b00000000; // Set PORTA to output
	TRISB = 0b00000000; // Set PORTB to output
	TRISC = 0b00000000; // Set PORTC to output
	PORTA = 0b00000000;	// Clear PORTA port
	PORTB = 0b00000000;	// Clear PORTB port
	PORTC = 0b00000000;	// Clear PORTB port

	SCLR = HIGH; // Set Shift Register clear High

	int serial[];

	while(1)
	{
    	int serial[] = {0,1,1,1,1,1,1,1,1}; // Null 8,7,6,5,4,3,2,1
		
		// row 1
		sendSerial(serial);
		RTN8 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN1 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 2
		sendSerial(serial);
		RTN1 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN2 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 3
		sendSerial(serial);
		RTN2 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN3 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 4
		sendSerial(serial);
		RTN3 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN4 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 5
		sendSerial(serial);
		RTN4 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN5 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 6
		sendSerial(serial);
		RTN5 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN6 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 7
		sendSerial(serial);
		RTN6 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN7 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

		// row 8
		sendSerial(serial);
		RTN7 = LOW; // sink current bus 2
		OUTEN = HIGH; // Output Enable lights off
		RTN8 = HIGH; //  sink current bus 1
		pulseLatch();
		OUTEN = LOW; // Output Enable lights on // stall(1);

	} // while
} // main

Am I in the ballpark? I am still wondering why my MCU cant roll through this fast enough. Once I get this right I need to expand the shift registers to 32 bits.
 
So I stole a crystal out of a USB hard drive controller and put it in the circuit, and changed the configuration word to use the external clock and apparently it is working the way I want it to, so now i'm in business. I'm sure I'll have more questions as I get rolling with interrupts but that seems to be looking like my next hurdle...
 
Status
Not open for further replies.

Latest threads

Back
Top