5x7 LED matrix driver for variable width fonts - Page 1
Forum section: electronics / projects

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 12:29:21 pm
content: I've become somewhat obsessed lately with wanting to build something using bicolor (red/green) 5x7 LED matrices - but here's the twist: I'd like to be able to use avariable widthfont. That is, some characters would only be 3 pixels wide (e.g. I 1 ! etc), most would be 4 pixels, and a few 5 pixels wide (e.g. W M Q etc). Something like this:This rules out any driver using a built in font, as all I've seen use a fixed width 5x7 font (e.g.MAX6952). Also, using a 5x7 font on 5x7 modules would require physically spacing the modules, which I really don't want to do. Rather, the display (12 modules wide) should be treated as a 7x60 graphical matrix, with pixel data generated on the controller (an Atmel MCU). I know this is a fairly CPU intensive task, but I'm thinking with only 420 pixels it shouldn't be too bad - I would only need 2 bits per pixel for bi-color, or 840 bits in total, as brightness can be global. But in order to proceed to the next stage I need to pick a driver, and it's a jungle out there! So I'm hoping there may be someone here on the forum who has experience of working with this type of display, and can point me in the right direction?

author: Ian.M
author_rank: Super Contributor
timestamp: August 30, 2018, 01:46:53 pm
content: If you don't mind doing the matrix multiplexing in a timer interrupt on your MCU, TPIC6C595 as the column driver - its a low-side PowerMOS 8 bit shift register that can be daisy-chained and easily controlled by any MCU SPI port, with a current limiting resistor for each column, and seven beefy low Vgs threshold P-MOSFETS as high side row drivers, controlled either direct from your MCU if you've got plenty of I/O pins or via a 74HC138 3 to 8 line decoder, or if you are *REALLY* pin-bound, via a 74HC595 on the SPI bus which only needs one extra I/O pin to strobe it. Control global brightness by adding dead time with all row drivers off to the multiplexing and reducing each row driver's on time to maintain the same frame-rate.Done right, you should be able to present the display to your main program as a 105 byte memory mapped buffer, row oriented and two bits per pixel, that updates the display automatically when you change it (via the multiplexing ISR). If you've got enough RAM, make the display buffer pointer reload location for the SPI output in the ISR a variable, and you can then have multiple display buffers and swap between them on the fly, with the change happening at the start of the next frame.

author: Benta
author_rank: Super Contributor
timestamp: August 30, 2018, 02:23:53 pm
content: If the complete display is bicolor, all the drivers (both column and row) need to have bipolar outputs. 74ACxxx logic comes to mind, they can provide quite a bit of current both high and low.

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 02:50:14 pm
content: Thanks guys, interesting tips, though I have to admit a fair amount is a little beyond me, for exampleQuote from: Ian.M on August 30, 2018, 01:46:53 pmI hoped the LED driver itself would act as frame buffer, and that I'd only need to feed it a new 105 byte chunk when the displayed data is to be changed? Since posting, I've looked a bit further, and found theRohm BD26503GUL:

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 03:00:49 pm
content: There's also theISSI IS31FL3733

author: Ian.M
author_rank: Super Contributor
timestamp: August 30, 2018, 03:04:14 pm
content: @Benta,Surely it will either have separate anodes, or separate cathodes for red and green? If the colours are antiparallel, you wouldn't be able to multiplex it, you'd have to charliplex each individual matrix!My suggestion above is on the basis that its got common anode rows and separate R and G columms. If its got separate R and G common row anodes you need half as many TPIC6C595 column drivers, twice as many row MOSFETs, a pair of 74HC138 decoders and an extra I/O pin to drive them.If its got common cathode rows, you connect them to the TPIC6C595 chain and the columns to the MOSFETS, and instead of multiplexing a row at a time, you multiplex 1 of N columns simultaneously across the whole display, If R and G have separate cathodes sharing the anode for each column, N is 5, otherwise N is 10. Both of these arrangements scramble the display memory layout, though the latter column oriented layout is actually more convenient for writing variable width fonts to the display.@Lomax,BD26503GUL *sounds* nice, but how the <beep> are you going to assemble that tiny CSP 0.5mm pitch BGA? Also their matrix dimensions aren't a good match to the width of your modules, so you'll waste a lot of column drives that just cant be used without leaving dead columns in the display.

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 03:24:08 pm
content: Quote from: Ian.M on August 30, 2018, 03:04:14 pmGood point on the packaging - no way I could make use of that. The ISSI IS31FL3733 comes in a more user friendly TQFP-48 package, which I could probably cope with.Edit:The LED modules I'm interested in come in common cathode row configuration:The datasheet says they're also available in common anode row configuration, without giving a model #, so that's probably a "special order" jobbie.

