TrinketMIDI updated with volume control demo

Just a quick update this time: A long while ago I made a post about using Adafruit Trinket without Arduino and later converted that into a TrinketMIDI Github repository for making a MIDI device with ATtiny:

https://github.com/jokkebk/TrinketMIDI

Now thanks to a contribution by Gerhard Zintel, there is now also a MIDI volume device sample code in the repo. If you want to make a MIDI volume controller, it should be pretty easy with the code as well. Enjoy!

Power up your computer wirelessly with Wemos D1 mini

Tired of reaching for that power button? Or perhaps you’d like to be able to turn on your PC when travelling? I sometimes like to do that to access some local files (or software via VNC), but dislike leaving the PC on for days “just in case”. This article explains how you can do it with the $3.50 Wemos D1 mini.

Wake-on-LAN is of course a great idea, but it only works if your PC is physically wired to the router. Wake-on-WLAN theoretically should work for WLAN as well, but here’s a shocking revelation: it usually does not, as it requires your PC to power up your WLAN card for it to receive the magic WLAN packet, and router support. At least I’ve never had a combination of network card and router that would work.

I used to have a nice DIY knock-sensor to PS/2 thingy, but the piezo kept dropping out, and got tired of repeating the required sequence of knocks. So I thought it would be cooler to have just a Bluetooth button I could use to do the same. I had a WLAN enabled Wemos D1 mini board lying around, and it only draws less than 100 mA of power, so I thought to find out if I could make it listen to a “magic packet” and boot up my PC. Turns out it was easier than I even thought!

Note that this project involves opening your PC case and playing around with your motherboard power switch wiring. Everything should be relatively hard to screw up, but if done wrong, you may get electrocuted, you may stick a screwdriver where it shouldn’t go and damage your motherboard or other components, so proceed with your own risk!
Continue reading Power up your computer wirelessly with Wemos D1 mini

DIY Bluetooth Keyboard Breakout for $10

You could get an excellent Bluetooth keyboard controller from Adafruit called Bluefruit EZ-Key which allowed super easy creation of projects that sent keyboard presses (for example a gamepad) just by connecting some switches to the pins. However, the EZ-Key cost $20 and is now discontinued. And in any case, Bluetooth-capable devboards are now available from AliExpress for a few dollars, so $20 today feels on the steep side. “Could it be done cheaper?” I wondered…

I have honestly about a dozen cheap wireless devboards lying around, many based on ESP8266 which only have Wi-Fi, but some also with ESP32 which includes Bluetooth. I spent some time trying to configure a Chinese ZS-040 serial Bluetooth module to function as a keyboard, but the AT command set was a very small subset of what the similar HC-05 / HC-06 modules have. After an evening of trying, I decided to give up on that. There are instructions how to flash HC-05 modules with RN-42 firmware to get Bluetooth HID capability, but it will require quite a few steps.

I also took a look at esp32_mouse_keyboard project, but for some reason or another, abandoned that avenue. Don’t recall if there were obstacles or the project was still incomplete a year ago, might also be that the ESP32 only had BT LE which technically didn’t support HID (Human Interface Device). Throw me a comment if you have that working!

Meanwhile, another idea dawned to me:

A Cheap Bluetooth Keyboard Must Contain A Bluetooth Module

Enter the wonders of AliExpress: While you cannot source an easy BT keyboard module from US under $20, you can get a full mini Bluetooth keyboard for $9.50 (at time of writing) including postage! This package ought to contain:

  • A fully compliant Bluetooth board that pairs with iOS, Android and PC devices
  • Full functioning keyboard and case
  • Presumably, a battery and a way to charge it

Sounds a too good deal to be true? Well, let’s find out! The keyboard has a solid metal backplate that is easily screwed open with micro cross head screwdriver. Once inside, it reveals a very professional layout with a flat ribbon cable (or “FCC cable”) coming from the mechanical part into the controller module, And a small (most likely LiPo) battery.

Taking the tape off and turning the board around reveals a bit spacious, but very professional looking PCB with clear markings. There are easily usable on/off switch and connect button on the PCB, a connector for the keyboard switches, and obviously some kind of microcontroller wired to the connector, as well as another smaller chip that is most likely a voltage regulator or charging chip.

