Kevin Cuzner's Personal Blog

Electronics, Embedded Systems, and Software are my breakfast, lunch, and dinner.


A followup on the Dot Matrix Clock

Since I never quite finished the story about my dot matrix clock, I see no reason why I shouldn't write a bit of a continuation of my current developments. Shortly before I left on my mission for my church in November 2009, I received my boards for the dot matrix clock and assembled them. However, I ran into a problem: The displays would turn off after the voltages on the gates of the row driving mosfets reached a certain voltage and when the voltage was at a level where it would turn on the display, it had some problems with turning on and off the LEDs. Now, after I left on my mission I would think about this once in a while and I figured out the problem: I was using N-Channel mosfets with only 5V or less of gate driving voltage so they wouldn't turn on/off all the way. I am sure there are more problems than just that, but I keep kicking myself for using N-Channel mosfets instead of using P-Channel. Had I used P-Channel, the problem would have been avoided and this whole thing would have worked great. For the moment, however, this project is on hold since I am designing and building a few things that I will need in the long term here at college since I can't lug around a power supply and an oscilloscope.

So, in summary, if I were to do a re-design I would change the following:

  • The row drivers would be P-Channel mosfets. This would require using something other than a 4->16 demux for a gate driver unless I could find one with inverted outputs. Even with that I would probably put some very small gate drivers (if they exist...the size restriction might be too much) as a buffer to ensure the mosfets were turning on and off properly.
  • I would factor in larger tolerances. If there was one design lesson I learned from getting these boards it is that I need to make sure that I make the holes for things a little larger. It would definitely make assembly easier.
  • The PIC18F4550 would be replaced for a ATMega of some sort or maybe even a small FPGA. I was running into speed problems with the 18F4550 with getting refresh rates up (I know this is contrary to previous posts, but I was starting to have problems getting 30-60fps like I wanted...even though the image wasn't showing up anyway because of the mosfets). The 12MIPS speed was just a tad too slow and so I think if I were to use a 20MIPS ATMega it would work a lot better. Also, the tools for ATMega seem to be a little more opensourced than the ones for the PIC. I say this because avrgcc runs much better on my Linux machines than the various C compilers for the PIC series. Also, my AVR programmer (a USBASP) has very good native Linux support.

Now all that is left for me to do is to figure out how I can modify the boards I have so that I wouldn't have to drop $70 again...

Dot Matrix Clock: Display board assembly

Well, here it is. The moment I have been anticipating for a good while: The boards came in and I assembled them. I made a few videos and took a few pictures. I won't post the videos yet since I am still going through them and making sure that I don't go and make a fool of myself.

After getting that far, I believe my camera died. Anyways, I assembled the breakout board and completed all the parts of the display. I did not solder down all the display modules to the pcb because I am going to be fiddling around with the resistors on the column sinks and I didn't want to have to desolder a display before being able to do anything else. The next day, I started testing:

As for testing and stuff, it mostly works. I made a few errors in both the hardware and the software, but I at least got the LEDs to turn on (I have not, however, gotten them to turn off properly...). My original program which should have been immediately portable to the hardware did not work so well and I ended up writing the entire display portion of the program in assembler: Apparently doing a variable bit shift on a 32 bit number takes up a very...long...time when compiled in C for the PIC18F. The main issue with the original program was that when I expanded the display size to 40x16 it suddenly had no refresh rate to speak of. This was mainly a product of the way I had organized memory. I had stuck the entire display into an array of long ints so that access to individual pixels could be done almost entirely by index. Sadly, when the size of the display was multiplied by 10 the computation of the bitmask began to take too long and made it impossible to properly refresh the rows. The assembly program I made to replace this organizes memory in the same fashion that I believe VGA cards organize the memory: Everything in one big long array which has no end-of-row designation and just wraps around when it is displayed. This ended up being much faster and hopefully it will work for the finished product.

As for the hardware problems, I have several. First of all, I made the primary mechanical engineering mestake when designing the package footprints: I didn't factor in tolerances. All the through-hole parts BARELY fit. In fact, I have to coax everything in using a craft knife to get the pins lined up exactly before the part will even go in. The button pins are going to have to be sanded down since there is a taper to the pins that was not in the datasheet which makes the pins too large for the holes. The next big problem is that the column sinks are behaving very strangely. After the voltage into the LEDs passes above 3.3V or so some of the columns just stop sinking while others stay on. I have a few ideas to find out exactly what is going on here, but I have no real plan of action to fix that as of yet. My final problem is that I somehow managed to lift a pad when soldering down a resistor. How this happened I am not sure, but I think it has to do with cheap board construction and using a solder wik that is too big. I barely managed to find a trace to solder to, so it is kind of fragile even with the hot glue I used to secure the wirewrapping wire I used as a trace extender. The next time I do this I am putting a via in EVERY trace that runs into a pad, even if it doesn't need one just for this sort of situation.

Anyway, aside from the mentioned problems the boards turned out pretty well. Olimex was fast and relatively polite. Their construction wasn't too bad (aside from the pad, but that may have been mostly my fault) and the boards shipped right on time and arrived right on time (to the day, in fact). Overall I would say this whole board experience wasn't bad and since it mostly worked I will say I didn't waste my money.

Dot Matrix Clock: Renderings of the display board

I finished modeling the entire board in blender today, so here are a few different views of the clock:

I created these images in blender by exporting images of the various pcb layers from eagle, compositing them in gimp into front and back images, and uv-ing then onto the board. All the components were done by looking at their datasheets of course.

Dot Matrix Clock: Open sourcing the display schematic

Following the suggestion of a friend, I am going to open source a portion of the software (when it comes) and the display schematic. After I get the board and finish up the software I plan on releasing this as a kit. So far it is looking like the kit is going to cost somewhere between $110-$140. I would supply the board with the controller already soldered and programmed.

As it stands, the hardware features are as follows:

  • 40x16 display with two LEDs per pixel giving 1280 LEDs
  • Constant Current LED sink chips to prevent varying brightness problems with the display.
  • PIC18F4550 Microcontroller running off the PLL on a 16Mhz oscillator giving 12MIPS throughput
  • 41-pin high density board to board connector. A breakout board is included since development without one would be nearly impossible.
  • 4 buttons. These are not connected to the display microcontroller, but can be read through the board to board connector.
  • 8-bit parallel bus with CS, R/W, and CLK pins for communicating with the microcontroller in the fastest way possible. I have not yet decided on a maximum clock speed, but the clock is on an interrupt enabled pin.

The planned basic software features are as follows:

  • Built in font(s). These would not be restricted by rows or columns and would be placeable by specifying start coordinates. I may also add the ability to have either user fonts and/or variable width characters.
  • Pixel-by-pixel control of graphics. Each dot has 16 possible colors (4 brightness levels per color in each pixel...two colors). This would also allow direct memory "dumps" into the display for the possibility of animated things (assuming you have a powerful enough processor on the master side of the bus).
  • Triple buffering to prevent overwriting the buffer currently being displayed. This may be extended to allow animations by switching buffers, but I am not sure if I have enough memory yet.
  • At least 15fps throughput. 30fps is my target.
  • Bootloadable using only bus commands, no POR required. I may or may not make the bootloader protocol public, but I am leaning toward making it public.
  • More to come if I accomplish these and still have some clock ticks left over...

As for the board gerbers, I am going to keep them to myself. I spent nearly a year on the board design and I think I need to have at least some profit come of it before I release it to the world for some crazy board outsourcer to steal and clone at half the price I managed to get it fabbed at. I'll tell you this much: Eagle's autorouter can't handle the entire thing and there are well over 300 nets (not airwires...nets), so good luck.

Now for the schematic. Here you go:

DotMatrix_v3_5.png

Dot Matrix Display Schematic v. 3.5

Now, before someone goes on yelling about how much the BSS138 sucks as a MOSFET I guess I should say that I have replaced it with a much better one that can actually source the current I need it to. The BSS138 has a couple ohms of RdsOn, so I replaced it with a MOSFET that has around 0.25Ω RdsOn. Enjoy.

Dot Matrix Clock: Order placed

I have finally placed my order for the dot matrix clock. I chose revision 3.5 which had a surface mount crystal instead of the through hole version.

The only problem I have run into so far is that Olimex requires that the payment informatoin be faxed, so I have to use the fax machine at work to fax the order information. Luckily, my dad also works there and if he uses it for personal use there is much less chance of him being punished than me.

I just have to hope that they notice that all my solder side stuff is mirrored as that is the default with Eagle.

Dot Matrix Clock: Down to two candidates

Well, just a short update here. I think I will probably be at home for another month or so, so I am going to go ahead and order the dot matrix clock display board. However, I need to decide between a surface mount crystal or a through hole crystal. I think my post on edaboard.com pretty much sums up my dilemma:

I have two possible versions I have been designing for some time now. Since it is looking like I am going to be home long enough to finish it I guess I should get it fabricated. However, one thing needs to be decided before I order it and that is whether or not I should use a Through-Hole or Surface Mount crystal.

Originally I was going to just use a through hole crystal, but after having a friend of mine look over the board as another set of eyes he pointed out that my crystal traces were over 3in long and had several vias in them. So, we identified a spot where a surface mount crystal could go with no vias and 0.5" traces. The criteria for fitting in this space was that the crystal had to be no more than 7mm long, 3mm wide, and 1.5mm tall. The obvious problem here is that nothing really fit in that space except for a crystal made by Abracon that is 3.2x2.5x0.7mm. Now the problem is size: is the crystal too small?

My resources: 0.015" solder, 1/32" spade tip (on a variable temperature soldering iron), solder wick, and a relatively steady hand (successfully soldered a .4mm pitch 64tqfp by hand without overheating it). Things I don't have: A magnifier, reflow oven Things I don't have but could get: Heat gun, solder paste

I don't have enough experience with this sort of thing to answer it myself and I really can't afford to buy two versions of this board. Is using a crystal this small really worth it?

System Message: WARNING/2 (<string>, line 17)

Definition list ends without a blank line; unexpected unindent.

Well, hopefully I will have that problem solved before the end of the month so I can place my order as soon as Olimex comes out of their summer break (for some reason, Europeans take a month long vacation from work in the summer...how odd...).

Eureka! The Dot Matrix Displays Work!

sdc10183.jpg

Running one display block with pixel 0,0 turned off

I have finally managed to get a dot matrix display running full bore without resorting to outrageous voltages such as 18V on 5V logic. I have been working towards this moment for probably 2 or 3 years now.

This uses a pinned version of the hardware described in previous posts and more or less proves that it will work with that hardware with few modifications. The only major difference is that I am not using the same chip for the LED current sink. In the picture on the right it is running at an input voltage of 6.37V@325mA which is regulated down to 5.26V and 4.78V.

One major deviation from the hardware mentioned previously is that the row decoder is running at a slightly higher voltage than the rest of the circuit (5.26V). This is to remedy a problem I noticed with the MOSFETs in which their gates are not fully turned on unless the gate voltage is above the drain voltage. What I ended up doing was running a 5.1V zener off of the input from my power supply to create a higher voltage than the 7805 supplies to the rest of the circuit (including the MOSFETs). This is marvelously ineffecient and seems to be causing the 7805 to heat up, but that also might be from the problem that I will go over next.

The other major deviation is how I am running the column sink driver. I ordered one that I thought was almost the exact same as the one I planned to use on the PCB, but doesn't behave like the datasheet says it should. I ended up having to take away the external resistor and replace it with a direct short to ground. This effectively removed the current cap and now the chip is drawing 120mA by itself (which is bad). In contrast, the chip draws 20mA with a 300Ω resistor, but half of the rows get turned off. This in itself makes no sense since this is the column sink and for something like this to happen it would have to have something to do with the row drivers (i.e. the MOSFETs and accompanying logic), but it consistently shows up when I put a resistor on the resistor pin of the column sink chip. However, if a row starts flickering irregularly all I have to do is increase the input voltage a bit and it goes away. Any ideas as to why this would happen are appreciated (leave a comment).

From a coding standpoint I think I grossly overestimated how hard it would be to strobe this display. The chip is running at 12MIPS and so far is able to render an entire 40x16 buffer at 30fps with a ton of idle time. I have not yet implemented the grayscale dimming functionality, but even that won't add much to the overhead. Looking at my scope I can see that out of the 584uS between rows only ~290uS is actually used for writing to the column sink and switching which row is turned on. This means that my "processor usage" slightly less than 50%. I was expecting it to be significantly more, but now I see that implementing the 8-bit parallel bus which will be the link between this and the "computer" board will be easier than I'd hoped.

Revision two

After looking at my design of a few days back I decided it definately needed another revision. For one thing, I switced out the serial->parallel chips to a more common chip that I can get off of digikey (497-5746-1-ND) for $3.30 apiece which isn't too bad (it's not the best though...but it will save on shipping). I also got rid of most of that empty space that I was not using and managed to compress the entire thing so that it is as small as it can get unless I drastically change my design.