author: Buriedcode
author_rank: Super Contributor
timestamp: August 30, 2018, 03:38:16 pm
content: Whilst there isn't any official standard, I would call those "tricolour" - because both LED dies can be on at the same time (often they are multiplexed though). I (wrongly) assumed by "bicolour" you meant back to back diodes which save on connections but make driving slightly more complicated. The two terms are often used interchangeably and can create confusion.With that image you provided you're essentially just driving double the number of LED's which just means adding more SPI driversAfter reading Ian.M's reply - I have nothing to add as that pretty much covers it all!

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 03:46:48 pm
content: How about... using 14 pins on the MCU, to drive a single column, and scan that across the display at a high enough rate that persistence of vision makes it look steady (say 120Hz x 60 columns = 7.2kHz)? Or is that too simplistic?Edit:Quote from: Buriedcode on August 30, 2018, 03:38:16 pmAgreed, it's a mess - I was thinking of calling them "tri-colour" in my original post, but that too sounded confusing, many would probably assume I was talking about RGB diodes. I have no interest in blue colour LEDs; in fact I'm well fed up with them. Nor am I after any mix of colours other thanyellow. One problem with the approach I suggested above would be that any yellow pixels would be brighter than the others?For the sake of this discussion, I'm looking atthe ATTiny4313 MCU. Up to 18 I/O pins (I need a few for the UART though), 4 PWMs, 2 timers (one 16-bit). Cheap as chips. In fact, at just £0.80, probablycheaperthan chips, if we're talking about the edible type.Edit 2:To save on I/O pins, and since I would never need to have different colours within the same column, I could use 7 pins to control on/off, and a further two to say whether it should be green, red or yellow. Clumsy?Edit 3:Another example...

author: Ian.M
author_rank: Super Contributor
timestamp: August 30, 2018, 04:20:45 pm
content: Not practical for wide displays under normal illumination. With such a low duty cycle the peak LED current to get adequate brightness becomes unreasonably high and even if your drivers can handle it, the LED dies and/or bond wires cant take it.However if you have a separate TPIC6C595 for the rows of each individual matrix, and parallel matching columns of all the matrixes to the P-MOSFET high side drivers previously described, you get what I described in my third paragraph to Benta in reply#5, and with only a 1/10 duty cycle so if you can pulse the LEDs at 100mA, you get 10mA average current. With a little trickery with the pointer increments in the SPI output loop, you can get the display buffer mapping to be purely sequential left to right, one byte per column per colour, either byte interleaved RG (the most convenient if your fonts store colour) or seperate bit-planes for R and G which is bettir if you are colouring the characters as you draw them. If the latter, you'd better double buffer if you want to be able to scroll yellow text without getting an annoying R/G strobe effect. Unfortunately, this solution wastes one bit per byte of display RAM as there are only seven rows.I think the ATtiny4313 is a bit *too* limited. Its only got 128 bytes of RAM so it isn't practical to fit a 120 byte bitmapped display buffer in there, and the code to do character to bitmap conversion 'on the fly' would be quit a bit more complex. If you plan to make 100000 of these it might make sense to shoe-horn it into that chip in hand-crufted assembler, but for a one-off it makes more sense to throw an ATmega328P at it with plenty of RAM for two display buffers and ROM for lots of fonts without having to scale them on the fly, and keep the code conceptually simple. Prototype it on an Arduino then move the MCU to your own board when its ready.

author: Cody Turner OKC
author_rank: Contributor
timestamp: August 30, 2018, 04:29:41 pm
content: Hi Lomax, If you look at the AMS website, it has like 20 or more LED matrix and keypad drivers controllers etc, some even have demo firmware, They also allow you to sample up to 5 pieces of 3 diffrent parts 3 times a month I have used the for LED drivers, magnets, megnetic encoders, lux sensor rgb sensors, etc you might want to check out the site. its very easy to navigatehttps://ams.com/led-drivers

author: Benta
author_rank: Super Contributor
timestamp: August 30, 2018, 04:30:10 pm
content: Quote from: Ian.M on August 30, 2018, 03:04:14 pmI agree, but this wasn't clear in the OP. Bidirectional LEDs can indeed be multiplexed, but the drive circuit is rather complex.

author: ebclr
author_rank: Super Contributor
timestamp: August 30, 2018, 04:53:59 pm
content: In Fact, isn't that hard just add an ending char on the font definition, and just skip to next character when end is found in the Led definition table

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 06:50:51 pm
content: Working on a more detailed reply, but just wanted to say thanks to everyone who's contributed - lots for me to digest!Also to clarify my aims: with the abundant availability of cheap full colour LCDs, OLEDs, "NeoPixels", and all manner of whizz-bang displayery, in every shape and size, often with built in drivers, it's more than a little nuts to want to use something as dumb as LED matrices. I'm interested in them only forstupidreasons: I like the retro look, I'm attracted by the minimalism of the approach, and the challenge of "making them go" is an interesting one. Thereisa practical real-world application somewhere further down the line, but as I'm still struggling to grasp the basics that application appears to be much, much, further away than I had hoped!

