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 ....

Sunday 26 October 2014

PIC a chip .... any chip .....

Once upon a time ...

So ... after messing around with that optical mouse a few months ago, I inadvertently rekindled my interest in a teenage hobby where, many years ago, I read every issue of Practical Electronics that came my way, bought numerous bits of Veroboard and burnt myself liberally with a cheap and nasty soldering iron, but really did nothing more than build other people's circuits and even then with just a handful of transistors etc. .... all of this digital logic was still quite new (we're talking mid 1970's here) and it was difficult to do anything really interesting without a lot more time and effort than I used to have back then .... not that I have much more now, of course ....

Anyway, since my escapade with the mouse, I've been tinkering and reading and buggering about with a couple more Arduinos, and then, after posting a begging letter on Freecycle for any unwanted electronic components, somebody very kindly gave me, among other stuff, an 8-bit PIC microcontroller - a PIC16F676 to be precise - along with an old PICKit1 evaluation board, and this got me Googling and thinking ....

This was much closer to the metal than the Arduino, and being programmable in C as well as Assembler, felt like much more of a challenge! 


So what did you do next?

What did I do? I'll tell you what I did .....

I took some of the bits I'd been playing with on the Arduino - namely a handful of 8mm addressable RGB LEDs, commonly known as NeoPixels, and I decided to migrate one of the Arduino demo programs to the PIC.

Easy enough, I thought. But not after a closer look and a second thought. Or even a third thought.

These LEDs are really quite a package. Not just any old RGB LED, capable of displaying any of the 16.8 million colours familiar from normal computer displays, but they also contain the circuitry to latch in the last-set colour, so you don't need to keep pumping it with data from the microcontroller. They also have a neat one-wire communication method and can be daisy-chained together so that a single (albeit carefully crafted) pulse of 1's and 0's can set the colour of each LED in the chain and it will stay that way until switched off or told otherwise. So each LED needs only four connections: +5V and GND (to provide the power), the one-wire DATA_IN, and the similar outgoing DATA_OUT which feeds along to the next LED in the chain.

So, a simple daisy-chain of LEDs might be wired up like this (you can actually buy these same NeoPixels already wired on a metre long strip, or a ring, or various other shapes) ...




Hard times

The downside to the handy one-wire interface, though, is the necessity to provide very tightly timed pulses. As there's only a single wire, there is no room for handshaking or any other common protocols. You must adhere to the datasheet specification, or it just won't work (although there is a bit of leeway and others have found that this can be stretched a lot further than first thought).

Most of the mid-range PIC products can be clocked at a maximum of 20MHz by using an external crystal instead of the internal oscillator. With each instruction taking four clock cycles, this gives a minimum instruction time of 200 nanoseconds. The NeoPixel datasheets, with varying degrees of detail, specify that the shortest pulse - for sending a zero rather than a one - is somewhere around 350 nanoseconds (+/- 75ns) so with a couple of assembler instructions on the PIC it's just do-able.



The following code snippet is what I came up with:
It's defined in a macro to avoid cluttering the code as this has to be repeated 8 times for each byte of the RGB data that's sent to the LED chain. I've chosen pin RC2 as the output from the PIC that hooks in to the LED one-wire input, and with the external crystal to run at maximum speed, the PIC is wired up like so:


You can see I've added an ICSP header for programming the PIC in-circuit, so I don't have to keep pulling it out of the board every time I make a change, and there's a bypass capacitor across the power inputs to suppress noise. Ignore the ADC, SDA and SCL pins for the moment, we'll come on to those soon.

