Showing posts with label LED. Show all posts
Showing posts with label LED. Show all posts

Sunday, 1 November 2015

One Small Step ...

... gulp!

Well it's a big step for me, and you'll see why pretty soon. But let's start with a gratuitous arty-looking shot of where we're headed ...




So, as a bit of an introduction, I've been messing around with a number of projects. Having got the hang of designing my own PCBs and getting them made and sent from China for very little money and just a lengthy wait (ok, about a 10 day turnaround if you pay extra for DHL), what I found I've started doing is pipelining my hobby.


Pipelining?


Yes.

So what I mean is, I have an idea for a project, then I design a circuit, research components, breadboard it, write some code, and then when I'm confident enough that it's going to get me somewhere I order some PCBs and wait.

Then, while I'm waiting, I have an idea for a project, I design a circuit, research components, breadboard it, write some code, and when I'm confident enough that it's going to get me somewhere I order some PCBs ... and so on.

This way, by the time the boards arrive for project X, I've already submitted a PCB order for project Y and am busy breadboarding project Z.

This is magic. It not only stops me getting bored, but it allows me to fail (and therefore learn) at three times the rate that I was achieving previously!

Accelerated failure! Perfect. I should patent this idea or something ...


Accelerated failure


So, following my terminology above, I've managed to successfully fail with project Y before even receiving the PCBs. How cool is that?

I'll get to the "small step" thing soon, honest, but in case you're wondering what I'm blathering on about, here's the current state of projects X, Y and Z.

Project X - I've got hold of an ArduCAM Mini module which I've ported to work with a PIC and then combined this with an ESP8266 so I can automate the process of capturing a full colour HD resolution image and then email it to myself for posterity using WiFi. The ultimate aim is to build some kind of time-lapse photography system. The basics work fine, I have some working boards but things need tweaking to allow low-power modes etc. and I still haven't tidied up the software ... so, a work in progress which I'll bore you with in a later blog ...

Project Y - If you remember back in December last year I was messing about with some 8x8 LED matrices. Well, the eBay seller that I bought these LEDs from was having a bit of a sale. Not being able to resist a bargain, I bought a load more of these LED arrays and thought it would be good to use PWM (remember the fan?) to drive each of the 64 LEDs at a different brightness level. So, a quick design with a 74HC138 multiplexer and a PIC16F648A, which features "high current" sink/source for direct LED driving, and I was quickly on my way to waiting for some more PCBs to arrive .... but ....

... too keen .... far too keen ...

Thinking that I could get a useful range of brightness levels while multiplexing all 64 LEDs on an individual basis was wrong. Well, not wrong, more like stupid.

So .... before I tell you about Project Z, I need to tell you why Project Y failed.


Project Y ... or Y not!


This was the basic idea. A single 8x8 LED matrix with the cathodes driven low via a 74HC138 inverting multiplexer and the anodes connected directly to the PIC via current limiting resistors.
The plan was to run the PIC at 20MHz from an external oscillator (saves me a pin) and cycle through each LED by setting one (and only one) anode high - by very careful programming - and one (and only one) cathode low - courtesy of the 74HC138 because that's what it does - and while I'm delaying for a bit on that one LED, to set the PWM duty cycle in proportion to the required brightness and use the PIC's built-in PWM output to drive the enable line on the multiplexer. So effectively toggling the LED on and off to vary its brightness.

By running the PIC at its maximum allowable speed and configuring the PWM for ~78KHz,, this gave me about 12.5 microseconds dwell time per LED, which was enough for about ten cycles of PWM to get the required brightness.

So, even though this worked, and worked quite well, it looked a bit dim. I probably should have done the testing in daytime rather than evening because I thought it was just a matter of tweaking the current limiting resistors a bit to get as much current as possible through each LED without exceeding the 25mA peak limits of the PIC source pin. So I designed some PCBs that matched the physical size of the LED matrix and which held the '138 and the resistors, thinking I'd have a nice module that I could piggy-back multiple copies of onto another board where a collection of PICs would orchestrate a larger display.