author: Buriedcode
author_rank: Super Contributor
timestamp: August 30, 2018, 08:30:38 pm
content: Quote from: Lomax on August 30, 2018, 06:50:51 pmMe too! We really are spoiled these days with extremely high contrast, full colour displays that cost next to nothing. But I still find using tricolour bargraphs, POV displays and even monochrome STN LCD make for excellent UIs in my projects. There is also the challenge - be it in terms of hardware design, or more likely firmware of making the most with what you have rather than just importing libraries. Again this is for my own little projects, for actual work there's a reason why these have been superseded in many areas.

author: Ian.M
author_rank: Super Contributor
timestamp: August 30, 2018, 09:23:09 pm
content: The 'retro' approach for LED scrolling message boards and annunciators was the TPIC6C595 and P-MOSFETs I described. Before that it was a chain of TTL shift registers and separate ULN2003 open collector Darlington arrays, with discrete LEDs pressed into plastic array mounts usually organised as vertical strips so you only had to align a limited number of pins to replace one*with BJTs for the row drivers The separate controller board usually had the row drivers with IIRC some sort of usually 8051 based MCU, with a battery backed RAM for the message memory and usually an external EPROM, all 8 bit parallel. There was typically either a serial/wired controller port for programming either with a controller or PC, or an IR receiver and an IR remote for programming.Usual faults were burnt power in sockets, bridge rectifiers and regulators, and a sprinkling of dead LEDs in the matrix. Rarely you got one that was locked up with a row out or mostly stuck on, which was a real PITA caused by something wrong round the MCU, as if the multiplexing stalled, it was possible for it to burn out the row driver and a random selection of any LEDs in the affected row that crossed with columns that were active, and depending on how long it took to be discovered and how much futzing around the user had tried before sending it in for service, that could be most of the LEDs on the affected row, with the occasional ULN2007 burnup if one of the affected LEDs failed short, and the ULN2007 was already running hot from displaying inverse characters.I've repaired enough of them in my time, to the point that I didn't keep any bits except rectifiers and regulators when I got out of that gain as I never wanted to see another one darkening my bench! I did code my own on a MPF-1P Z80 board to drive the display panel of a dead sign via the Z80 PIO on the MPF-I/O board, semi-bitbanging the SPI interface using bit 0 of the port, bits 1-7 not connected but reserved and OUTI with hardware strobe, and rotating the bytes in the RAM buffer so on the next pass the next row's data was aligned with bit 0, which made the principal of the college I was taking a further education course at rather happy as his microcomputer module had something better to show for the open day than the usual assigned project: a minimal LED crossroads traffic light + pelican crossing. It was a rush job as the principal had flipped his lid about 10 days before the open day, and asked me as the class's resident guru if I could od anything with the dead message display he had. It took about half a day to figure out its controller was a dodo, and come up with a plan to hook it to one of the class Z80 boards, then a week of evenings and lunchtimes culminating in a coding marathon to develop a no frills 'Enter your text and scroll it' program. IIRC I edited the code at home on a Sinclair QL, transferred it by serial port to a ZX Spectrum to assemble and debug it then bit-banged the MPF-1P tape format because it was far far easier than dealing with entering it on the MPF-1P's chiclet keyboard and single line 16 character VFD display.IMHO if you just connect a bunch of LED matrix controllers to a serial bus, you are missing the whole experience, so you should do it 'retro' by about 30 years except with a modern MCU. Use one with enough RAM and MIPs abd a reasonably fast SPI module, and you can even do individual pixel dimming with no extra hardware usingBCM(aka bit angle modulation, which is much more computationally efficient than software PWM).* We never did, as if you warmed it up to soften the plastic mount by running it with as many LEDs on as possible the mount or used a hot air gun, you could pop the single strip mount off leaving the LEDs in the board, desolder the dead LED, press a replacement out of a spare strip and press it into the removed mount, then you'd only have two leads to wiggle into the holes before you could press the mount back into place, make sure its flush and solder the new LED. Some experimenting with spare LEDs held in place without soldering was usually required to get a good colour and brightness match.