I have 20 LEDs in my chain (because that's all I bought) and, as they can draw a maximum of around 60mA each when fully illuminated, they will need to have a suitable power supply,  capable of supplying at least 1.2A (mine is actually rated at 2.5A, which is comfortably larger). Referring back to the LED circuit above, you'll also see a 1000uF capacitor across the power rails and a small series resistor for noise suppression as recommended by the LED datasheet.If you try to do this yourself, read the datasheet carefully, keep the power at 5V or lower (the LEDs have been reported to explode at 6V) and definitely add that 1000uF capacitor to avoid blowing your first LED at power-on. 

You can see that I also added a handful of smaller bypass capacitors and an inline filter to keep noise to a minimum but these are possibly overkill. [UPDATE] I've now removed the inline filter and replaced it with an LT1086-5 voltage regulator and now take power for everything from this (it will supply up to 1.5A at 5V) so the schematic has been updated in the download.

Board (bored?)

On the image below, you can see the positioning of the PIC - notice I've used a different chip here, the PIC16F684 because the '676 doesn't have quite enough memory - and you can see the LEDs, which are wired in a boustrophodon pattern (Google it), all marked in yellow. You can see the LED power also marked, coming in from the middle left. The PIC and related circuitry has a separate power supply in this picture, which at that time came from my computer's USB (with grounds common). There is now a single regulated 5V supply (see update above).




So, having got this far, it's useful to make sure that the code for driving the LEDs is performing in spec. Hooking up a logic analyser to pin RC2 on the PIC, and temporarily hacking the code to make it send alternate bytes of just zeros and ones (so each byte is either 0x00 or 0xFF), you can see that the timing is pretty much ok:


A section of a set of "zero" pulses
A section of a set of "one" pulses
And indeed, by setting the LEDs to some identifiable colours, like pure Red, Green and Blue, I could see that this part of the code worked fine. Which was nice.


"Like the corners of my mind ..."

Nice, but not very interesting. The Arduino NeoPixel examples have some nice colour-chasing effects and it would be good to replicate this on the PIC.

The Arduino does this on the fly, calculating a new set of colours based on the elapsed time and the previous set of colours. Not so hard to do in C or C++, with floating point math support, but a different kettle of fish altogether using assembler on an 8-bit PIC.

So, cunning plan #1, why not use the Arduino code to generate a suitable set of data and then just hardcode that into the PIC? 

Well, here's why not...

The Arduino is relatively well endowed when it comes to memory (the Uno has 2K), but the PIC16F684 only has 128 bytes (yes, bytes), and, given that I need 60 bytes (20 LEDs x 3 bytes RGB) for just a single set of colours, it limits the options somewhat. My first PIC, the 16F676 only has 64 bytes, which makes it totally impractical, but 128 bytes is still, well, not much.

Cunning plan #2 - add some more memory! Ok, more obvious than cunning, but at least another chance to learn a bit more and get some more interesting functionality into this putative project.

Microchip also makes a range of Serial EEPROM chips, like the 24LC64, which provides 8K bytes (64K bits) of additional memory.That's enough for about 130 frames of data for my 20 LEDs, and the memory itself is very cheap (I bought 10 of these from eBay for £3.64 including postage). It talks to the PIC using I2C, so only takes up two more I/O pins, one for clock (SCL) and one for data (SDA). 

So this part of the picture goes like so:


Referring to the earlier schematic, you can see that the SCL and SDA connections hook up to pins RC1 and RC0 on the PIC.

It was easy enough to adapt the Arduino NeoPixel code and make it write 136 frames of colour data to the EEPROM instead of driving the the LEDs directly. Then all that's needed is to pop the EEPROM into the PIC circuit instead and write the code to read from it.


Mindreader

Some PICs have hardware support for I2C, but unfortunately, the 16F684 doesn't. However, Microchip have an Application Note - AN974 - that describes how to implement I2C in software to interface to a Serial EEPROM, which is just about perfect! 

All I needed to do was to adapt the example code for the EEPROM I used (this needs two bytes for the address rather than one), change the timing code to match my 20MHz clock and to run I2C at the faster rate of 400kHz, and put in the necessary infrastructure to load any of the 136 frames of data (each 60 bytes) into the PIC's memory to drive the LEDs.

Here's a very low quality snapshot of this part of the functionality in action - the colours don't get caught well on camera, so it's not (quite) as disappointing as it looks:



You can see the Serial EEPROM outlined in yellow, and it's associated bypass capacitor just partially obscured by the top left LED.


So far so good...

... but not quite good enough.

So, trying to squeeze even more functionality out of the PIC, and noting that it has an ADC (analog to digital converter), and remembering even further back to when my mate Chris and I ran a disco when we were still at school, I thought I'd try to get some sound-and-light effects going.

At first, I didn't quite know how I was going to make this happen, but I did know that it would be possible to get some audio input from a cheap and cheerful microphone into the PIC via ADC and then do "something" with it in the software. That "something" would occur to me later, but for now, the final part of the circuit you can see at the bottom left of the board is this:
On the left is an electret microphone capsule, which needs to be powered in order to work (it contains a small pre-amp), the output of which is passed into an LM358 op-amp, configured in inverting mode.

There's a 2.5V DC bias on the non-inverting op-amp input, to keep the signal from going negative (the ADC can't handle that) and the gain is set (experimentally) so that the output has a range of approximately 4V peak-to-peak.