Well, wrong.

As soon as the order for the boards had gone in, I set about maximising the brightness by measuring the current consumption and reducing the resistor values to get a happy medium. This is where I failed. Even removing the resistor completely (normally not a wise idea!) only gave me an average current draw of just over a milliamp. Pathetic.

The reason eventually dawned on me, that by multiplexing all 64 LEDs individually, the brightest that any of then could be was only going to be one sixty-fourth of its maximum. Effectively, my duty cycle had an upper limit of ~1.5%, which I was then reducing further by applying PWM on top! Doomed to fail.

Thus, Project Z was born ...

Project Z


Wondering how this LED display thing is really done, I stumbled upon Application Note 1216 from Avago Technlogies, entitled "Introduction to Driving LED Matrices".

Yes, I should have read that first, but hey ... impatience is something else I need to work on ...

Anyway, if you read that PDF, you'll see that multiplexing LED matrices isn't done one pixel (LED) at a time, it's done one row at a time! 

The whole thing starts with the required frame rate - normally no less than 60Hz - which is required for persistence of vision to fool the eye into thinking that the display isn't flickering. So, for the sake of argument, we'll aim for 100Hz, which means a single frame will last for 10 milliseconds. As we have eight rows and we're multiplexing them, then it follows that each row will be active for one eighth of that 10ms, so each row gets 1.25ms (or 1250 microseconds).

Now the 1250us time slice for that row is further divided into a number of time slots that relate to the number of desired brightness levels. Still with me? Ok, then each LED in that row is held on for the number of time slots equivalent to its required brightness. 

For example, keeping the mental arithmetic simple, suppose we want 125 different brightness levels (aka grey levels). Then the row time of 1250us is divided into 125 slots, each of 10us and this 10us period represents our "inner loop" at each step of which we decide if each LED in the active row needs to be on or off. We can do that simply by decrementing its grey level within that loop and turning the LED off when we reach zero.

Sounds like a good plan, my multiplexing overhead goes from one-sixty-fourth to one-eighth, my LED brightness increases accordingly and I only need minor changes to my code. Hmmm..... really?

Suppose that all 8 LEDs in the active row have the maximum grey level of 125. They will all be on for all of that 1250us time slice. During that time they will each be drawing 25mA, which means 25 x 8 = 200mA needs to be sourced and sunk (sinked?) ... that's well outside the maximum limits of both the PIC and the multiplexer. If we don't want a nasty accident, something beefier is required....

Skinning a cat


As in "there's many ways..." - don't worry if you don't understand, no animals were harmed ...

Anyway, there are a number of solutions for this LED driving problem. You can buy dedicated LED driver chips, I've used some myself with the previous foray into LED matrices. You can get built-in current limiting, PWM, dot correction, yada yada ... for example, things like Texas Instruments' TLC5941 and many others. But it all boils down to the same things:

  • You need a way of sourcing current
  • You need a way of sinking current
  • You need a method of multiplexing
  • You need a way of controlling grey levels


Well, I've already got all of these, just that the first two are not man enough for the job. This was because the PIC handled both the sourcing and the grey level control, and the '138 handled both the sinking and the multiplexing. So, let's delegate those sourcing and sinking jobs to something else ...


More source sir?


I found a few possible components for sourcing eight channels at suitable current levels, but these were not as common as the sinking counterparts. I eventually settled on another Texas Instruments chip, the TLC59213, which is an 8-bit parallel Darlington source driver with an input latch. Its can be driven directly from TTL or CMOS levels and it can source up to 500mA per channel, which is easily enough for what I need.

Here's the "Typical Application Diagram" from the datasheet.