author: Lomax
author_rank: Frequent Contributor
timestamp: August 30, 2018, 11:03:31 pm
content: Quote from: Ian.M on August 30, 2018, 09:23:09 pmThanks for the backstory - and yes, I agree; I'd rather use registers and build it "low tech". More fun that way, and besides, I tried reading the datasheets forsome of the more integrated chips, and they're reallyquiteadvanced. Not that I couldn't wrap my head around how to configure them, given enough time - I just have better things to do! Also, the display I'm after is relatively basic; No individual pixel (or even character) dimming needed, no scrolling or animation, only three fixed colours per pixel (2 bits), and never more than one colour per column.I've spent the evening studying a few designs others have come up with - mainly for single colour 8x8 matrixes, but then it's the basic principle I'm trying to grasp, which should be largely the same only doubled. IthinkI'm beginning to understand. One design I saw used an 8-output ring counter to iterate the rows with a clock pulse, and many seem to like MAX7219 for the columns. I think I've found a source for common anode row 8x8 matrices which have the same height as the 5x7s I had been looking at (important); conceptually these seem easier for me to work with*, as I wouldn't need to split the display horizontally for multiplexing, only the eight rows (for a 1/8 duty cycle), and could then use two MAX7219 for the columns on each module (one red, one green). Does that make sense?Also, from earlier:Quote from: Ian.M on August 30, 2018, 04:20:45 pmGood point(s). Iknewthat sounded too easy.Quote from: Ian.M on August 30, 2018, 04:20:45 pmStill struggling to understand most of this!Quote from: Ian.M on August 30, 2018, 04:20:45 pmOh. I thought it had 256 bytes of (S)RAM and 4k flash? I do have some other code to go on there, which although it doesn't use a lot of RAM does occupy ~1.5kb of flash, so I'm probably pushing the 4k limit anyway. But since the "column by column scan" scheme I proposed isn't viable, pin usage will be fairly low - I count six; I'd need four for the SPI bus, and hope to get away with clocking a counter for the rows from a single pin and one reset - perhaps the ATtiny841 (512b SRAM, 8kb flash) would do? I do like those ATTinys for some reason!*phew* Mammoth post over. Thank you for making it this far!*) There's also something poetic about having 64 LEDs per colour per row, with eight rows for a total of 1024 LEDs; precisely 1 kibibyte. Just a nice number

author: Ian.M
author_rank: Super Contributor
timestamp: August 31, 2018, 01:17:24 am
content: I really don't see the attraction of the MAX7219 for this. Yes a single one can drive an 8x8 mono matrix, but your 5x7 RG matrix is actually 10x7 when you consider individual diodes and the 8x8 RG matrix is either 16x8 or 8x16, so there's no way for a MAX7219 to sensibly drive one as you cant sync their internal multiplexing between chips. What you need is a fast dumb cheap SPI individual LED driver with analog current control not PWM, so you can multiplex the commons yourself. As the TPIC6C595 can be clocked at 5MHz loading a byte in only 1.6us, and can maintain its previous ootput untill all in the chain have got their data and then update simultaniously, and is only around £1 each, its hard to beat even though it needs eight external resistors to set the LED current.Simultaneous multiplexing of the columns in each matrix unit is probably the way to go. It keeps the display buffer better organised for variable width fonts as if the display is multiplexed by columns rather than rows,you don't have to do any barrel shifting and masking to align font data bytes with the byte boundaries in each row.Post a link to the datasheet for your proposed 8x8 matrix and I'll come up with a minimum hardware driving and multiplexing strategy for you.N.B. if the multiplexing stops while you are pulsing say 100mA into the LEDs to get enough brigtness you *will* blow LEDs, so for the sake of your wallet, don't do that during development. One approach if using individual low side resistors to set the LED currents is to reduce the supply voltage to the high side MOSFETs low enough to get the LED currents below the ab.s max continuous rating. This may not be practical if there is too much difference beween R and G Vf voltages. Another is to low pass filter signals tapped from all the multiplexing lines and use a diode network to feed the one with the highest duty cylle into a comparitor. If it goes over about 25% something's wrong and the display can be blanked by gating all the TPIC6C595 chips outputs off via their G (output enable) pins, or PWMing G with a 555 at many times the multiplexing frequency to dim the display so you can see the lit LEDs for fault diagnosis. Such a protection circuit may be disconnected once the firmware is 100% debugged and finalised.I checked the datasheet for the ATtiny4313 but I might have accidentally skipped a row or looked at the wrong table and given you the RAM from the ATtiny2313. Its tight even if you have 256 bytes, especially if you are going 8x8 x8. Half the RAM for one 2 bits/pixel display buffer means you've got absolutely no option but to stick to the basics you proposed, except for the one colour per column restriction. It would be considerably more complex (but not impossible) to unpack a two bit colour selector per column to colourise a mono display buffer on the fly as its output. That would reduce each column to 10 bits, with a 64 byte mono bitmap and 16 bytes of vertically striped colour attributes, saving 48 bytes, but a chunk of that would be used as variables for the extra processing required. OTOH it would lend itself well to a four pass per column multiplexing system to support varying the global relative brightnesses of R G and Y.