Say what?

Ok, the audio input hooks into pin RC3 on the PIC, which is configured as an analog input (AN7). The ADC is 10-bit, which means a maximum range of 0 to 1023, so this maps my ~4Vpp to a range of around 0 to 800.

Throwing away the two least significant bits gives me an 8-bit value in the range 0 to 200, which I can use to do that "something" I mentioned earlier.

The 0-200 number I end up with is just a very rough measure of the ambient noise level at an instant in time (well not an instant, but a very short period anyway), so it's not going to behave like a true peak detector from a sample-and-hold circuit, but it's possible to simulate the same sort of response in software. In pseudo-code, it goes something like this:

  1. Read the audio level from the ADC.
  2. If the level is greater than the current peak, store it in the current peak. 
  3. Otherwise, decay the current peak by a small percentage.

This means that the peak will react quickly to increases in overall noise, but will decay more slowly if/when the noise level drops. This helps to average out the artefacts caused by sampling an alternating signal and in practice follows a sound quite well.

To avoid messing around with calculating percentages for decaying the current peak, I used more experimentation time to figure out that decaying by about 1% or 2% of the current value worked well with my overall time scheme. So, with my audio level ranging between 0 and 200, it was easy enough to hardcode this bit of logic to avoid unnecessary coding of 8-bit division:

  1. If the peak is greater than 140, decay by 3
  2. Else, if the peak is greater than 70, decay by 2
  3. Else, if the peak is non-zero, decay by 1

Seems simple, and it is, but works well and only takes a handful of lines of assembler code:


Don't worry about these short code example. If you're really interested, you can download the whole source code at the end of this post.


Nice but dim

Now, having got a number that sort of correctly follows the average sound level, I decided that the only "something" I could do with it was to use it to adjust the brightness level of the LEDs. So, the colours would stay the same as read from EEPROM, they would just be scaled down a bit dimmer when there is a low sound level.

However, this required a bit of additional coding to get things happening at the correct time. There's no point reading the EEPROM and updating the LED colours too fast, because it doesn't look good and makes you feel sick. But, we do need to react to changes in sound level quickly or the whole thing will lag behind the live sound and that also won't be good.

Therefore, I've used one of the PIC's inbuilt timer modules to flag when it's time to read a new frame of RGB data from the EEPROM. I've set this so that the colours change about 9 to 10 times a second. When I've read all 136 frames, the code just goes into reverse and reads backwards to frame zero again, and so ad infinitum.

So, what happens when the colours are not changing is that the audio level is determined as already described, then the current frame of colour data is re-read from EEPROM and then adjusted in brightness according to the audio level before being sent to the LEDs. In simplified terms, like this:
Note that it's necessary to re-read the EEPROM, even if the frame number didn't change, because we don't have enough memory to store the un-dimmed version we last read and we want to re-dim it to a new value based on the latest audio level. If we had more SRAM on the PIC we could keep a second copy of the RGB data and avoid accessing the EEPROM more frequently than the 9-10fps required. But we don't, so we can't.


The final curtain...

Right, that's enough explanation, you probably want to know what it looks like. Me too. It's just a shame that this sort of thing is very difficult to capture with video - colours are not good, focus shifts as brightness changes, etc. etc. but just so you get the feeling for it, here is version zero of my Totally Pointless Toy (TPT v0) ....



One other effect I tried was to take an idea from this project, that simulates a fire effect using an 8x8 matrix of RGB LEDs. It's easy enough to just use the Arduino to write whatever I want to the Serial EEPROM and then just plug it back into my circuit. So, 136 frames of simulated fire later, this is the result ...




Source code

Right, that's all for this post - I certainly enjoyed myself and learned a heck of a lot in the process. If you want the source code and a copy of the whole schematic, you can download it from here.


[Update]

After making some small changes, the board layout now looks as shown below, with an LT1086 5V 1.5A LDO voltage regulator supplying the whole circuit. This is a lot cleaner and just requires a single wall-wart power supply, which I robbed from an old Netgear router.





Monday 16 June 2014

Seeing double ...... triple?

As I mentioned in another blog post, the ImageMerge software that I've been developing proved to be enormous fun during testing.