I Googled around to find out if the “YC1026” MCU would have a datasheet to help me along the way, but unfortunately I only got Chinese web pages (most likely the manufacturer) without any documentation. Time to dig out my trusty Picotech 2000 scope and do some old-fashioned reverse engineering!
Continue reading DIY Bluetooth Keyboard Breakout for $10

$8 Bluetooth automation button for Raspberry Pi Zero W

This project was born as a sidetrack of another one (I’m planning on building a $10 DIY Bluetooth page turning pedal for my piano and iPad sheet music app, similar to PageFlip Butterfly). I was looking if AliExpress would have bluetooth pedals, which they don’t — it seems Chinese vendors are REALLY good at copying products but there is little new product innovation combining something as simple as a bluetooth keyboard sending one or two keys with a pedal (two items that they do have)! But while searching, I found this inexpensive gadget (in case the product is removed, you might just search for “bluetooth remote” at AliExpress.com):

So what is it? It’s an $8 disc with multimedia buttons that pairs with your smartphone and you can use it for example in car to control your music. But maybe it would pair with my Raspberry Pi W which has integrated bluetooth as well? Well it costs about nothing to find out!

Fast forward about two weeks and it arrived. I did not try to use it for its intended purpose, but instead went straight to pair it with my Raspberry Pi Zero W. Turns out the pairing process was quite painless, you can follow for example LifeHacker’s tutorial for pairing quite easily. And it goes a little something like this (your MAC address might vary, just look for output after “scan on”):

# bluetoothctl
power on
agent on
scan on
connect FF:FF:00:45:8D:FF
trust FF:FF:00:45:8D:FF

Continue reading $8 Bluetooth automation button for Raspberry Pi Zero W

$5 USB MIDI adapter with ATmega32u4

This article will detail how to build a USB MIDI adapter (one-directional: you connect the adapter with USB cable to your computer, and it receives notes and pedal data from your keyboard’s MIDI OUT and transmits them to your computer) with ATmega32u4, 6N137 optocoupler, a few resistors and spare MIDI connector or cable. Read on for details!

Preamble

Last year I wrote how you can turn Teensy LC into an inexpensive USB MIDI adapter. I used it to replace a non-working Chinese MIDI-USB adapter that did not send controller messages (i.e. piano pedal) properly to PC.

However, since the Teensy still costs $12, and you have to get some additional components, it doesn’t make sense to use it in a dedicated MIDI adapter, since you can get a working USB MIDI adapter for around $15 from Thomann and probably many other places.

But how about other boards? After making my Teensy LC adapter, I actually tinkered with Adafruit Pro Trinket, and got that working as well (the standard Trinket does not have hardware UART so V-USB and software UART is somewhat risky). But there is even a better board for this: The ATmega32u4 board I previously showed how it can be made into USB HID mouse. Let’s see how to turn it into a USB MIDI adapter!

Required hardware

To build this, you will need roughly $5.40 worth of components:

  • SparkFun Pro Micro (clones with ATmega32u4 can be had for $3.50 from AliExpress, eBay, etc.)
  • 6N137 optocoupler, which can be had for ~$0.30 a piece (I suggest sourcing a couple in case you burn one by accident)
  • 330 ohm and 2 kohm resistors ($0.10) and 1N4148 diode if you want to be safe
  • MIDI connector or alternatively you can just cut a short cheap MIDI cable and wire it to your project, let’s say $1.50

Continue reading $5 USB MIDI adapter with ATmega32u4

Split MIDI Files with Python

In my previous post I showed how to use Raspberry Pi to automatically record MIDI files from digital piano whenever you turn it on. However, if you sit down and play for an hour, and get one big MIDI file, it is not very useful. So what to do?

Pianoteq has a feature that splits your playing session based on breaks you take between playing notes. So I decided to mimick this feature with a simple Python script that:

  1. Keeps tab on keys and pedals pressed
  2. Whenever X seconds elapse without any keys or pedals down, a new MIDI file is started
  3. Additionally, if user presses and releases sustain pedal several times in the end, filename for that MIDI is altered to “highlight” that file