author: Lomax
author_rank: Frequent Contributor
timestamp: August 31, 2018, 08:19:11 am
content: Quote from: Ian.M on August 31, 2018, 01:17:24 amThanks Ian, will take some time to digest all that, though I hear you on the TPIC6C595. I will be back with a longer answer later, but just wanted to provide the LED matrix datasheet:http://betlux.com/product/led_dot_matrix/BL-M07A881xx.PDFUnsure whether "Super Red" (AlGaInP, 660nm, 200mcd) + "Green" (GaP/GaP, 570nm, 195mcd) or "Ultra Red" (AlGaInP, 660nm, 320mcd) + "Ultra Green" (AlGaInP, 574nm, 250mcd) will provide the better yellow when mixing? Tried finding an online comparison of different LED phosphors (with pictures) but failed. Also unsure whether black or grey background will look better behind the dark grey acrylic I plan to cover the display with. On one hand the grey is more similar to the (unlit) diffused lenses, so should result in a more uniform appearance - on the other it may lead to more light scattering behind the acrylic and lower contrast...

author: Ian.M
author_rank: Super Contributor
timestamp: August 31, 2018, 11:26:13 am
content: Quote from: Lomax on August 31, 2018, 08:19:11 amI don't think you can answer that without sampling them. Its certainly going to be easier than futzing around with a calibrated light source, two prisms and a bunch of lenses and filters on an optics bench to match the spectrum.I'd also look at BL-M07A881EG-XX, "Orange" (GaAsP/GaP, 635nm, 190mcd) + "Green" (GaP/GaP, 570nm, 195mcd) as, if you can stand the orange rather than red, its a lot more likely to give a nice yellow. Personally I'd sample it and your 'Ultra' contender in the black face variant and the other one in grey face. Any that don't make the cut can be used in early development at the burning LEDs stage.<Using basic primary colour names for brevity from here on>The A (column anode) matrixes would be well suited to (approximate) 1/16 multiplexing by column position within each matrix driving them all simultaneously with different row data with a string of TPIC6C595 chips or better the TPIC6B595 - same chip, but a continuous current rating of 150mA per output instead of 100mA to better match the matrix's peak pulse If current rating. As the current will be set by the row resistors of each individual matrix, it will be in a fixed ratio for red and green determined by the supply voltage minus their respective Vf so you'll need to trim the intensities of Red and Green by varying their relative duty cycle while maintaining the same total on time per column. If you want independent yellow brightness and colour balance control, that can be achieved by outputting a second string of row data during each colour's on time, sending R&~G during the red on time to reduce its contribution to the yellow by the time remaining till the next anode change, and G&~R during green to similarly reduce it.The result will be the ability to independently dial in red, gren and yellow intensities and select the yellow's red/green colour balance without the need for complex hardware.Its going to be somewhat of a brute for supply current. Pushing it to the limits with all LEDs on with both R and G at max brightness and no compensation for the resulting combined yellow, each column draws a bit under#150mA x8 during its ON time That's 1.2A per matrix for a hefty 9.6A total at a voltage TBD by pulse testing. A buck converter from a higher voltage is definitely called for. Let's suppose it ends up needing 5V. Bucking from 12V at 85% efficiency would halve that to 4.8A in - still a PITA but not so bad. Bucking from 19V gets it down to a reasonable 3A in, which is easy and cheap to provide from a second hand laptop supply. The *AVERAGE* current in normal operation with non inverted text is going to be far under that 9.6A, but depending on how close to the 150mA Ab.s Max. pulse If limit you *NEED* to push it to to get the required brightness, the peak current during multiplexing would still be nearly that high@. (Pathological case with normal text, a string of all letter 'H' on 8x8 matrix.) If your supply cant deliver that, it's riding on its output bulk decoupling during the peaks, which is likely to result in unwanted brightness fluctuations of verticals with respect to other parts of each character and possible colour shifts of yellow verticals. Due to the much lower average demand, you can almost certainly get away with a buck converter module from EBAY with a 10A ''chinesium' rating. However, if you go down that route, you'll need a TL431 + hefty TRIAC crowbar to save your matrix and drivers if the buck module's pass MOSFET fails. The loss of multiplexing protection circuit I mentioned earlier can drive a small current into the module's control chip's feedback pin to fool it into dropping its output voltage or alternatively if you'd rather a hard shutdown, fire the crowbar or activate the module control chip's inhibit pin.To determine the matrix supply voltage and row resistors, you are going to need to do pulse testing. Take a P-MOSFET that can handle >1.2A and drive it from the output of a 555 set up to provide a 1/15 duty cycle low going pulse at about 1KHz, Power the 555 from a 12V fixed voltage. Take one matrix, and eight 33R 1/4W resistors and connect all the rows via individual resistors to ground. Jumper ONE column anode (R or G) to the MOSFET drain. Put a good sized decoupling cap on the MOSFET soource and feed it from a variable supply ramping it up slowly from below 2V till you get the desired brightness staying under 150mA pulse current (which if the resistors are accurate is a 4.95V pulse measured at a row anode on your scope). If you want to fiddle with testing the yellow colour balance, grab another 555 and MOSFET, set it up to be triggered sequentially by the end (rising edge) of the 1/15 duty cycle 555 pulse, and to produce a variable with low going pulse to gate the second MOSET. Then with one drain connected to R and the other to G anodes (same column for yellow, adjacent columns for red vs green brightnesses), you can vary the second one's on time to balance colours without changing the common supply voltage. You can also try the effect of different row resistors.Allowing an abs max 5ma per TPIC6B595 from the same logic 5V rail as the MCU and 10mA for the decode to 16 outputs for the P-MOSFETs, that's 50mA @5V above what the Arduino or Atmega needs, so a linear regulator could handle it dropping from 19V with about a watt of dissipation. If an Arduino is used, the linear regulator could drop to 8V Vin and let its onboard regulator provide the 5V logic supply, and if you are going bare ATmega, or if you want to run the Arduino at 5V rather than off Vin, you'd simply drop to 5V for the MCU and logic directly.# How close to 150mA you can go depends on how much voltage you drop across the row current limiting resistors to reduce the importance of the difference between red and green Vf voltages.@ Because you are going to have to pulse up to 9.6A through the MOSFETs, and there is the possibility you'll need over 6V LED supply, there's a fair chance you'll need 16x proper gate drivers or at least a level shifter with active pullups if the 74HC138 outputs cant provide enough drive. A cheap option here would be a CD4515 4000 series CMOS 4:16 decoder (active low) in place of both 74HC138 chips, powered from the LED supply, with its limited output drive (1mA) increased by a complimentary push-pull emitter follower pair on each output to give around 100mA gate drive. Between 5V and 7V LED supply it wouldn't need any level shifting. Above and below that it would, but with only five input lines to shift that could easily be handled by a CD4504 hex level shifter. As you can see - its a tossup between 2x 16 pin 74HC138 chips + 4x quad MOSFET drivers, or 1x 16 pin CD4504, 1x 24 pin 4515 and 16 pairs of jellybean PNPs *AND* NPNs or at best dual complimentary paired (PNP + NPN) in SOT23-6 or similar.