In my application, I'll be using this to drive the 8 LEDs in a single column - so, like I explained above but with rows and columns swapped. Therefore, at any one time there may be more than one output channel active, so - like it's shown in the diagram - this is where I need to put my current limiting resistors (so that the 8 LEDs in the active column are effectively driven in parallel, each with its own resistor).

There was also an older, similar chip from Allegro called UDN2981, which although discontinued some time ago is still available for some eBay sellers. However, apart from being old and difficult to obtain (I did get some to try), it also doesn't have the input latch. That latch is very useful for me, because it means I can take my time - in the code - setting up my high/low outputs on the PIC without worrying that it will cause glitches on the display as I switch columns. Once I've set up the new configuration, I just pulse the clock input to latch my new outputs to the LED. Nice.

One other alternative I considered was the TPIC6B595, which is a high-current 8-bit shift register. It can also handle up to 500mA per channel and it otherwise behaves just like a normal '595 shift register and is in fact pin-compatible. However, having to serially shift in the 8-bit LED pattern for the active column takes longer than setting up the parallel outputs of the TLC59213 and I was a bit wary of introducing this delay into the innermost loop of my scanning code. I didn't try it, so I don't know if it would be a problem ... just felt a lesser option for me.

Ok, so that's the beefy source (beef sauce?) sorted - at the cost of one more component - so what about the sink?


Sinking, sinking ....