I first thought to learn enough of MIDI file format to do everything from scratch, but there’s quite a bit of small details to handle, so in the end I decided to use an external toolkit from Craig Stuart Sapp called midifile to do the heavy lifting. You should be able to just clone the Git repo and make it with Raspberry Pi:

pi@raspberrypi:~ $ git clone https://github.com/craigsapp/midifile
pi@raspberrypi:~ $ cd midifile
pi@raspberrypi:~/midifile $ make

You should now have two useful commands in ~/midifile/bin: toascii to read a MIDI file and dump an ASCII (text) version of it, and tobinary to do the reverse. With Python’s Popen and smart piping, we can read and write the binary MIDI files as they were in this text format. You can check out how the format looks like with some MIDI file you have:

~/midifile/bin/toascii somemidi.mid | less

Here’s a sample of a MIDI file recorded by arecordmidi (I added the note in square brackets):

"MThd"
4'6
2'0
2'1
2'384

;;; TRACK 0 ----------------------------------
"MTrk"
4'50044
v0      ff 51 v3 t120
v0      ff 58 v4 '4 '2 '24 '8
v7147   90 '58 '29
v88     b0 '64 '5
v1      b0 '64 '7

[LOTS OF MIDI EVENTS]

v0      ff 2f v0

There’s some header data in the beginning, and each MIDI event is comprised of a deltatime field starting with ‘v’, and then fairly standard MIDI events in straightforward syntax. I hardcoded my program to expect single track which starts with tempo and speed data (ff 51 and ff 58 lines) which I use to calculate how many deltatime units is one second. I copy this header part to start of every MIDI file, and append the final “ff 2f v0” (END TRACK) event to the end. Here’s the full code:
Continue reading Split MIDI Files with Python

Using Raspberry Pi as an automatic MIDI logger

During my summer holidays I got an interesting idea: Pianoteq has a very nice feature of “always on MIDI logging” that saves everything you play on your keyboard while Pianoteq was on. I’ve previously made some MIDI projects and had a great idea:

How about building a small device that records everything I play on my piano, and save it as MIDI files?

This would enable me to later grab a good performance, and eliminate the “recording anxiety” I get if I know I’m recording and should definitely not do any mistakes during the next 1000+ notes. Furthermore, even with easy MIDI recording to USB stick, it’s still several manual steps plugging the memory stick in, starting recording, stopping it, lugging it to a computer, etc.

My first idea was to use some WLAN-enabled embedded device, but MIDI IN would require optoisolators and some custom electronics, and more modern digital pianos often come with only USB MIDI, so it could easily become an exercise in communication protocols. Fast forward a couple of minutes to my next revelation:

Raspberry Pi Model 0 W already has USB and WLAN, and it’s small. Why not use that?

Turns out using a RaspPi as fully automated MIDI logger is really easy. Read on for instructions!

Update: Also check out my follow-up post to split the recorded MIDI files automatically!

Recording MIDI with Raspbian

Turns out recording MIDI from a USB MIDI enabled device is really easy. When I plug in my Kawai CS-11 (sorry for the unsolicited link, I love my CS11 :) to the Pi (or just turn it on when it’s plugged in), dmesg shows that the Pi automatically notices the new MIDI device:

[  587.887059] usb 1-1.5: new full-speed USB device number 4 using dwc_otg
[  588.022788] usb 1-1.5: New USB device found, idVendor=0f54, idProduct=0101
[  588.022800] usb 1-1.5: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[  588.022807] usb 1-1.5: Product: USB-MIDI
[  588.074579] usbcore: registered new interface driver snd-usb-audio

Once the USB MIDI device is found, you can use arecordmidi -l to list available MIDI ports:

pi@raspberrypi:~ $ arecordmidi -l
 Port    Client name                      Port name
 14:0    Midi Through                     Midi Through Port-0
 20:0    USB-MIDI                         USB-MIDI MIDI 1

Continue reading Using Raspberry Pi as an automatic MIDI logger

USB Mouse with ATmega32U4 Pro Micro Clone and LUFA

I have spent a fair amount of time with 8-bit AVR microcontrollers and one of the cooler things has been the V-USB library which implements low-speed USB with clever (and very time-critical) bit-banging. The popularity of my USB tutorials is a testament to its usefulness, and I’ve gotten lots of mileage out of that.