author: Lomax
author_rank: Frequent Contributor
timestamp: August 31, 2018, 12:28:51 pm
content: Quote from: Ian.M on August 31, 2018, 11:26:13 amThanks Ian, really grateful that you're willing to help with this - but please, try to keep it on a level I can process; I'm getting confused here!I'm not just new to LED matrices, I'm pretty new to multiplexinganything.I had sort of made my mind up to go with switching row anodes, using beefy P-channel MOSFETs. That would keep the system in a domain that's easy for me to visualise, electrically and logically. Grouping columns for a sideways scan seems more complex to me, especially with an arbitrary number of total columns (the row number is always 8 ). With an Imax of 30mA per diode, and 128 diodes per row, I suppose I need at minimum 4A capable drivers - and to allow expanding to ten modules (160 LEDs/row) 5A. Would the ZXMP7A17KTC be a suitable switch (if driven from a 74HC299)?Code:Drain-source voltage VDSS -70.0 VGate-source voltage VGS 20.0 VGate-source threshold VGS -1.0 VContinuous drain current ID -5.7 APulsed drain current IDM -17.7 AContinuous source current IS -9.2 APulsed source current ISM -17.7 AInput capacitance Ciss 635 pFTurn-on-delay time td(on) 2.5 nsRise time tr 3.4 nsTurn-off delay time td(off) 27.9 nsFall time tf 8.0 ns

author: Ian.M
author_rank: Super Contributor
timestamp: August 31, 2018, 02:02:12 pm
content: Quote from: Lomax on August 31, 2018, 12:28:51 pmRow multiplexing makes your font handling code much harder to write and slower. The matrix part# BL-M07A881xx you posted (reply #18) is common cathode to row and is fairly well suited to column multiplexing. To row multiplex it each must be rotated 90 degs (possible only for square ones) to use it as common cathode to column. You still have the disadvantage of 1/16 multiplexing and needing 16 P-MOSFET row drivers.If you want a brighter display you'd need the BL-M07B881xx variant, with common anode to column, which would only need 8 P-MOSFETs, but they'd need to be capable of handling 19.2A worst case. You'd also need twice as many TPIC6B595 chips so its a wash on cost. Again, you get to choose row or column multiplexing by how its rotated.The 30mA If max is *continuous* current. When multiplexing, one pulses it far past that. You should be looking at "Peak Forward Current IPF(Duty 1/10 @1KHZ)" which is 150mA, which is five times greater and has *massive* implications for the P-MOSFETs, MOSFET drivers and PSU needed. Therefore your proposed driver you quoted parameters for above is most likely unsuitable, though I'd have to check it out in detail to be certain it couldn't be run at a somewhat reduced peak current.Its also why you need a safety circuit during development. If something goes wrong with the multiplexing you've only got a few ms to get *ALL* the LED currents down to 30mA or less or they'll turn intoDEDs#Signing off for half a day or so. Catch you later . . . .# See better definition ofDED