dotmatrix_8x8_v2.png

Dot Matrix revision 2

Major Changes

As you yan see I have moved all of the chips underneath the displays. I had not done this before because I thought the autorouter wouldn't be able to handle it and I would be left with 100 airwires to resolve. However, when I upgraded the chips the package size had to go up from SSOP to SOIC. This drastically reduced the complexity of routing and made it possible to fit everything beneath the displays. I was a bit sad about this change, but I could only find SOIC versions of the more popular chip (I enjoy soldering small chips because of bragging rights).

Another major change is the position of the mosfets. I have moved them from more or less a column into two "blocks" which are more or less symetrical. I had never thought of this before and it made the airwire ratnest much less dense in the long run with being able to position the column sink chips underneath the adjacent dot matrix module. The mosfets I am using are BSS138LT1GOSDKR-ND (say that 5 times fast) and are $0.58 apiece for 20 (they only way I could find them was on digireel, so the price changes with quantity).

The final major change was an error correction. I found that I had accidentally named all of my clock lines CLK. I have probably 4 different clocks and they were all connected together. I had to separate them and that pretty much broke the last design since I didn't feel like layout out the board in exactly that pattern again.

Releasing my designs

I have decided that I am going to publicize my designs if anyone wants them. However, I will not be giving out the eagle files for my own reasons. Eventually I will export the schematic in JPG (I have to clean it up a bit) and I will include the board as gerber and excellon files. This could take time, so don't expect them for a bit.