There are, however, some limitations to software USB with such a low spec microcontroller. USB communication hogs up the MCU completely during USB communication, which means you lose dozens of microseconds in random (or in many cases 8 ms) intervals. This rules out things like software UART at reasonable speeds (which I discovered when trying to implement MIDI on Adafruit Trinket). And more powerful ATmega328-based dev boards like Pro Trinket start to get quite large.

ProMicro on a breadboard

Not so with this tiny beauty shown in the image. It’s a ATmega32U4 based board, where the U4 means it has hardware USB support. The form factor is extremely compact 12 pin header length, which leaves 5 rows free on the smallest prototyping breadboards. That means you can have a DIP8 component with a few resistors on the same breadboard (such as a 6N137 optocoupler which is nice for MIDI… ;).

And the best part is, that because the chip is flashed with same firmware used in Arduino Leonardo (and a largely matching pinout), you can use Arduino for programming, and avrdude supports it out of the box.

Actually, scratch the above statement. The best part is the price. The board is based on Sparkfun Pro Micro 16 MHz, but it’s actually a Chinese clone, which you can get for $4 via DealExtreme and from quite many places in AliExpress: Just search for ATmega32U4 and they will come up. This means you can just order five and solder them into whatever project you’ll make permanently. And unlike Arduino Micro (for which clones exist as well), this has the micro-USB port already in place.

Using Pro Micro without Arduino IDE

Now you can just follow SparkFun’s instructions on how to use that thing on Arduino (short version: select Leonardo as board type, and look up the schematic if you are unsure which pins are connected to LEDs, etc.). But if you’re like me and want to get to raw metal, avr-gcc and avrdude is the way to go. Here’s a simple blinky demo:
Continue reading USB Mouse with ATmega32U4 Pro Micro Clone and LUFA

Mounting / Fixing Raspbian SD Card from Raspberry Pi

Shut down my Pi today and thought to make a copy of files in its SD card. This is what mount /dev/sdf2 /mnt had to say:

mount: wrong fs type, bad option, bad superblock on /dev/sdf2,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail  or so

Great. After trying parted and fsck, it became apparent that for some reason, the root partition is marked as being 1 block longer than the physical card. Must be a bug with Raspbian partition expansion or something.

Thankfully, I found this gold nugget which suggested using resize2fs to fix it. Turns out I had to run e2fsck first (and say “y” a couple of times):

sudo e2fsck /dev/sdf2
sudo resize2fs /dev/sdf2
mount /dev/sdf2 /mnt

Voilá! Fully functioning filesystem again.

Fixing Android Browser SVG Scaling with max-height

Ever had that moment where you started coding X and instead spent four hours doing Y instead? I just had it, and it stemmed from a quite simple idea: let’s do an embedded SVG bar chart with React (nice library by the way)! Because I just started with Bootstrap which makes it really simple to scale your content to the device at hand, I also wanted the diagram to scale. Easy, right? WRONG!!!

<svg version="1.1" width="100%" viewBox="0 0 200 100">
here are some primitives
</svg>

The viewBox attribute defines the internal coordinates for the SVG, and the width attribute should ensure the SVG fills the container. And it does, at least on desktop. And mobile Chrome. But not Android default browser. I tried different settings of preserveAspectratio. I tried CSS tricks that should work but they wouldn’t. After some hours, I gave up and went to sleep. And this morning I found this nugget: WebKit long had a bug, where SVG element is resized to 100% height, which on mobile device was interpreted as screen height (not the parent element)!

So long story short, if I use my S5 in portrait mode, the 1080×1920 screen makes the above SVG element 1920 pixels high, with 1080×540 (2:1) diagram in the middle of huge white area. The bug is reported in 2012: https://bugs.webkit.org/show_bug.cgi?id=82489. This was supposedly already fixed, but seems the new version hasn’t trickled to my mobile OS yet. Thankfully, the fix is quite simple and does seem to work, just add max-height to the element:

<svg version="1.1" style="max-height: 100%" viewBox="0 0 200 100">
here are some primitives
</svg>

I didn’t even need the width=”100%” because that seems to be the default. Doesn’t hurt, though. So, just sharing this for everyone, maybe Google will index this and help others in need.