author: Lomax
author_rank: Frequent Contributor
timestamp: August 31, 2018, 02:21:58 pm
content: Quote from: Ian.M on August 31, 2018, 02:02:12 pmMy plan, though still somewhat vague, would be to treat it as a 2x64-bit array (red, green), which gets stuffed with bits from the font definitions for a given string. I.e. to output "Foo" in red take the first rows of the "F", "o" and "o" character definitions and pack them into the red output array (adding a single 0 bit between each). Repeat for all eight rows, outputting the result of each iteration to SPI before resetting the output array(s) to zeroes. This should be pretty quick, and allows arbitrary character widths. Also makes it easy to interleave red/green in different ways, depending on what order the TPIC6B595 chains expect. Maybe I'm missing something?The 5x7 matrix I first looked at was (seemingly) only available off the shelf in a cathode row config. But your first reply (I think) turned me onto the row anode track. That's why I started looking at 8x8 grids, where I only ever had the BL-M07B881 in mind. Apologies if that wasn't clear. Oh and the row anodes are common, so only 8 channels needed, with 128 LEDs hanging off each one.Quote from: Ian.M on August 31, 2018, 02:02:12 pmIf 19. 2A is the pulsed peak current then the ZXMP7A17KTC gets pretty close with 17.7 A.Quote from: Ian.M on August 31, 2018, 02:02:12 pmNoted. How about having a master shut-down pin which only goes high while the multiplexing is running? This could be used to kill the row supply.

author: Ian.M
author_rank: Super Contributor
timestamp: August 31, 2018, 02:56:25 pm
content: Leaving aside matrix & bitmap layout, and driver selection for now and responding to your shut-down question:Yep. There are plenty of ways of skinning the shutdown cat, some of which can be done for only a buck or two of parts. There's an output enable (inhibit) pin on all the TPIC6x595 family parts so the easy option is to turn *ALL* of them off which saves your matrix even if one or more MOSFETs have gone dead short or the LED supply has over-voltaged (though you'd still need a crowbar to save the high-side drivers if they cant take your original supply voltage).For the montoring circuit you need 16 1Meg resistors and caps to low pass filter the multiplexing direct from the MOSFET drains, some diodes to combine them, a 1Meg pulldown and a comparator with a potential divider reference input to see if any of them have stuck on. It really couldn't get cheaper or simpler.

author: Lomax
author_rank: Frequent Contributor
timestamp: September 05, 2018, 09:13:09 pm
content: Third time lucky...I've built a "proof of concept" app in Python (yes,Python, stop looking at me like that!), just to get my head around how to slice & dice & colourise all those pixels. It listens to incoming messages over a serial connection and picks up control codes in the passed strings to change the formatting options. The bitplanes (red, green) are multiplexed with a configurable interleave and presented as combined and interleaved ASCII "images", as well as eight individual rows of bytes. Still tinkering with fonts, but early testing shows that quite a few different geometries render well; from just 3x5 pixels to full-size 5x8. Fonts are read on the fly from 1-bit PNG images, and only one font at a time is loaded into memory. Colour, font and inverse can be freely mixed within the same "message", and settings persist between messages. The visual presentation runs as a separate thread, and reads from a bitarray buffer which is updated each time a new message arrives. It all works surprisingly well, and happily redraws in the terminal at 10Hz without any sign of bogging down.I now feel a bit(!) more confident that I can make these things go for real - time to dust off my AVR C toolkit and start converting the code! Does anyone know if there is a useable AVR simulator for Linux, or is it still a case of running Atmel Studio in a Windows VM?

author: Lomax
author_rank: Frequent Contributor
timestamp: September 11, 2018, 09:15:57 am
content: Working on the porting to Atmel C - I found a nice WYSIWYG MCU simulator for Linux which does AVRs and PICs, as well as a variety of "outboard" components, including 8x8 LED matrices.It's called SimulIDE, and has apparently been around a while, though I've never encountered it before. Very much a "work in progress", it has an annoying tendency to segfault, and the drag'n'drop GUI frequently glitches, but when it does work it's quite brilliant (and hey, beggars can't be choosers, right?).I worry that it will prove beyond me to ensure the function that reads and outputs the buffer bytes row by row (over SPI) runs continuously and smoothly; a fair amount of pre-processing is required to update the buffer whenever the input string changes. This has me thinking, is there such a thing as a "2D shift register"? Like a 256 byte buffer chip that I could load the buffer into instead of keeping it on the AVR? Sorry if this is a stupid question!Edit:256 bytes because it would allow for 16 module wide displays.

