Recently, Cypress released a new range of processors, the PSoC 4, and a new development kit for them, the Pioneer. The PSoC 4 is Cypress’s new line of low power configurable microprocessors. They’re based on the Arm Cortex M0 architecture, and have much more basic analog and digital capabilities than the 3 and 5, but still retain the PSoC’s incredible reconfigurability. The pioneer is an Arduino clone based on the PSoC 4 processor; it’s got onboard program and debug capabilities using an onboard PSoC 5(!) configured for interactive debugging. The whole board sells for $30 US.
A lot of people have been asking me about the Loki and my plans for it, especially in view of the release of the Pioneer. This is something I’ve been giving a lot of thought to. The Pioneer has a lot of advantages - it’s made by Cypress, it’s at a price point I can’t match with the Loki, and it has onboard debugging, something I wasn’t able to build into the Loki at a reasonable price. Whilst the Pioneer lacks Loki’s very cool and flexible expansion system, it’s able to take advantage of the entire ecosystem of existing Arduino shields out there.
Loki could still have a very viable niche as a ‘big brother’ to the Pioneer, since the PSoC 5 is so much more capable than the 4. I’m considering releasing it with this in mind - possibly redesigned to fit an Arduino Mega / Due form factor to take best advantage of the Arduino ecosystem and to provide a simple upgrade path. Sadly, this would mean giving up on the Loki’s expansion system and the flexibility that grants.
In the short term, however, I’ve decided to put Loki on hold while I see how the Pioneer pans out, and to give me time to work on other projects. Keep an eye out for more progress in a little while. In the meantime, though, I do have another very cool project that uses the PSoC 5 in the pipeline - expect an announcement on that in the next few days!
While minimatrix is in principle a pretty simple device, there’s a surprising amount of detail that goes into getting it right - and some interesting lessons to be learned in designing and programming it. I thought I’d detail a few of them for the benefit of anyone building something similar - or simply for interest.
Here’s the complete minimatrix schematic:
As you can see, it’s fairly straightforward. The LED matrix is driven directly by the attiny; other than that we only have the IR receiver and button - which use the same GPIO pin - and the battery. The microcontroller is an ATTiny4313, which has - just barely - enough GPIO pins to drive the matrix.
There’s good reasons for assigning the pins the way they are here - and we’ll get into them a bit more in the section on driving the matrix, below.
PCB layout is also fairly simple, though we have a serious lack of space on something so small. A double sided approach is necessary, and has the added advantage of looking awesome.
The back of the board - the part that faces out when soldered to a matrix - has all thru-hole parts: the battery holder, IR receiver, and button. The front of the board is all surface mount, and has the microcontroller, resistor arrays, and a couple of decoupling capacitors. The nice thing about this is that once everything’s soldered together, the microcontroller is entirely hidden from view - all you see is a neatly packaged device with battery, button, and display.
There’s a lot of choice out there when it comes to picking LED matrixes, and unfortunately the choice doesn’t stop at form factor and capabilities. There’s absolutely no standard pinout for LED matrices, and few if any of the pinouts make any logical sense, either. Here’s a couple:
While the first one makes marginally more sense, neither is what I’d call a logical arrangement of pins. Fortunately minimatrix only has to care about monocolor LED matrixes, because when you get to bicolor and full color ones, the number of available pinouts explodes exponentially.
Single color LED matrixes come in what is commonly referred to as “common anode” and “common cathode” versions. In a single-color matrix, this notation doesn’t make a lot of sense, so it’s easier to think of it by considering whether rows are anodes or cathodes. It’s unimportant which you choose for a single color matrix, but for multi-color ones, common anode is often easier, since it’s easier to do high powered low-side switching than it is to do high-side switching.
Driving the matrix
The basic approach to driving an LED matrix like this is well known and not terribly complicated. You scan over rows, and for each one you power the appropriate columns that should be lit for that row, sourcing your data from some sort of frame buffer. This is most easily done inside a timer interrupt; realistically in order to get a nice flicker free display you need to scan the rows around 50 times a second or more; I went with 100, meaning your timer interrupt needs to fire 800 times a second to scan all the rows. Not terribly difficult, even for a low powered MCU like the ATTiny range.
One significant refinement is in the way pins are allocated, as I alluded to above. Note from the schematic that all the columns are driven - in order - from a single port, port B. This is the only port on the ATTiny4313 that has a full 8 pins. Doing things this way has a major advantage when it comes to the speed and efficiency of our code to write data to the display. Instead of having to individually set each bit, we can write an entire column with a single operation by copying straight from our frame buffer to the port. Here’s the core of our timer interrupt routine:
static uint8_t row = 0;
// Turn off the old row
PORTD |= PORTD_ROWS;
PORTA |= PORTA_ROWS;
// Set the column data
row = (row + 1) & 0x7;
PORTB = display[row];
// Turn on the new row
As you can see, this is extremely straightforward, and quick to execute. All we do is set the appropriate row bit, increment the row counter, and output the data for that row to port B.
Done? Not quite. Check out this photograph of the minimatrix in action:
Notice how the columns with fewer LEDs on are brighter than the columns with more? That shouldn’t be the case, and at first glance it’s not obvious why it would happen. Check out this chart from the datasheet, though:
That’s showing the voltage on a pin that’s being pulled low, relative to the amount of current it’s sinking. As you can see, the more current it’s sinking, the higher the voltage - consistent with the pin having a nonzero resistance to ground. If we’re sinking 10 milliamps at room temperature, the voltage on the pin will be about 0.3 volts. Since our supply voltage is only 3 volts, and the forward voltage drop on our LEDs is about 2 volts, that means our LED just got about 30% dimmer!
The solution to this is reasonably straightforward. Instead of setting a single timer interrupt for display refresh, we set two. The first turns the LEDs on as above. Then, it calculates a delay based on the number of lit LEDs in the column, and sets the delay until the second timer interrupt accordingly. This second timer interrupt turns the LEDs off - effectively, dimming the display so that all rows are the same brightness as one with all its LEDs lit. This is perhaps the only practical use I’ve ever encountered for all those bit manipulation hacks for counting set bits
Before settling on IR, I experimented with a couple of options for allowing users to program messages and animations into the minimatrix. One I spent a lot of time on was programming using computer monitors and light detectors, like these projects did. It’s not even necessary to add light sensors, since the LED matrix can be used for that purpose.
Sensing light using an LED is pretty simple. Reverse bias the LED - set the cathode high and the anode low - then stop driving one of them and wait to see how long it takes it to change state. The more light is shining on the LED, the faster the anode will go high (or the cathode, low). If all you care about is a digital threshold, you can pick a delay that distinguishes the two light levels you care about, wait that long, and then do a single check.
In principle, the LED matrix can be used the same way. It even ought to be possible to have an entire matrix of sensors, by selectively reverse biasing rows and then testing columns, or vice versa. In practice, I had a lot of issues with this causing what appeared to be crosstalk - both electrical and optical - between rows and columns. I was able to use entire rows as a single sensor with some degree of reliability, but that was about it.
A further problem with this approach is speed. For light levels emitted by a typical computer monitor, you need to wait between about 5 and 20 milliseconds for each sense, which gives you a realistic upper bitrate of about 50 bits per second - less than spectacular. You can attempt to use multiple channels, but then you run into the crosstalk issues I alluded to above.
Given the low bitrate, reliability, and crosstalk issues, I decided to move on. Fortunately, IR is a whole different ballgame.
There’s a number of IR encoding schemes for remote controls out there. Some of the more popular ones are RC-5, NEC and Sony SIRC. All of them use on-off keying with a carrier wave in the range of 36-40KHz - most commonly 38KHz. What this means is that they emit a series of pulses at 38KHz for ‘on’, and no pulses for ‘off’. This is easily detected and decoded by common IR receiver components, so the signal the microcontroller gets is a logic low when a carrier wave is present, and a logic high when it isn’t.
The protocol used by the remote controls I’m using, and the one I decided to go with, is RC-5. This is a fairly straightforward protocol. Each message is 14 bits long, consisting of a start bit, a ‘field’ bit, a ‘toggle’ bit, a 5 bit device address, and a 6 bit command. There’s no checksumming or error correction.
All of this data is transmitted using manchester encoding. Manchester encoding works by splitting each bit up into two half-bits. A 0 is represented by the sequence 10, while a 1 is represented by the sequence 01. The purpose of this is to ensure regular transitions in the data stream, which makes it practical for the receiver and transmitter to stay in sync with each other.
While manchester encoding’s very simple in principle, figuring out the best way to decode it took me an embarrassingly long time. Using an interrupt or polling based system, each time the signal goes from 1 to 0 or 0 to 1, you know how long it’s been since the last transition - but how do you extract the datastream from that? I’d recommend stopping and thinking about the problem before you read on - see if you arrive at the same solution I did!
The important insight with manchester encoding is that there is a transition in the middle of every bit. If the transition is high to low, the bit being transmitted is a 0, if the transition is low to high, the bit being transmitted is a 1. All we have to do now is identify which transitions are in the middle of bits (the ones we care about) and which are between bits (which we can discard).
Fortunately, this is really easy to do. Since we’re already timing the interval since the last transition, simply check that when we get a transition. If it’s about half a bit interval - 889 microseconds in the case of RC5 - ignore the transition, and keep counting, since we know it’s an inter-bit transition. Any other transitions are logically those corresponding to bits, and we simply observe the direction of the transition to decode the data. Simple!
In the current minimatrix firmware, this is done with a timer interrupt, but with the new schematic and PCB, this can be done with an interrupt - which has the additional benefit of making it possible to wake the minimatrix up from power down mode with IR commands.
Another challenge in building LED matrix displays is how to display text. Typically a bitmap font is used for this, with a common size being 7x5 pixels. The font can be stored as constant data in a C file and compiled straight into the firmware. There aren’t a great deal of good options out there, and the best one I found is Adafruit’s glcdfont. This is a 7x5 bitmap font, represented as 5 bytes for each glyph; each byte corresponds to a column, which lines up very conveniently with minimatrix’s column addressing. Thus, when handling text, each time we need to scroll a new column into view, we look up the relevant column of the current glyph in the font array, and simply write that byte to the frame buffer. Simple, and quick.
Currently, minimatrix embeds the entire glcdfont in firmware, all 256 glyphs. This uses up a fair chunk of flash - 1280 bytes out of the 4k available - so it’s distinctly possible that it’ll be cut down to just the 128 or even 96 most useful glyphs in future, as we try to cram more features in.
Another alternative is a proportional font, which has a couple of advantages. It looks substantially nicer, since ‘i’ and ‘l’ and so forth no longer take up the same with as ‘m’ and ‘w’. It also allows for having ‘dingbat’ or ‘icon’ glyphs in the font which are wider than a typical glyph, up to the full 8 columns. There’s two main disadvantages: First, it will require more memory, not less, to store the indexing information required to look up variable width characters. Second, I haven’t been able to find any variable width bitmap fonts! This is why one of the stretch goals for the minimatrix fundraiser is to commission such a font, and open-source it, which I believe will be a benefit to anyone wanting to do this sort of text display.
Also, if anyone has any ingenious ideas on how to represent a proportional font in as little memory as possible, I’d be very keen to hear them.
Storing and displaying animations
Minimatrix’s approach to storing and displaying data is straightforward. Text and animations are stored in EEPROM, of which the 4313 has 256 bytes. The first few bytes are a header, specifying what type of data it is, and other important information, like the scroll speed or frame rate, and the number of frames in the case of animations. 256 bytes is enough for about 248 characters of text data, or 31 frames of (uncompressed) animation.
Currently, minimatrix has two graphics and storage modes: marquee text, and raw framebuffer animation. A tool is provided in the github repository to convert 8x8 2 bit gifs into the format used for animation. I’d like to implement more graphics modes, and contributions from others along these lines are very welcome.
Contribute and get a free minimatrix
I’d very much like to see contributions from others to the minimatrix firmware. Send a pull request to the github repository with a feature, bugfix or enhancement, and I’ll send you a free one in the mail. Easy!
Of course, Minimatrix is open source hardware, and the firmware is open source too. Check it out in the github repository.
I’m currently running a fundraiser for minimatrix on Tindie, and you can get one for just $12.50 with an IR remote, or $10 without. The LED matrix manufacturer has a high minimum order quantity, so I’m hoping there’s enough interest to justify doing a run of them.
Busy week this week, but little progress on things that seem important.
I bought a label printer to simplify the process of shipping out orders. Combined with Tindie’s new CSV export option, I can now take a bunch of orders and automatically generate and print labels; the labels have a datamatrix in the corner that when scanned with my phone sends my browser to the relevant order page, so I can see what to pack and click ‘shipped’ when I’m done. Automation!
Incidentally, the label printer, a Brother QL-700, turns out to be really excellent. It uses label rolls in simple plastic caddies, which when inserted identify themselves to the printer by a simple punched-hole-and-switch system. Threading the labels into the printer is simplicity itself, making changing label types really easy. On top of that, it shows up as a standard printer. It also exposes a USB drive with a ‘lite’ version of their software, or you can download a much more capable package from Brother’s site. To my great surprise, the label software is actually pretty decent, with sophisticated layout and mail-merge options built right in. The only major problem I’ve been able to identify so far is poor unicode support. I wrote a simple Python script to read and munge Tindie’s CSV files into a format more suitable for a mail merge.
All the parts for the Re:load have arrived by now barring the PCBs and some extra thermal paste for the unexpected surge in orders. Both have shipped from China, and should be with me soon; once they arrive I can start shipping, at which point all my automation becomes truly useful. I spent a few hours on the weekend and Monday packing kits; I think it takes me a little over 1 minute per kit all up, including sticking labels and packing the bags with parts. I’ve done 100, and will do the rest soon. It’s curiously calming, though also prone to giving one RSI.
I continue to fight with the CNC shop to get the rest of the tooling blocks done. They swear they’ll call me tomorrow with good news. Fingers crossed.
I finally plugged in the Loki Sound Plank and gave it a simple test run. As hoped, it works perfectly, at least the bits I’ve tested so far. Ideas for a sample that shows it off are appreciated.
When I chose Cypress’s PSoC processors as the platform for Loki, one of my concerns was to make sure that Loki’s hardware and software design were as open and free as possible. Requiring binary distributions or closed licenses wasn’t acceptable to me, as I suspect it wouldn’t be to a lot of the maker community. Mostly, this is up to me, but in some areas it was a little tougher.
Cypress has an excellent IDE for the PSoC 3 and 5, PSoC creator. It’s generally very nice to work with, and it’s free - but free as in beer, not free as in freedom. Again, this isn’t normally an issue - they impose no restrictions on how you can redistribute source you author with the tools - but the license that’s applied to the API and components that come with PSoC creator does not permit redistribution of source, only of compiled binaries. I wanted to use the built in PSoC bootloader component for Loki, and I wanted to make changes to it, but I couldn’t do so as long as it was licensed in a way that meant I would not be able to release the source for my amendments.
Before I went down the long road of writing my own bootloader from scratch, I decided to get in touch with Cypress to see if they would be prepared to do anything. I dropped them a line, and was very pleasantly surprised to hear back shortly afterwards from someone on Cypress’s legal team. We had a very cordial discussion where he made sure he understood my needs and requirements, went off to consult with the engineers, then came back to say that yes, they would be happy to relicense the bootloader component under an OSS license; would the BSD license do? Yes, it would do very nicely. The only additional requirement they added is that it not be called “Bootloader”, so as to prevent confusion with the official component.
As a result, I’m delighted to present Freebooter, an OSS fork of the official Cypress bootloader component, relicensed under the BSD license. I’m certain this will be of great interest and use to the maker community and anyone building OSS projects based on the PSoC; I hope we can build a community to improve and enhance the bootloader beyond the excellent starting point Cypress has provided.
In my ideal world, Cypress would have already licensed their entire SDK under the BSD license. But I’m seriously impressed with their response to my request, and what it implies of their engineering and management culture. I think it bodes well for Cypress’s interactions with the OSS, OSHW and hobbyist community in future that they were prepared to listen and engage with someone who wouldn’t even register as a blip on most company’s radars.
You can find the complete source for Freebooter here. If you have any interest in the PSoC and devices based off it, I’d encourage you to check it out, use it, and improve on it.