Not having an endless supply of images to merge, I came up with a simple plan to test the merging part of the software (rather than the registration). So I set up the camera on a tripod, placed in the lounge in a suitable position, and - using the self-timer - took pictures from identical viewpoints but with different content.

The "different content" in this case being me.

The very first attempt used three source images, so I merged two of them first and then merged the third with the result of the first step. One of the images was slightly out of focus, so I wasn't too happy with the result, but it did lead on to some more experiments.

Anyway, for the sake of posterity, the first "triplet" image, started with these three images:





The resulting merged image came out like so:




Could do better ...

Now, given that I'd not only posed myself in different positions, but also tried out different facial expressions (if you can call them that!) to try to show three different characters, it started me thinking....

Getting carried away, I then came up with this ....



... and this ...



... which, after two more merges, turned into this .....




Like father like son ....

Seeing some of the hilarity these produced when posted on Facebook, my dearest son couldn't wait to get involved and so we tried one (two?) of him indoors ....



... and one (three?) of him in the garden .....



.... which is enough frivolity for now, so back to some real work soon ......

Wednesday 4 June 2014

Windows on history

Did you ever see ...

This excellent blog post that displays how Russian photographer Sergey Larenkov uses Photoshop to merge old and new photos to produce some really compelling images that help to bring history alive?

Well, it got me wondering how tricky it must be to get exactly the right point from which to take the modern version of the photo, not knowing exactly where the original photographer was standing, what lens he used, what focal length, zoom etc. So it's actually quite difficult to get two suitable images for merging..... even if you can afford Photoshop (I can't) ....

So, given that writing software in general, and image processing in particular are what I do in my day job, I knocked up a - hopefully - simple-to-use application that not only corrects for slight differences in perspective, but also rescales images as necessary and provides an easy way to do the merging. As an example, taking a historical picture from the online archives of my home village ...



... together with the present day equivalent, taken by yours truly on a cold Sunday morning ....



... I was easily able to produce this merged composite ....



... which is not a bad result, if I say so myself.


Go on then, give us the software ....

Ok, if you have Windows 7 or Windows 8, or 8.1, you can download the installer from here and give it a bash. No guarantees, no warranty, etc. this is all an alpha release and subject to bugs, problems, incompatibilities, whatever, but if you want it, here's how you do it, using the above images as an example ...


Image merging the easy way ...

First off, you need at least two images. I say "at least" because you can merge multiple times and have an infinite number of them, but you can't have less than two. You just can't.

The images should be of the same scene, and should be taken from roughly the same position but do not need to be the same size or format, the program will take care of resizing and mapping one image onto the other to make it easier to merge them together. 

So, when you start the application, it looks something like this ...




The user interface is similar to Microsoft Office, with a ribbon at the top and some shortcut options for loading, saving etc. at the top left. Everything is controlled by the ribbon options, moving from left to right. Different options will be enabled/disabled as you proceed, so you really can't do anything inappropriate. Well, not with this software anyway ...

So basically, you follow these steps:
  • Load two images – using the “Select images” panel on the ribbon
  • Mark corresponding points – using the “Mark and merge images” panel
  • Paint areas where you want the secondary image to show through – using the “Composite image” panel
  • Finally, adjust the blur and save the result – using the “Save results” panel
These steps are described in detail next ....

Select the images


The images are arbitrarily called “primary” and “secondary”. The primary image is the one that the bulk of the content is expected to come from and will form the basis of the final result. The secondary image is the one from which selected areas will be merged into the primary image.


So, click the Primary and Secondary buttons - in any order - to load two images ...

You can pan and zoom each image and can adjust the vertical splitter bar to adjust how much of each image you see. Use the mouse scroll-wheel to zoom in or out and just click and drag with the left mouse button to pan the images. Each image can be panned/zoomed independently.

The next step is to mark a number of reference points on each image so that they can be correctly registered. Moving on …

Mark and merge

On either of the images, find a suitable reference point, such as a corner of a door or window frame, that you will be able to locate fairly accurately on the other image. Zoom in to get more accuracy and then right-click once with the mouse to mark a green spot at that location.

As you do so, a corresponding marker will be added to the other image in an approximately similar position. It’s not always easy to see, so you may need to zoom in or out to find it. 

