Following the first part, here more information about the design choices.
Depending on the frequency and the capabilities of the tag, several (physical) formats are available. For the 125kHz frequency, the non-rewritable sort seems to exist in 3 main forms:
keyring tags: possibly great for specific functions but also a potential choking hazard for young children
stickers: They seem "quite" thick (a good millimetre?) but could be attached to toys or figurines.
cards (thin or thick): thins one are cheap (about $0.10 per card), sturdy and reliable.
Wondering how to personalise the cards, in the end I went for a simple printed sticky label which can be replaced if necessary. With the A4 paper size, it is possible to find some sheets with 15 labels (70 x 50.8mm). These are slightly smaller that the cards themselves (85.6 × 53.98 mm) but near enough.
As mention before, there are several type of cards depending on the content. So far, this is mainly related to either the colour of the icon or the design of the label.
The first and main type has the following definition:
and is used for "sounds" like musical instruments or animals sounds for example.
Order of printing
The label positions are counted from the bottom-left-hand side of the page.
If it seems a bit counter intuitive at first, there are 2 good reasons for this:
The PDF coordinate system is working that way, so there is no need to swap values
When printing with an inkjet printer, it is better if the feeding of the page is starting with the thickest part (i.e. with labels still present). By printing, thus removing, labels always at the bottom, it is safer when doing it by small batches.
There are two IDs at the back of each cards. But in reality, the numbers are related. I have no idea why it is organised like this but the best guess is that is related to system with 16-bit storage/computation.
The first number represents the decimal value of the complete number (24 bits). For the second group, before the comma, it's the first 8-bit decimal number and after, the 16-bit decimal remainder.
13691859 = 208 x 65536 + 60371
Note that in the YAML database, only the first number is used without the leading zeros because YAML seems to have an issue with big numbers (or might consider the value as octal rather than decimal).
The seed of the idea was a project made by someone who inserted RFID tags in CD plastic cases in order to help an elderly member of his family. I couldn't remember the reference any more but, at the time, I found the idea fantastic.
The idea here is towards a young member of the family but general logic is the same: It has to be very easy to use.
Similar projects which can be found on the Internet, though. For example,
There are 2 main frequencies in the world of (short range) RFID : 125kHz and 13.56Mhz, the latter being used for NFC and smartcards as well. These days, availability and price of cards/tokens/readers doesn't seem to be an issue for either type.
I ended-up going to the 125kHz route a little bit by chance:
Readers are very cheap and I had one collecting dust on my desk.
The range is slightly shorter than with higher frequencies which could be beneficial to avoid interferences between the cards.
Lower frequency might be less of a health hazard for a young child.
On the other hand, library books here and mobile phones are using the 13.56Mhz frequency. I might miss some opportunities of evolution. Who knows?
Arduino or Raspberry Pi?
After considering using an Arduino and a MP3 module, it turned out that there would be far more possibilities of evolution with a Raspberry Pi.
The main issue with Raspberry Pi/Linux is that both the card and filesystem are at risk if there are to many write IOs or the power is cut abruptly. These were mitigated using a Read-Only setup.
In term of price, a Raspberry Pi is slightly more expensive but (at the time of conception) I found some Raspberry Pi 3 for $25 delivered (from China (but UK made?)). Boot time (specially when using Python 3) is several time faster than with a Raspberry Pi B+ or zero even if these should be performing well enough.
SD Card & USB Flash
Although it is perfectly possible to store both the system and the data (music) on the same SD Card, the re-imaging of the system is a bit more complicated in this case. For the time being, I decided to keep them separate and store all the music aside on a USB Flash drive.
A number of recipes exist to boot the system faster. It's particularly long on a old Raspberry but on a Raspberry 3, this doesn't seem to be too much of an issue (just a few seconds). So in the end, I didn't investigate much.
As mention earlier, the weak point on the Raspberry Pi platform is certainly the storage, specially with SD Card: They either wear quickly or end-up with a corrupted filesystem if the power is cut violently. This is a downside compare to a solution based on a Arduino for example.
In our case, it is essential to protect the card against this kind of bad treatment as one can't guarantee anything in the end of a child!
Two techniques seem to co-exist: The first one consist in using an overlay and any change will be written in RAM and lost during reboot. It as its advantages but wasn't that practical in the long run.
The second one, created, improved and popularised par K3A, Charles Hallard and Adafruit, ... has the big advantage of providing a way to switch RO to RW (and back) live, making updates very easy.
Storage of media
To keep things simple and to allow the use of the jukebox for multi-part music albums & stories, media are stored using the following structure:
1 card = 1 id = 1 album = 1 folder = 1 info file + 1 or more media files
The name of the album doesn't matter (usually something Composer-Title). A scan is ran at the start-up and the association id <-> path kept in memory.
In theory, it should be possible to read the content of a folder sorted by name, at random, etc... but so far this hasn't been implemented.
Type of cards & IDs
The info file in each folder can contain grouping tags (genre, ...) and a system of generic/group cards can be implemented (for example: "Dancing music at random" or "Lullabies" or "Bed time stories", ... This hasn't been fully implemented yet.
On the printing side of label, 2 types of cards (music / sounds) and several icons have been designed. There is currently no link with the tags cited above. More on these later.
Version 0 - Prototype
The first version created was to validated the concept. In order to keep things "easy", I decided to buy a ready made speaker solution (Adafruit I2S 3W Stereo Speaker Bonnet). The price of the bonnet + speakers + shipping (from a local reseller) ended-up in the same order of the Raspberry Pi 3 itself but it was supposed to be easier.
It turned out that VLC + Pulse Audio + "cheap" I2S is barely compatible and even after the tweaks, each song had variable level (from medium to loud) and was starting with a big plop. Usually after 2-3 songs, the whole system would crash and in need of a complete restart.
The jukebox was unstable and the packaging was ugly...
... but it was a great prototype and it was a instant hit with my little one!
Last summer, I hinted that I was about to switch from the monolithic programme with all its threads to a constellation of separate processes.
The main reason was that the monolithic application needs a restart for any change in the configuration and that a crash/exception on one thread breaks everything.
True, having several separate processes impose to find a way to start them all in the first place and something else to look after them. It also uses quite a bit of memory (because of Python overhead, a tiny process is almost as memory hungry as a small one). Last but not least, the interprocess communication can be problematic.
Enters the Raspberry Pi 2
Fortunately, the Raspberry Pi Foundation released the Raspberry Pi 2 which has now a quad-core CPU, 1GB of memory (and even the Raspberry Pi 3, more recently, but I doubt it would make much difference here). At ~ 3MB of memory per process, there is plenty of available RAM! And also, starting a Python process is now almost immediate compared to the 5-10 seconds needed on the 1-B+ model.
Communication : MQTT
Thinking about it, there is not much need of communication between processes. In the majority of cases, it is all bout sending the data to the display interfaces and to a database (for the sensor part).
Anyway, the ubiquitous MQTT can solve all the communication problems... These days, it seems that there isn't a similar hub project around which isn't using MQTT either at the core or at least for plug-ins communication.
I have already detailed the way I format the topic and the payload of the messages.
Every process is now using a bootstrap library which manages the daemonisation, the MQTT communication, and logs. There are 2 types of messages : the data and metadata (starting, heartbeat, ...).
Currently the model used is the following:
All measurements have the MQTT retain option activated to keep the last value available to a reconnecting process
Pushover is a notification system for mobiles (and desktop)
I am currently using 2 storage systems: RRD and a timeseries database (test in progress)
'display_bikes' and 'display_transport' call external webservices and/or doing web scraping of pages. Resulting data is only displayed but never stored.
Just last week, I was mentioning the existence of Minibian which is basically a Raspbian Jessie but with a minimum set of pre-installed packages.
Raspbian Jessie... Light
And a couple of days ago, the "Raspbian Jessie Light" was anounced! (I don't know if it is linked to the Raspberry Pi Zero release, but one can say that they were focused on reducing things this week!)