Easy choice here and really only one way to go. Yet another TI component (no, I don't get commission!), the ULN2803A high-voltage, high-current, 8-channel NPN Darlington array. The "A" on the end means that this part has built-in 2.7K base resistors for each Darlington pair, so it's an easy one to use directly from a CMOS driven output from the PIC.

Eight channels in, eight 500mA sinks out. Again, more than enough for what I need, but at the cost of yet another component (see where I'm going here?).

Only one complication here is that the sinks - which relate to my LED columns - are the ones driven by the multiplexer (because I don't have enough pins on the PIC). However, the 74HC138 multiplexer I used in Project Y is inverting - so all but one output is HIGH. Whereas, the ULN2803A expects a HIGH input to activate each sink channel. Simple solution though is to swap out the 74HC138 for its non-inverting companion, the 74HC238, which is otherwise identical.

Ok, we have the technology .... we can rebuild him ...


8x8 Greyscale LED Matrix Driver


Remember that the point I'm trying to reach here is to have a small PCB, small enough to just fit a single 8x8 LED matrix, that contains as much of the driver circuitry as possible, so that I can use it in conjunction with another board - or by flying ribbon cables - so I can hook up a larger display.

Bearing that in mind, here is the full schematic for such a board. It contains the source and sink drivers, the multiplexer, the eight current limiting resistors and the 8x8 LED matrix. It has some pin headers so I can hook it up to power and to the PIC (just click on it to see it larger).




Notice that the row and column pin ordering is now not so logical. You'll see why in a moment.


So what's with the "small step"?

Ok, finally, I get to the point! You probably got there before me though, and I'd be surprised if you didn't. But ... if you're still wondering .... just think ....

... one 16-pin IC, one 18-pin IC, one 20-pin IC, eight resistors, one capacitor, 16 connectors for the LED matrix and 14 pin headers for connection to the PIC. All on a PCB that's a maximum of 33 millimetres square....

Not a snowball's chance in hell.

It doesn't fit. It will never fit. You knew it wouldn't. I knew it wouldn't. You always knew what I'd have to do. You told me. I didn't listen. I put my fingers in my ears and went "la la la".

Surface mount.

Yes.

I got there eventually.

I'd always said "I'd have to get boards made for everything" .... crap ... "It's not easy to breadboard with SMD" ... crap ... "It's difficult to solder" .... crap ... actually all crap. All my excuses, that is.

If you've been paying attention to my accelerated failure technique, you'll realise (although I didn't) that I've developed the habit of getting boards made for everything anyway. So I may as well design SMD boards right? You get more space to play with and you can use both sides of the board. Components are very often cheaper and you have a wider selection of parts to choose from. No brainer. No brain at all, more like.

As for the other "objections", look at this:




What is it? I'll tell you what it is. It's a TSSOP-20 to DIP adapter. You take a tiny 20-pin device, like the TLC59213 in the picture (ring any bells?), solder it on, add some 0.1" pin headers and you stick it ... in your breadboard .... and it works. Easy.

Who made it? I did. How many attempts? One.Was it easy? Well, a bit shaky to be honest, but it was much easier than my large sausage-like fingers and rubbish eyesight thought it would be.

Yes, I have arrived. I shall celebrate with a cold can later .... but for now, we have a board to design!


Squeezing it in ...


Easy to fit everything but routing is more tricky. Pin pitch is smaller, so more difficult to route tracks between pins. Even if you do, you have to make them narrow enough to get the right clearance and then make sure they can still take the required current and don't add too much impedance ... yes, a whole new world of problems, but now I'm here I don't think I'll be going back.

The fact is that I did it. You can now see that the non-sequential numbering of the headers is purely to aid in routing. These bloody LED matrices don't nicely have eight anodes on one side and eight cathodes on the other, but they're spread around in some unknowable but seemingly consistent configuration. Anyway, like I said, I did it.

Here's the top of the board:




And here's the bottom (mirrored, so as viewed from the top):




Maybe you can see lots wrong with it, but it's my first, so it's special. I will always love it. Here's the real thing.




So, now, I can try to get this mess off my breadboard and crack on with the real aim of the project, which is to build an arbitrary-sized display by combining the modules - drive each one with its own PIC to distribute the computing load (and hence the need for an FPGA) and see if I can do anything useful or interesting with it.


Before and after


So, before I took that one small step, this is what my breadboard looked like with just one of these LED matrices wired up:




Now, this is what it's like with two of them:




Neat eh? Now I can start to progress with trying to drive more than one of these modules somehow, but that's another project ... project ...errrm .... whatever comes after Z, I guess ....oh .... bugger .... you see what I did by not thinking ahead .... again? 

Accelerated failure is a success ..... !


Video evidence


Just in case you're still reading ..... ;-)




Ok, I'm off to start or finish another project now .... more later ....

Saturday, 27 June 2015

Don't be so wet! ...

.... or so dry!

It's been six months since my last post, a long time but I've been busy.

Continuing my exploration of all things electronic, I've been happily making stuff, making mistakes, making a fool out of myself by asking stupid questions of anyone and everyone, but also learning a lot. I've compounded all the practical work with a couple of free online courses too - both from Coursera, I've stumbled successfully through Linear Circuits and also Introduction to Electronics - not too advanced, but useful nonetheless and certainly as much as I could manage with a full time job!

So, what's with the "wet and dry" theme?


How to explore your own hobby while keeping your "significant other" happy!


My wife is a keen gardener. That's keen with a capital K, and gardener with a capital G. So we have an active and ever evolving garden, plus more houseplants than you can shake a stick at.

So, for my next project, I cunningly suggested that I might make her something that would allow her to monitor the state of her houseplants from the comfort of the sofa - that is to say, a wireless plant moisture monitoring system! No, I didn't mention that you can buy such things for very little money and with much more hope of success, but I got the green light to start building things, which was the main result I wanted ... hehe.


Wireless wetness

If you Google or eBay for nRF24l01p, you'll find loads and loads of people who will sell you these little units very cheaply:

What it is, is a 2.4GHz wireless transceiver that you can talk to with Arduino, Pi, PIC, whatever and generally get simple wireless capability into your projects very easily. So I bought a handful.

They run off 3.3V so rather than using my normal preference of 5V PICs, I chose to use one of the PIC16LF range of low power microcontrollers, in this case the PIC16LF1554, which has much more available than I needed for this project (I just need SPI and ADC really) but it did allow me to test and prototype with a UART talking to my PC via a TTL to USB adapter.

The grand plan

So the grand plan was to have a number of moisture monitoring sensors, each one stuck into a favoured houseplant pot, and each periodically measuring the soil moisture level and pinging off a packet of data to a central monitoring station, which would collect and collate the various wetness reports and allow them to be presented in a suitable manner.

I planned to use simple resistive moisture sensors because a) they are cheap, and b) they are cheap. So a few quid on eBay and a long wait for China Post and I harvested a dozen of these:



To read the moisture level, you simply wire this as part of a voltage divider that you sample through the microcontroller's ADC (analog to digital) pin to get a resistance measurement that you blindly assume is both accurate and varies in a linear relationship with the moisture level. Neither of these are true, but who cares - that's not the point! I did pay homage to some advice though that warned against always sampling with the same polarity - risk of gradual electroplating of one prong from the other - so I always take two ADC readings, one with polarity reversed, to even up the battle a little.

To make things even more interesting (complicated), I also wanted a way to reconfigure the sensor units without having to reprogram their PICs, so I used a simple protocol that allows me to remotely adjust the frequency of wetness sampling for each individual sensor. It goes something like this:

  • Sensor wakes from sleep mode.
  • Sensor takes two ADC readings and creates a packet of data.
  • Sensor sends data to the master unit.
  • Sensor waits a reasonable number of milliseconds for a reply.
  • If the reply arrives and requests reconfiguration, the sensor adjusts its sleeping time.
  • Sensor goes back to sleep.

By using the PIC's watchdog timer to wake it from sleep mode, along with some suitable preset combinations of prescaler and counter, I could manage a sampling period of anything between 15 seconds and 16 hours. The former useful for testing and the latter 8-hour or 16-hour period being used in practice.

The sensor

The sensor circuit went through two revisions. Mainly because I was stupid. Ok, no "mainly", but only because I was stupid!

But then you don't learn anything without making mistakes, so stupidity is a good thing ;-)

So the first version of the sensor PCB looked like this:


The first stupid mistake is the battery on the left. I chose the wrong part in Eagle, so instead of having a battery holder, I had a fixed battery with welded solder tags that you can't remove from the board without desoldering. So obviously, you also can't switch it off. Hmmm .. too keen to get the boards ordered, and I don't mind admitting it. Lesson learnt. Probably.

The second stupid mistake was that I forgot to add the recommended 10uF capacitor across the power terminals of the RF unit. In practice it didn't seem to matter, but as I was going to redesign anyway, the second version attempted to fix these issues. The final schematic for the sensor was like so:


At the top left is the 4x2 header to receive the nRF24l01+ unit, then under that is the voltage divider circuit to the moisture sensor (JP1), and apart from power and bypass cap, that's it. So it now looks like this:


The battery can be removed or replaced as required and so I now have a nice stock of the other, fixed tag, batteries because I found I could buy 80 of them for ~£5 on Amazon. Ho hum.

Anyway, I made six sensor boards, each PIC pre-programmed with a unique identifier that gets put in the data packet when sending to the master. So the master correlates the sensor ID with its - also pre-programmed - list of houseplant names, ready for display. Hooray - nearly done.

Mastering the master

The master unit is actually the more complicated part of the system. Not because it has any inherent complexity, but really because it's difficult to fit all of the code into the 4096 words of flash memory and 256 bytes of RAM. For anyone familiar with MPLAB X, how many times have you seen your resources so completely used as this?


This is because we need the code for talking to the RF unit, the code for talking to the OLED, the code for interacting with the 23LCV1024 SRAM, various text strings, and also font mappings. Quite a lot to fit in!

Anyway, here's the schematic:


I've put a 3.3V LDO there because I'm powering it from a 5V wall-wart even though it's 3.3V throughout - it's much easier to find spare 5V supplies in the rummage boxes. So, nothing too difficult to see there - the external RAM has a fixed battery (I knew they would come in useful!) to keep its content safe during power off and I've also added a jumper in there to clear the RAM if I want to start again. In the code, it first reads the RAM looking for a magic number to see if it was previously initialised or not. If not, it writes six pages of empty data to the SRAM with the plant names coded from a 5x7 font. So the display is really just mapped to the SRAM and the PIC only needs to write the bars for the incoming data and read back a single page at a time to display.

The populated board looks like so:


Power comes in top left, the PIC is bottom left and the SRAM bottom right. The momentary push switch at top right allows one to cycle through the six houseplants to see the current moisture level and a bar chart history over the last 128 sample periods (only 128 because the OLED is 128 pixels wide).


Seeing is believing ...

So, finally (yes I know I'm rushing), I've made a short video of the master unit in action so you can see the principle. As usual, I'll link to the code downloads at the bottom ...



One thing that may be interesting is what happens to the soil moisture sensor after a few months use. This is what my first sensor looks like now, after something like five months in an indoor plant pot (over-watered, as it happens!):





Source code downloads

As promised!

Plant monitor sensor
Plant monitor master


Wednesday, 17 December 2014

PIC and mix ...

... or maybe PIC and pray!

Well, after my last post regarding the PIC microcontroller, I've got hold of a bunch more PICs (some from eBay, some directly from Microchip) and these include the relatively modest PIC16F648A of which I successfully bid on a tube of 25 for less than twenty quid, which I think is a bargain.

The headline spec is as follows:

  • 7Kb Flash program memory
  • 256 bytes RAM
  • 20MHz maximum speed

It also has 256 bytes of EEPROM, a capture/compare/PWM module, a USART, two comparators and a programmable voltage reference. The 7Kb program memory equates to 4096 instructions - because this PIC has a 14-bit instruction word - and the 20MHz maximum speed really means 5 MIPS because each instruction is executed in 4 clock cycles (20MHz / 4 = 5 MIPS). 

The data sheet notes that this PIC "fits in applications ranging from battery chargers to low power remote sensors". So, I decided to do nothing of the kind .....


The Matrix

Ok, not this one ...


 ... but this, slightly less impressive but definitely cheaper one (this was about 3 quid, delivered) ...
It's spooky that it's sort of the same colour greenish colour, but anyway - I'd bought as a kit to piddle about with on the Arduino. 

It has a single 8x8 matrix of LEDs, driven by a MAX7219 and hooked up to the microcontroller by a simple serial interface. You can address each of the 64 LEDs individually and make all sorts of fun patterns (really?), well that's what the blurb said when I bought it. You can also chain a few of them together, to drive something like a scrolling text display, which is why there is a five-pin header on the right hand side too.

Now driving this with the PIC instead of the Arduino would have been quite trivial. I could even almost copy the Arduino MAX7219 library and port it to C on the PIC. Also, 8x8 wasn't interesting enough and I didn't want to chain them, I wanted maybe a 2x2 block of these matrices, so I'd end up with a 16x16 array - big enough for something "useful" (ahem). Well, it's a learning exercise innit?  

So, off to eBay again, and I picked up a few more LED matrices for about a pound each, and also a small stock of MAX7219's.


Circuit training

Now all I needed was a way to hook four of these together so I could drive the composite array with my PIC. The basic circuit was quite simple - sixteen lines from the MAX7219 to the LED matrix, a current limiting resistor and a couple of capacitors for smoothing and decoupling. Multiply by four, chain the MAX7219's together and you get something like this:



Now, the nice thing about designing this circuit using EAGLE is that it's easy to create a corresponding design for a custom PCB, just by dragging and dropping the components of your circuit onto a bare board layout. Ok, it's not quite that simple, but it's easy enough for a novice like me and I was keen to go through the process of designing a PCB and having it professionally made (which is actually unbelievably cheap, if you're prepared to wait for it to arrive from China).


Board? Me?

So, stumbling through the EAGLE tutorials and gleaning whatever advice I could understand from the Internet, I ended up with a board design like this:



I used EAGLE's auto-routing feature for the track layout - having never done this before and having little confidence that any changes I made would be "better", I just did my best to make it look pretty, exported the files in the generally accepted Gerber format, and sent the whole lot off to ITEAD Studio along with my £19 payment, and waited .....

... OK, I didn't have to wait as long as I thought. Eleven days later, my 10 (yes ten) boards arrived by air mail from China, and even to my unpractised eye, looked very good quality. See what you think :


Top view of the board
Bottom view of the board
Now, with nothing stopping me apart from waiting for the soldering iron to heat up, I got cracking. First, I populated the IC sockets, headers, resistors and caps ...



... and then fitted all four of my LED matrices, one at a time:


One down, three to go
All safely installed, if slightly untidy

Slight deviation

While all of this was going on (i.e. the waiting part), I was busy preparing the PIC for the arrival of the super-matrix. Looking through my boxes of bits, I also found a 16x2 LCD panel, like this:


16x2 LCD panel
And, having nothing better to do, I started off building this into my PIC environment, so I could use it for debugging, if nothing else. Previously I'd been debugging using a logic analyser and a spare PIC pin to trigger collection of crucial signals on the part of the circuit under investigation, but found that there's no real replacement for the ability to dump out some text or some hex to see what's happening inside the PIC. The mid-range PICs I tend to use don't support in-circuit debugging without an external debugging header (which costs money - too much to warrant the expense).

There are numerous examples of driving these LCDs, so I won't repeat the detail here. In summary, I'm driving it in 4-bit mode rather than 8-bit (saves 4 pins) and also doing this via an M74HC595 shift register, which means that - by doubling up on the shift register and LCD enable lines, I only use 4 pins in total from the PIC. I'm trying to save as many as possible to add more stuff later.

So, the final circuit for the PIC was as follows. Note the DIN, CS and CLK outputs that are destined for the 16x16 LED matrix assembly. The remainder is the LCD and its 595 driver, an ICSP header for programming the PIC in circuit, and an external crystal and load caps to get the PIC cranked up to 20 meg. Bottom right is a 10K trimpot to adjust the LCD contrast.




Happy days

Now, putting the whole lot together - with the PIC and LCD on a bit of stripboard, and some hastily written test code, we have lift off! ...




So far so good, but there was still a bit of capacity left on the PIC - I'd only used 50% of the 256 bytes of RAM and about 30% of the program memory. Not bad from the free (non-optimised) XC8 compiler supplied by Microchip. Also, I hadn't really done anything useful with the LED matrix other than flash up a hardcoded smiley.

So, back to the box of bits, and out comes an old (very old) PS/2 mouse. One with a real ball.


The final lap

Finally, with the help of this description of the PS/2 mouse interface, and a couple of my remaining PIC pins, I wired up the mouse and added the code necessary to initialise it and respond to its signals.

I didn't show it on the schematic above, but the mouse connects to the PIC pins RB0 (mouse clock) and RB1 (mouse data). These pins are both used as open collector signals, so I have enabled the internal pull-ups on PORTB rather than use external pull-up resistors. It works well, and seems to be stable, which is all I could hope for.

So, now, at last, from that modest PIC, normally used for battery chargers etc., I'm supporting a 16x2 LCD display via a 595 shift register, a set of four MAX7219's each driving an 8x8 LED matrix, and a PS/2 mouse, that I have programmed to "draw" on the LED matrix. All in all, this would have been the starting point for an innovative arcade game thirty years ago (sigh - feeling old now), but it's taught me a lot - most of all it's taught me how little I still know and how much I'm enjoying this resurrected hobby ....

Take a look at the final video to see everything working together, and if you really feel inclined to do anything like this yourself, download the source code from here.



That's all until I've finished my next "project" - involving some of the more powerful PICs and a couple of (at least) wireless transceivers .... watch this space ....