Fabrication

I am now thinking of how to get this board fabricated. I have found one company, olimex, who will do it for around $40 per board (no minimum quantity) which is really quite cheap. The also allow panelizing and will cut your boards for you if you want, so I might wait until I have the entire clock finished before sending it off for fabbing. The only problem so far is that my board is .3" too wide for their smaller double sided panel. The upgrade is over $100 and adds about 6" on every side to the space which I don't need unless I decided to make two clocks and panelize all the parts into one board. Hopefully it isn't too hard to get these fabricated since I kind of need them to be fabricated before I can do serious testing on my software.

Resurrecting the Dot Matrix Clock

Man, I have been working on this project since probably 2006.  This is by far my longest lived project with about 4 different breadboarded prototypes, 2 or 3 different control schemes, 2 differnt types of displays, and 3 different microcontrollers designed for. I think I have settled on a final design and I do have to say that this clock is more like a computer than an actual clock.

Background

A few years back I saw a POV clock made using a PIC16F84 which I thought was pretty cool. The only drawback that I saw at the time was the fact that it depended on moving parts that made noise. I really wanted to make something like that, so I looked into Dot Matrix displays. At first they seemed really expensive and difficult to get, but I eventually learned that surplus sites and eBay had very cheap displays that I could get. I proposed the idea to my mom to see if she would pay for it and she agreed (to a reasonable limit). I expected the project to take 6 months to a year. I was  dead wrong. Getting a display to even be bright enough to see was a challange on its own, but eventually I learned enough about how to push LEDs to their limits that I could get a visible display running. Originally I used LPT747R displays, but these turned out to be too dim and even after pumping 18V through my 5V logic (resulting in the literal explosion of a hex inverter, but no damage to any of the other parts strangely) they were still barely visible under normal lighting. I discovered that even though LEDs may seem bright when powered constantly they are dimmed to about 1/16 of their original brightness when ran multiplexed. An added bonus of this is that you can pump about 16 times the amount of rated current through an LED (this reduces the LED life though...and if your display freezes those pixels are shot). The other brightness limiting factor is the maximum current driving capacity of the chips used to supply the current and to sink the current. Using standard 74HC logic didn't work very well since they simply couldn't supply enough current (this is probably why 18V didn't blow up the LEDs...not enough current). It took a while, but I have been able to figure out how to drive enough current through the displays to get them to be bright enough (more on this later). Recently I switched over to some 8x8 dot matrices which have also increased visibility greatly.

The display uses an array of serial->parrallel shift registers driving (now sinking) the rows with either a multiplexor or mosfet array sinking (now driving) the rows. I now use a combination of a multiplexor and mosfet array to drive the rows. The entire system is controlled by a microcontroller (originally a 16F628A, but now an 18F4550). The microcontroller stores two entire screens in memory and displays one at a time. During the displaying process each row is clocked out to a chain of shift registers and once the entire row is out the registers shift their data out to some latches which turn on specific LEDs. The rows are controlled by the microcontroller in some fashion which has varied depending on the current mockup.

The current hardware

The current version of the Dot Matrix clock consists of two main boards: The display board and the controller board. As of this writing I have only completed the PCB layouts on the display board. An 18 pin connector connects the two board. Each board has a microcontroller on it with the display board having a PIC18F4550 and the controller board having either another 18F4550 or a PIC24HJsomethingorother (I haven't decided yet). The displays are 10 8x8 displays arranged into a 5x2 pattern giving me 40x16 pixels to work with. I plan on having 4 brighness levels possible per pixel, but this depends heavily on the amount of memory I will be able to spare for display buffers on the microcontroller. The displays are column-cathode, row-anode so power is supplied to the rows.

The PCB layout as it stands now (and as it will probably look in the next revision more or less) is displayed below. There is quite a bit of unused space, so it is possible that I will upgrade to a 4 layer board and just put the entire clock on one board.

dotmatrix_8x8_prelim.png

Layout as it stands now

Row driving

Row driving is accomplished by using a 4->16 multiplexor switching 16 mosfets which drive each row. Each mosfet is rated at something around 200-400mA which should be more than enough to drive 40 LEDs at a 1/16th duty cycle at full current with all of them on. Current limiting is accomplished by the column driving/sinking chips and will be explained next.

Column Driving/Sinking

Current capacity was a big problem with my previous designs using the 74HC595 chips for column sinking. The chips could only sink so much current at once and would start limiting it at a certain point. This lead to unequal brighness and low visibility. I found a solution to this on one of the pages at this site. It showed a demonstration of a display using an MBI5027 shift register to sink columns. This shift register is capable of sinking 50mA per output pin and limits current by use of a set resistor on one of the pins. It also has short/open circuit fault detection. The only problem with this chip is that it isn't very available. The only place I could find it was on this King Fish electronics or something like that. They used UPS for shipping which was a minimum of $10. I was not about to pay $10 shipping for a few $1 chips, so I put out a plea for help on one of the various forums I troll and got a response about this MAX6979 chip from Maxim-Dallas. It does the exact same thing as the MBI5027 and even adds a watchdog so that it blanks the display if serial input stops for over a second (could save my modules if my controller crashes). What's more, it was only $0.26 more than the MBI chip and it was sampleable. I have not yet gotten this chip (I think it is in the mail) and I can't wait to try it out.

The shift registers are arranged in a chain and data is entered rightmost pixel first. The previous row's data is displayed even during clocking and isn't replaced until an entire new row is ready.

The Software

As of yet I am not ready to release any of the software for this, but I will give the basics of its operation below. The software is mostly incomplete, but I have most of it thought out.

The Display

I have spent most of my time debugging the software for this. Until I got an oscilloscope this was very slow going and my code was very error prone. Even with an oscilloscope I tend to make mistakes like not blanking the previous row before turning on the next one (causes ghosting) or clocking out the data backwards. So far I have only experimented with going right to left, but as I write it has occured to me that arranging the shift registers in the opposite direction and outputting the data left to right would be easier on my mind (and would avoid having to flip my arrays). In either case, the basic sequence this uses to output a row is as follows:

  1. Clock out the new row with the rightmost bit first
  2. Turn off the row currently on off
  3. Shift all the new data into the latches on the shift registers
  4. Turn on the new row and repeat step 1 with the next row keeping this row turned on during step 1

Switching steps 3 and 4 causes slight ghosting and that was probably one of my larger mistakes when I was first writing the code a while back. The rows are stored as two arrays of 40 16-bit words using a row mask. Only one array is actually displayed at any given time and the array that is not being constructed with graphics data is being displayed. After the graphics array is constructed the active array switches and the opposite array is writen to. This prevents screen flicker, makes animation smoother, and allows for a constant framerate without fear of interrupting a write and getting something funky displayed for a frame or so. This is a commonly used technique that I first learned when programming BASIC with I was about 10 or so and applying it to this is not difficult as long as I have the memory.

Adding "color" to the pixels is one of the possible features of this. Instead of having each array be 40 16-bit words it will have 40 32-bit words. This doubles the memory requirement and starts to approach the memory limit of the 18F4550 (remember there are two arrays). The row displaying sequence will be quadrupled so that instead of displaying 16 rows it effectively displays 64 rows, 4 for each actual row. This shouldn't reduce the overall brightness of the screen since all it does it add PWM to each individual row with 2-bit resolution giving 4 "colors".

Data will be written to the display using an 8-bit master-slave parallel bus between the display board and the clock board. I have not yet come up with a control sequence, but the basic functionality will be like the Parellel Slave Port that I have seen on a few higher end microcontrollers. I am leaning toward something along the lines of the following for a control sequence:

  1. Master sends commands that specify where to start writing data and how much data will be written
  2. Master enters data mode and writes raw data to the bus. The address pointer is incremented with each byte sent
  3. After the specified number of data bytes the slave enters back into control mode
  4. The master can either issue more writing commands or send a "refresh" command that will switch which array is written to and display whatever data it has just written.

The program is going to be interrupt driven with the row displaying on a timer so that the framerate is constant. Switching arrays will only happen after an entire frame has been displayed, so there will have be a few flags between the bus "process" and the display "process" to facilitate this. Hopefully the controller won't be overwhelmed, but I plan on running at the full 12MIPS using the fastest crystal possible and the PLL.

Obviously, most of this code is not yet written but I do have a good idea of what I have to write and after getting a hardware prototype working it sould be relatively easy to put this code in.

The Clock iteself

I haven't even started writing the software for this, but it will be probably even more complex than the display software. I plan on using one of the 24HJ series of PIC microcontrollers to handle this to try and process as much as possible. Some features that this clock will definately have and I have already figured out are as follows:

  • Timekeeping using a RTC with a supercap as a backup power supply
  • Multiple alarms (maybe up to 32 or so?)
  • Number changing animations
  • Menu system

Other possible features that I could add given enough time:

  • Multiple fonts for numbers
  • Use an SD card with uncompressed WAV files on it to get alarm "ringtones" (I have done something like this before, but never using an SD card or actual WAV files...only arrays of numbers)

Outlandish features that could only be added if my current programming experience is significantly increased:

  • Get and read RSS feeds using wifi
  • Sync a calandar with a computer wirelessly
  • Who knows...

Conclusion

As always, do not take my ideas without asking me first or crediting me somehow. Feel free to use this as a resource for your own projects, but if I see an exact duplicate of my clock out there somewhere that I didn't know about previously it could be bad. The point of this clock is to be unique, so if you end up making a clock based off of information you found here then try to make it unique enough so that it could be distinguished from mine easily.

I am not sure how often I will be able to actually work on this clock, but I will post updates when I reach milestones and such.