EngIP 31 Posted May 1, 2011 Share Posted May 1, 2011 Here's my current progress on an LED matrix display. I'm using 4 outputs to control 35 LED's, which was the point of the whole exercise. I've used 2 x 74HC595s, with the reset tied high and the Output Enabled tied low. I've tied the clocks together to reduce the number of outputs used, and used two pins for the data outputs to the shift registers. Mostly done with trial and error (I've since found the 74HC595 isn't suitable for driving multiple LED's - but it can cope with individual ones). The code is below, and not the greatest, but it works! I'm just using an 8x8 output to the shift registers, but I'm sure it could be optimised for 7x5. I'm going to add another shift register and make a little game of it later, but I'm happy with it for now. Any comments/criticism welcomed, but be gentle, it's my first MCU project. Actually, it's my first ever project. http://www.youtube.com/watch?v=RLsNdYr09qU #include unsigned char COL[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; unsigned char ROW[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; //Does this below need declaring seperately to when it is declared by the function below? int delayTime; void delay(int delayTime); //Serial function, adapted from wikipedia entry on bitbanging. void sendSerial(unsigned char dataGreen, unsigned char dataColumn); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Hold the WDT (WatchDog Timer) P1DIR = 0xFF; //Set Port 1 as outputs /* * p1.1 DS Serial data Row * p1.0 DS Serial data Column * p1.3 ST CP storage register clock input * P1.4 SH CP shift register clock */ while(1){ int x, y; unsigned char z=0x02; // for (x=1;x<8;x++){ for(y=1;y<6;y++){ sendSerial(z, COL[x]); z <<= 1; delay(10000); } z=0x02; } } } void delay(int delayTime){ int t1; for (t1=0;t1 t1=t1*1; } } //The following function is the code from the wikipedia entry on BitBanging, adapted for my specific application. void sendSerial(unsigned char dataGreen, unsigned char dataColumn) { int i; // send bits 7..0 for (i = 0; i < 8; i++) { // consider leftmost bit // set line low if bit is 1, High if bit is 0 if (dataGreen & 0x80){ P1OUT &= ~BIT1; } else{ P1OUT |= BIT1; } if (dataColumn & 0x80){ P1OUT |= BIT0; } else{ P1OUT &= ~BIT0; } delay(2); // pulse clock to indicate that bit value should be read P1OUT |= BIT4; delay(2); P1OUT ^= BIT4; // shift byte left so next bit will be leftmost dataGreen <<= 1; dataColumn <<= 1; } // Set storage register. P1OUT |= BIT3; delay(2); P1OUT &= ~BIT3; } bluehash 1 Quote Link to post Share on other sites
TopHatHacker 25 Posted May 1, 2011 Share Posted May 1, 2011 Hey looks good, I was thinking about picking up a few of these 5x7 matrix' .. they seem pretty cheap. kind of an odd size, but looks like some potential TopHatHacker Quote Link to post Share on other sites
EngIP 31 Posted May 2, 2011 Author Share Posted May 2, 2011 Yeah, I thought it's an oddball size, but I'd guess that 5x7 is used as it's good proportions for characters/numbers. The one above is a red/green one, so I'm going to have to do something with an extra 595 (or appropriate shift register) to be able to control all 70 LED's with 5 outputs. Quote Link to post Share on other sites
Mac 67 Posted May 2, 2011 Share Posted May 2, 2011 Which came first, the 5x7 font or the 5x7 display (grin)? These 5x7 modules work out very well with my MacMux Quote Link to post Share on other sites
nexusone1984 32 Posted May 3, 2011 Share Posted May 3, 2011 I connect the 74HC595 with three pins from the MSP430 Launchpad to drive up to 8 seven segment LED displays. You only have a problem driving the LED's is if you turn on all of them at one time, I turn on each LED one row at a time. But I do it 100's of times a second, so you don't see them blink. But at the same time you don't draw more current then the IC can handle. My next project is using some 5X7 LED's I have laying around. Here is how I have connected the 74HC595 to my MSP430. See attachment temp-led595.pdf Quote Link to post Share on other sites
EngIP 31 Posted May 3, 2011 Author Share Posted May 3, 2011 Thanks for that Nexus, looks very similar to how I've wired my set-up, but I hadn't thought of using the serial out (of the 595) to feed a second register - using that method, you could operate many outputs from just 3 pins (rather than my method of sending serial data to each 595 from it's own pin). Regarding my inability to achieve sufficient brightness using the 595's - I have tried to strobe the LED's to take advantage of POV, but the brightness just isn't there. It's probably down to the fact that my LED matrix is CA, so I'm trying to source far too much current from the 595 - I think it would be much more capable if I were using a CC display. I'm going to have a play with the timing, and see if I can make it work any better, but my results so far (just using alternate program cycles to alternate two LED's brings a noticeable drop in brightness) suggest I'm using the wrong tool for the job. Quote Link to post Share on other sites
Mac 67 Posted May 4, 2011 Share Posted May 4, 2011 EngIP, I'd like to apologize for forgetting to say congrats' on your first MSP430 project. You did a great job and it looks like it could be a good building block for bigger displays. Regarding my inability to achieve sufficient brightness using the 595's - I have tried to strobe the LED's to take advantage of POV, but the brightness just isn't there. It's probably down to the fact that my LED matrix is CA, so I'm trying to source far too much current from the 595 - I think it would be much more capable if I were using a CC display. May I ask why you think switching from common anode to common cathode displays might improve brightness? Wouldn't that still leave you with one '595 sourcing current and one '595 sinking current to the display? Also, could you be more precise about the type of 5x7 displays you have? It would probably be more meaningful to describe them as "anode row" or "cathode row", depending of course on their orientation, 5 rows & 7 columns or 7 rows & 5 columns. Cheerful regards, Mike Quote Link to post Share on other sites
EngIP 31 Posted May 4, 2011 Author Share Posted May 4, 2011 EngIP, I'd like to apologize for forgetting to say congrats' on your first MSP430 project. You did a great job and it looks like it could be a good building block for bigger displays. May I ask why you think switching from common anode to common cathode displays might improve brightness? Wouldn't that still leave you with one '595 sourcing current and one '595 sinking current to the display? Cheerful regards, Mike Thanks Mike, it's amazing the feeling of accomplishment you get when you figure something out yourself, no matter how simple it may be to others. I've wanted to do a matrix project for a while, as I "invented" the idea of sequentially illuminating row by row in order to create an image, before discovering it's been thought of (long) before . You'll have to forgive my ignorance when it comes to electronics, my knowledge is very hotch-potch, and my MCU knowledge starts and ends with the launchpad I purchased about a month ago. Hopefully that will improve as a module of my degree next year is embedded systems. The 5x7 displays are common anode on the 7 rows. Regarding the CA/CC, my thinking was that should I try to illuminate 3 x LED's simultaneously, I would have the anode 595 trying to source enough current for 3x LED's (on one pin) whilst the cathode 595 would be sinking 3x LED's on individual pins. I'm assuming the 595's can sink much more current than they can source, so in the reverse of the previous example, the cathode 595 would be sinking 3x LED's from one pin, rather than sourcing. My assumption is that a 595 (or any IC as a rule of thumb) will be able to sink more current than it can source. Of course, illuminating LED's individually would mean CC/CA is irrelevant, as you have rightly said, the current is always being sourced/sink by a 595. The brightness drops when using this method still, but I think this is down to the speed of my code/the MCU. I've made a little progress with the matrix, so I'll post up later how far I've got (and the source code), and hopefully I can get some pointers on how to improve it. Edit: Just wanted to add, having re-read what I previously posted, I can see that I wasn't clear - sorry for any confusion. :oops: Quote Link to post Share on other sites
Mac 67 Posted May 4, 2011 Share Posted May 4, 2011 Thanks for the additional info'. It seemed from your video and program that you were only lighting one LED at a time. And the delays seem long enough to give you an idea of the brightness you could expect when lighting an LED continuously through two '595 outputs. So, what then could be the reason for the low brightness? With my school schedule (two spring semester classes) I haven't really had a chance to play with my LaunchPad and with LED displays so I can only guess. Are you running the '595s from the 3.6v source on the LaunchPad? Could the combined voltage drops of two '595 outputs be limiting the voltage and current to the LED? Are the displays of the "super bright" type which in my experience seem to throw off a lot of light even with very low (3-5 ma) current? Some experiments might be in order. Try lighting one of the LEDs by sourcing it from a '595 output with the other end of the LED grounded, then try it the other way (sinking from '595 with opposite end of LED to Vcc). If you're going to light multiple LEDs in columns or rows, depending on how you end up driving the matrix, you really should consider column or row driver transistors, or their serial-to-parallel IC counterparts. Good luck in your classes. This semester only started Monday and I'm already swamped (grin). Regards, Mike Quote Link to post Share on other sites
SugarAddict 227 Posted May 5, 2011 Share Posted May 5, 2011 With the project I'm working on now that uses 8x8 matrices, I've found that doing 1 led at a time does the best job for me... There is another way to source/sink if you don't mind adding some transisters/resistors to your circuit. viewtopic.php?f=9&t=683 This way you can source/sink with whatever you want, with the correct resistor values for the brightness you want. Removes the 595 bottleneck. Quote Link to post Share on other sites
EngIP 31 Posted May 6, 2011 Author Share Posted May 6, 2011 Hi Mike, I'm going to put my hands up and say I've not been very clear about what's going on with this. The video I posted shows my first success at multiplexing, which was indeed lighting up individual LED's one by one. I then moved on to characters and such, which is where the brightness issue comes to the fore. I've pretty much figured it out now, with a bit of experimentation (and pointers from yourself and others) - the 595's are limiting current, but the refresh rate is the culprit when addressing individual LED's. Unfortunately, setting it to run at 16MHz is beyond my capabilities at the moment, so unless someone puts together an idiots guide, I'll just have to wait until I can set some time aside to dedicate myself to the task (like you, I'm currently swamped!). SugarAddict - That's a nice PCB you've manufactured there! I've had a quick read through and noticed you've upped the MCU to 16MHz, which is something I think I'm going to have to do. I'm only doing this for the learning aspect, and If I were doing it for a finished project, I think dedicated driver IC's / transistors would definitely be used. Now, on to my problems/questions. Any help or advice would be greatly appreciated. And Mods/Admin, sorry if this isn't the right place, but I didn't think it would be any more appropriate on a different board. Question 1 - Why is addressing individual LED's faster? I decided to write a little code to compare the brightness of addressing individual LED's Vs. addressing rows. Let's say I wanted to light Row 1:Column 1 and Row1:Column 2 for simplicity. The individual method would send 0x01 followed by 0x02 over and over (two instructions). The row method would send 0x03 over and over (one instruction). I put both methods in individual for loops (same number of iterations) and noticed the row method took longer to execute, despite there being significantly less instructions in the for loop. I can't understand how this can be, as they both use the same bitbanging function, but one uses it twice as much per cycle of the for loop, yet executes all cycles quicker than the short code. Question 2 - Surely the following code doesn't exceed the limit for a G2231? EDIT (edited then got a reply) - Simplified, my code is as follows, the error I get is run out of RAM. #include //unsigned char PH[x] = {14, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; void main(void){ //Code goes here ~80 lines or so } Many thanks for any help, and thank you for the replies so far Quote Link to post Share on other sites
zeke 693 Posted May 6, 2011 Share Posted May 6, 2011 What does the compiler say when you comment out the delays instead? Are the values in your array changing or are they constant? If constant I think you can modify their declaration to get the compiler to stuff them into Flash memory rather than RAM. Someone help me out here. Is it const or static? The code might look like this: unsigned char const PH[14] = {14,5,4,3,5,2,5,2,5,4,3,5,5,5}; Oh, what are the compiler error messages? Are you out of RAM or FLASH? Quote Link to post Share on other sites
EngIP 31 Posted May 6, 2011 Author Share Posted May 6, 2011 Thanks Zeke, I got rid of the delay function as a function as it was only called once. The values in the array are constant, and I was thinking along the lines them being written to the wrong place. The error message was out of RAM. I've pretty much decimated the code now, but I'll rebuild it all tomorrow and will look into this const/static declaration. If someone could point me to some literature that covers this (I don't know if it's C specific or TI/MSP specific) that would be great. Many thanks again, Guy Quote Link to post Share on other sites
SugarAddict 227 Posted May 6, 2011 Share Posted May 6, 2011 I have the same problem if I use more than 1 led on a display. I attempted to use a refresh rate of 8 and the leds would be different brightnesses all over the place... Questions I would ask is... What happens when you add a second LED to a sourcing 74HC595? How about a second led to a sinking 74HC595? (One try with same source for both, second try with different sources) Are these LEDs in parallel or series? I found the simplest solution was to do them one at a time. The option to remove the 595 limitation on the board I linked you was something I haven't explored, but it may fix the issue to some degree, as you could source enough to cover more leds perhaps.. Quote Link to post Share on other sites
EngIP 31 Posted May 7, 2011 Author Share Posted May 7, 2011 Update, it's now doing something a little bit more useful than chasing an LED 8-) http://www.youtube.com/watch?v=WZNMLf6zzEU Here's my code. #include const unsigned char COL[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; const unsigned char ROW[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; //Letter format //make first char in array = the length of the array, //PV[n]= the nth LED in the sequence for that letter. //PV = letter 'P' 'V'ertical const unsigned char PH[14] = {13, 5, 4, 3, 5, 2, 5, 2, 5, 4, 3, 5, 5, 5}; const unsigned char PV[14] = {13, 1, 1, 1, 2,2,3,3,4,4,4,5,6,7}; const unsigned char AH[19] = {18, 4,3,2,5,1,5,1,5,4,3,2,1,5,1,5,1,5,1}; const unsigned char AV[19] = {18, 1,1,1,2,2,3,3,4,4,4,4,4,5,5,6,6,7,7}; const unsigned char MH[19] = {18, 5,1,5,4,2,1,5,3,1,5,3,1,5,1,5,1,5,1}; const unsigned char MV[19] = {18, 1,1,2,2,2,2,3,3,3,4,4,4,5,5,6,6,7,7}; const unsigned char SH[16] = {15, 4,3,2,5,1,5,4,3,2,1,5,1,4,3,2}; const unsigned char SV[16] = {15, 1,1,1,2,2,3,4,4,4,5,6,6,7,7,7}; const unsigned char FourH[14] = {13, 5,5,5,3,5,3,5,4,3,2,1,3,3}; const unsigned char FourV[14] = {13, 1,2,3,3,4,4,5,5,5,5,5,6,7}; const unsigned char ThreeH[16] = {15, 5,4,3,2,1,1,2,3,4,1,1,4,3,2,5}; const unsigned char ThreeV[16] = {15, 1,1,1,1,2,3,4,4,4,5,6,7,7,7,7}; const unsigned char ZeroH[17] = {16, 4,3,2,5,1,5,1,5,1,5,1,5,1,4,3,2}; const unsigned char ZeroV[17] = {16, 1,1,1,2,2,3,3,4,4,5,5,6,6,7,7,7}; //Serial function, adapted from wikipedia entry on bitbanging. void sendSerial(unsigned char dataGreen, unsigned char dataColumn, unsigned char dataRed); void delay(unsigned int delayTime); void main(void) { WDTCTL = WDTPW + WDTHOLD; // Hold the WDT (WatchDog Timer) P1DIR = 0xFF; //Set Port 1 as outputs /* * p1.1 DS Serial data Red Row * p1.0 DS Serial data Column * p1.5 DS Serial data Green Row * p1.3 ST CP storage register clock input * P1.4 SH CP shift register clock */ while(1){ int x,y; int loops; loops = 2000/MV[0]; for(y=0;y for (x=(MV[0]);x>0;x--){ sendSerial(0, COL[MV[x]],ROW[MH[x]]); } } loops = 2000/SV[0]; for(y=0;y for (x=(SV[0]);x>0;x--){ sendSerial(ROW[sH[x]], COL[sV[x]],0); } } loops = 2000/PV[0]; for(y=0;y for (x=(PV[0]);x>0;x--){ sendSerial(ROW[PH[x]], COL[PV[x]], ROW[PH[x]]); } } loops = 2000/FourV[0]; for(y=0;y for (x=(FourV[0]);x>0;x--){ sendSerial(ROW[FourH[x]], COL[FourV[x]],0); } } loops = 2000/ThreeV[0]; for(y=0;y for (x=(ThreeV[0]);x>0;x--){ sendSerial(0, COL[ThreeV[x]],ROW[ThreeH[x]]); } } loops = 2000/ZeroV[0]; for(y=0;y for (x=(ZeroV[0]);x>0;x--){ sendSerial(ROW[ZeroH[x]], COL[ZeroV[x]], ROW[ZeroH[x]]); } } } } void delay(unsigned int delayTime){ int t1; for (t1=0;t1 t1=t1*1; } } void sendSerial(unsigned char dataGreen, unsigned char dataColumn, unsigned char dataRed) { int i; // send bits 7..0 for (i = 0; i < 8; i++) { // consider leftmost bit // set P1.5 (Green cathode) low if bit is 1, High if bit is 0 // set P1.1 (Red cathode) low if bit is 1, High if bit is 0 // set P1.0 (Data column) low if bit is 1, High if bit is 0 if (dataGreen & 0x80){ P1OUT &= ~BIT5; } else{ P1OUT |= BIT5; } if (dataRed & 0x80){ P1OUT &= ~BIT1; } else{ P1OUT |= BIT1; } if (dataColumn & 0x80){ P1OUT |= BIT0; } else{ P1OUT &= ~BIT0; } //Send Clk signal high to all shift registers. P1OUT |= BIT4; //Then set it low again. P1OUT ^= BIT4; //Shift all the data and cycle through 8 times. dataGreen <<= 1; dataColumn <<= 1; dataRed <<=1; } // Set storage register to update outputs of shift registers. P1OUT |= BIT3; P1OUT &= ~BIT3; } bluehash and gwdeveloper 2 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.