When you’ve found the marker that was added to the other image, left-click and drag on the marker itself to move it to the exact position that corresponds to the reference point you chose in the first image. Get it?

Repeat this process until you have a reasonable number of marker pairs that are arranged over significant parts of the image. For example ...


If you left-click on a marker in one image, it turns to solid green and the corresponding marker in the other image also turns solid so you can see which ones match. 

If you have clicked a marker, you can use the Remove option from the ribbon to delete that marker pair from both images, or you can click Clear to remove all markers if you want to start again, and if the green colour is not visible enough, you can select a different colour using the Colour option.

Note that it's important that the marker points should identify medium-to-large, flat, two-dimensional areas, such as walls, doors, windows, signposts, etc. and should not all be in a single line. If they are, or if you don't have enough points, the next step might look a bit weird. No, it will look a bit weird ....

So, when you have marked at least 4 points (but ideally 7 to 10 - the more the merrier), click the Merge button on the ribbon to move to the next step...

The composite image ...

If everything went ok, you should see a composite image with a nice pink glow. This will be the primary image but with the secondary image – correctly positioned and sized – showing as a cross-faded ghost. 

If this is not happening, in other words, it does look weird, then as I said above, you probably didn’t choose enough good marker pairs in the previous step. In which case, click Undo Merge to return to the previous step and either adjust your marker positions or add some additional ones to get a better registration.

Using the images above, the following screenshot shows the sort of thing to expect. You can see that the primary image is unchanged (apart from looking pink!) but that the secondary image has been distorted – technically, it’s undergone a perspective warp – and scaled (stretched or shrunk) so that the reference points you marked are as near as possible coincident with those in the primary image. Use the Adjust crossfade slider to fade between the two images to check the registration ...

Now what you do, is to right-click and drag with the mouse to “paint” the areas of the composite image where you want the secondary image to show through. 

These areas will be shown in green as in the example below ...


To paint finer detail, just zoom in before painting – the size of the paintbrush doesn’t change, so the thickness of the brush depends on your zoom level. This is much easier (in my humble opinion) than having to select a particular brush size.

If you mistakenly paint some green areas where you didn’t want to, click the Erase button on the ribbon and then right-click and paint again to return to the pink colour. Click Paint to get back to normal.

After you’ve finished painting the areas you want merged, click Show Result ….

Nearly done ...

At this stage, the primary image will be merged with the warped secondary image in those places you have painted. It should look ok, but maybe not perfect.

By default, the areas will be blurred so that there is a smoother transition, which makes it easier on the eye if the images are not similar colours (as in the above example). This means you might want to paint bigger areas and let the blur fade nicely...


... alternatively, use the slider on the ribbon to adjust the blur radius until you get the visual effect you want. If you mess up, just click Undo Result to return to the previous step and adjust your painted areas.

When you are finally happy, click Save Result to save the final image. Note that you must click the large Save Result button on the ribbon – this is different to the small save at the top left, which saves details of the image filenames, marker positions and painted areas, so you can quickly load a marked and painted pair for editing later.

Ok, enough typing – get playing and see what happens. You have already seen one of my ideas – current and historic photos - but you can also experiment with identical scenes but with different people (I'll post some of my triplets later!), or maybe the same scene at different times of the day, or different times of the year, etc.

See what you think ..... it kept me amused ....

Tuesday 3 June 2014

Hacking an optical mouse

Have you ever wondered ...

... how a mouse works?

I don't mean the real old fashioned kind, with proper balls and stuff, but an optical mouse or even a laser mouse (similar to optical but higher precision).

Well, I did. ... Wondered, that is ....

So, after Googling around for a bit and finding a number of hacks (like this one or this one or several others), I decided to have a go myself. Which is why I engineered an early exit from work on a Friday afternoon that resulted in me scuttling into Maplin to pick up an Arduino Uno for the best part of twenty-five quid (yes, I know they're cheaper online, but I'm not such a patient hacker) .... and on Saturday morning, I hunted in various boxes to find a sacrificial mouse ... this one .... (as with all the images, click to see a larger version in a new window)

Sacrificial mouse
Sacrificial mouse
Removing the single screw under the QC label gets the top off the mouse to reveal the relatively simple circuit inside. If you click to the full size view, you can see I've marked the LED assembly, the optical sensor - in this case a Unity MCS-12085 (just Google the numbers on the chip!) - a microcontroller (MX84510, but that's irrelevant 'cos we don't need it), the micro-switches for the mouse buttons and four wires heading off to the PS/2 plug at the computer end. I removed the scroll wheel temporarily to avoid dropping it repeatedly, which was annoying me after the seventh or eighth time ....
Top view before
Top view (before hacking)
After finding the datasheet for the MCS12085 optical sensor, to identify the pin-outs, it's easy enough to flip the circuit board over and find the four little beauties that are apparently the only ones we need to hack into the sensor itself. I didn't figure this out myself - I have to give credit to the earlier hackers, who already described the principle .... but anyway, let's press on ...