author: Ian.M
author_rank: Super Contributor
timestamp: September 11, 2018, 11:39:48 am
content: That's why I mentioned double-buffering in several of my earlier replies. With two copies of the buffer, the ISR can be using one to feed the multiplexed display, while your foreground code updates the other with new text etc. Then the foreground code signals the ISR to swap buffers and waits for the swap. If you need to modify the current display contents rather than totally replacing it, there's an extra step of copying the contents of the buffer the ISR is using to the other one after each swap.There's no easy one-chip solution to off-loading the buffering and display multiplexing to hardware. You could write code for a slave MCU to handle it, but the added complexity of needing to receive the display data from a host MCU would make the program tougher to write and test than integrating it all into one MCU. You could also do a FPGA based design but that's a whole level of hardware complexity above what you are contemplating with a *VERY* steep learning curve.

author: Lomax
author_rank: Frequent Contributor
timestamp: September 11, 2018, 09:21:56 pm
content: Quote from: Ian.M on September 11, 2018, 11:39:48 amThank you, that makes things clearer. And no, I won't need to read/write the buffer; quite happy to regard it as write only. That's how my Python sketch works*. Curious why double buffers would be necessary though; the code to update the buffer builds an array of bytes (say 8x16) and when done says buffer = array. Does it really take that long to copy 128 bytes from one register to another? I can see how it could lead to visual glitches, particularly if the display is animated, but I'm not interested in animation - in fact I find itannoyingand distracting - if I can update the display in under a second I'm happy, and don't mind pulling OE for the duration to hide any tearing.Quote from: Ian.M on September 11, 2018, 11:39:48 amThis is a little surprising, but I'm probably missing something fundamental. Such a chip would be quite quite useful, no? "Here's some data, hang on to it for me and iterate over it by the tick of the clock I'm feeding you." Basically what ashift registerring counter does, but many in parallel.Quote from: Ian.M on September 11, 2018, 11:39:48 amAgreed on both counts. FPGAs are terrifying - I hate blank slates; too many options, too many possible paths. Unable to compute. I'd rather deal w. challenge of ISRs. Tempted to use a RasPi Zero instead (threads!), but would ruin the fun by being too easy - and decidedly non-minimalist (see sig).*) Edit - this is the code that builds & updates the buffer in my "proof of concept":Code: (Python)def update_buffer(self):global BUFFERself.reset()sieved, ccodes = extract_ccodes(self.string)for index, char in enumerate(sieved):if index in ccodes["C"]:self.colour = ccodes["C"].get(index)if index in ccodes["F"]:self.load_font(ccodes["F"].get(index))if index in ccodes["I"]:self.invert = bool(ccodes["I"].get(index))ascii = ord(char)if ascii in self.font:letter = self.font.get(ascii)for x in range(PLANES):for y in range(ROWS):# use bitwise magic to select bitplanes by colourif self.colour >> x & 1:bits = letter.copy()bits.extend( * CHARSPACE)if self.invert:if index in ccodes["I"] or index == 0:# we are at the start of an inverted block; add left paddingbits.insert(0,False)bits = ~bitswidth = bits.length()if self.cursor < COLS:self.pixels[self.cursor:self.cursor + width] = bitsself.cursor += widthBUFFER = bytes(self.pixels, self.interleave)

author: Lomax
author_rank: Frequent Contributor
timestamp: November 12, 2021, 01:45:59 pm
content: Hi all,I came back to this project after stumbling upon a sale of 0.7" 8x8 1.9mm (20x20mm) bicolour LED matrices on Ali Express; $50 for 35 pieces including delivery. I don't want to miss out on this since 0.7" bicolour LED matrices are super-duper rare - but I need help deciding whether to get the common row cathode or common row anode version! I've read through the old messages in this thread twice but I'm still confused...Here's the product page on Ali Express:https://www.aliexpress.com/item/1005002781472461.html

author: LinuxHata
author_rank: Frequent Contributor
timestamp: July 15, 2023, 08:57:38 am
content: I'm in same wagon - I have some LiteOn made 5x7 1.9mm bicolor led modules, and searching for appropriate driver for them. MAX6952/53 won't do the job (and they're bloody expensive). Of course, there are some generic purpose 16x16 matrix led drivers, but I'd like to have a fitted solution.