The four pins we need are two for power - GND and VDD (+5V) - the clock - marked SCK - and the serial input/output marked SDIO. Take a look at these on the image below and also note the connections to the existing PS/2 cable that I've highlighted in a yellow rectangle ...

Bottom view 1
Bottom view showing 4 pin-outs and PS/2 cable
Now if, like me, you're a lazy sort of bugger that can't be bother to hacksaw the PCB or drill holes into the copper tracks, like some of the other guys did, then you might sit and scratch your head for a bit and idly eyeball (visually trace) the existing connections to see where the four pins end up. This proves useful ...

The power and ground (VDD and GND) predictably end up at the outermost two wires of the PS/2 cable (because that's how the mouse is powered, after all), and the clock and data pins (SCK and SDIO) head off to the microcontroller - which normally drives the sensor and then outputs the processed PS/2 signals back to the 'pooter.

This is actually good news, because we don't need the microcontroller at all, and can remove it from the circuit and hook things up however we like.

So - in the image below - notice that two output pins from the right of the microcontroller connect to the remaining two wires in the PS/2 cable - the two between the marked VDD and GND inputs .... you see where I'm going with this?

Bottom view 2
Cunning plan forming ...
Well, what I'm thinking is that, with the controller chip gone, we just need to link the PCB tracks as shown below in red to get our four needed connections handily wired up to the existing PS/2 cable, with minimal need to physically fart around too much. Cool eh?

Bottom view 3
Cunning plan confirmed
So that's what I did.

I fired up the soldering iron, removed the microcontroller chip, and soldered links in to the PCB at the locations marked in red above. After doing this, the top view of the hacked mouse now looks like this ...

Top view after
Top view (after hacking)
Now just screw the cover back on the mouse and, to all intents and purposes, it doesn't look any different to when I started.

Except of course for the necessity to cut off the PS/2 plug and hook up the four wires to my Arduino. Something like this ...

Arduino
Arduino hooked up to the mouse sensor

The VDD and GND from the mouse go to +5V and GND on the Arduino, and I've arbitrarily chosen to wire the serial IO to digital pin 7 and the clock to digital pin 4.

Now breathe a big sigh of relief, because from now on it's all software, with which I'm much more familiar ...

... and after a bit of tinkering, I produced this Arduino sketch (click to download the source code) that provides a simple interface to the mouse sensor by typing commands in the Arduino Serial Port Monitor. Take a look at the code and you'll see what I mean - you can force the LED to be permanently awake (necessary to get a good image), switch it back to normal mode (where it will sleep after 1.5 seconds of no movement), and dump the 18 x 18 grid of pixel values to check that we get some kind of realistic data. Note that the pixel values are all in the range 0 to 63 because two bits of each 8-bit pixel are used to indicate data validity and start of frame - refer to the datasheet for the gory details.

Now, almost (but not quite) the final picture - here is the mouse attached to the Arduino, and all that's needed is to plug the Arduino into the USB port of the computer and try to get some output ....

Breadboard
Just add USB cable ...

... and here's a dump (if you see what I mean) from the Arduino Serial Monitor, in which you can "see" the pixel data returned by the mouse sensor ...

Pixel dump
Pixel values dumped as text

Now, looking at grids of numbers is not really why we started this, so I adapted the original Arduino sketch to provide a simple - but much faster - streaming output, which I then hooked into a C++ application to display the (rescaled) pixels as a grayscale image. You can download the streaming version of the sketch here, but I'm going to hold off on releasing the source code for the viewer for a bit because I have some more cunning plans for it in a later blog post ..... this could get interesting ....

For now, here's a snapshot of a single frame as seen by my sacrificial mouse as it glides effortlessly over an (unpaid) credit card statement ......

Pixel display

I'll post again soon with more .......... hope this was useful ....