At work we use Vagrant to keep our virtual machines consistent. Sometimes ‘vagrant up’ can take a little while to execute, it can be annoying having to check the terminal to see when your machine is ready. Thanks to Growl and this nifty function by @jack we can receive a notification upon ‘vagrant up’ completion.
1. Install growl
2. Install growlnotify (should be in the ‘extras’ folder of the application image)
3. test growl notify in terminal using ‘growlnotify -m “hello world”‘
4. add the function to your ~/.bash_profile
5. run ‘gn vagrant up’ to have your machine boot with the notification wrapper
5. Optionally, make a bash alias so you don’t have to type out the whole command. Add the line ‘alias vup=”gn Vagrant up”‘ to your bash profile either with a text editor or by running ’echo “alias vup=\”gn Vagrant up\”" >> ~/.bash_profile’.
For the past couple of months I’ve been working (occasionally) with my friend jack on an instant messaging service which requires no user account but still allows users to identify themselves. We came up with clamour, a semi-private IM service based on security by obscurity. Clamour is powered by node.js and mongodb. So bleeding edge.
I have a basic thermal printer from sparkfun.com and decided to get Android talking with it just for fun.
If you haven’t already used your thermal printer then you should print a test page first. Hook the printer up to a power supply and print a test page by holding down the printer button while plugging into the mains. Once you’ve printed a test page you can be sure the printer is ready to go.
If you haven’t tested your IOIO yet it would be best to go through this simple tutorial to ensure the IOIO and your device are working correctly.
The thermal printer requires it’s own power supply (when waiting the printer consumes very little power but it draws a lot of current while printing)
Here is the wiring diagram, you can see I’ve used two separate power supplies:
In the Android app we use the IOIOLib to establish a serial (Uart) connection, we can then push bytes to the printer. The main IOIO loops constantly polls a queue of bytes and passes them to the printer. The PrintController provides methods to print to the printer by adding bytes to the output queue. The user guide for the printer has a comprehensive list of print commands, only some of the available commands are implemented in PrintController, maybe I’ll do a full implementation soon.
You’ll need to make sure the app has IOIOLib set as a library project.
Note that the printText() command does not actually print the text, it adds text to the buffer to be printed. In order to print the text the printBuffer() method is used, there are various print/line feed methods available, they’re detailed in the user guide.
Here’s a video of the printer in action, sorry for the bad quality, it was filmed with a potato:
You can skip this step if you’re sure your IOIO is working correctly with your Android device. This tutorial will guide you through getting started with your IOIO, completing this tutorial will put your mind at ease that your IOIO and Android device are compatible.
2 – Wire up the IOIO
Wire pin 5 of the DIN socket to a compatible IO pin. It is essential you use a pin which is 5V tolerant, in this tutorial we will use pin 7. A list of compatible pins can be found on the IOIO Wiki.
Wire pin 4 of the DIN socket to one of the 5V output pins through a 220-ohm resistor.
Wire pin 2 to one of the ground pins.
Connect the IOIO to power and ground.
3 – Set up Android
IOIOLib provides all we need to get going. This method opens a Uart module which we can use to send MIDI data:
I’ve used a few classes from the openJDK implementation of javax.sound.midi to conveniently build output. We’ll store any output in an ArrayBlockingQueue which is polled by a main loop. MidiMessages from the ArrayBlockingQueue are passed to the output stream provided by the Uart object.
The example code has a Button and two SeekBars (‘sliders’). The button in the example sends a Note On message on touch and a Note Off message on release. This is a very basic implementation of a midi controller, any serious implementation will require much more finely grained handling of UI events. The slider in the example sends a Control Change message to control number 33.
Here’s the full activity code:
packageioio.examples.hellomidi;importjava.io.IOException;importjava.io.OutputStream;importjava.util.concurrent.ArrayBlockingQueue;importioio.examples.hellomidi.R;importioio.javax.sound.midi.InvalidMidiDataException;importioio.javax.sound.midi.MidiMessage;importioio.javax.sound.midi.ShortMessage;importioio.lib.api.Uart;importioio.lib.api.DigitalOutput.Spec;importioio.lib.api.DigitalOutput.Spec.Mode;importioio.lib.api.Uart.Parity;importioio.lib.api.Uart.StopBits;importioio.lib.api.exception.ConnectionLostException;importioio.lib.util.AbstractIOIOActivity;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.MotionEvent;importandroid.view.View;importandroid.view.View.OnTouchListener;importandroid.widget.Button;importandroid.widget.SeekBar;importandroid.widget.SeekBar.OnSeekBarChangeListener;/**
* This is the main activity of the HelloIOIO example application.
*
* It displays a toggle button on the screen, which enables control of the
* on-board LED. This example shows a very simple usage of the IOIO, by using
* the {@link AbstractIOIOActivity} class. For a more advanced use case, see the
* HelloIOIOPower example.
*/publicclass MainActivity extends AbstractIOIOActivity{privateButton button_;private SeekBar mix_;/** a queue of midi messages**/privatefinal ArrayBlockingQueue out_queue =new ArrayBlockingQueue(OUT_QUEUE_SIZE);privatefinalstaticint OUT_QUEUE_SIZE =100;privatefinalstaticString DEBUG_TAG ="IOIOMIDI";/**
* Called when the activity is first created. Here we normally initialize
* our GUI.
*/
@Override
publicvoid onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button_ =(Button) findViewById(R.id.button);
button_.setOnTouchListener(new OnTouchListener(){
@Override
publicboolean onTouch(View arg0, MotionEvent arg1){switch(arg1.getAction()){case MotionEvent.ACTION_DOWN:
playNoteC();returntrue;case MotionEvent.ACTION_UP:
stopNoteC();returntrue;}returnfalse;}});
mix_ =(SeekBar)findViewById(R.id.seekbar_mix);
mix_.setOnSeekBarChangeListener(new OnSeekBarChangeListener(){
@Override
publicvoid onProgressChanged(SeekBar arg0, int arg1, boolean arg2){ShortMessage msg =newShortMessage();try{
msg.setMessage(ShortMessage.CONTROL_CHANGE, 33, arg1);
out_queue.add(msg);}catch(InvalidMidiDataException e){
Log.e(DEBUG_TAG,"InvalidMidiDataException caught");}}
@Override
publicvoid onStartTrackingTouch(SeekBar arg0){}
@Override
publicvoid onStopTrackingTouch(SeekBar arg0){}});}/** plays a 'C' MIDI note
* @throws InvalidMidiDataException **/privatevoid playNoteC(){
Log.i(DEBUG_TAG,"Playing note C");ShortMessage msg =newShortMessage();try{
msg.setMessage(ShortMessage.NOTE_ON, 60, 60);
out_queue.add(msg);}catch(InvalidMidiDataException e){
Log.e(DEBUG_TAG,"InvalidMidiDataException caught");}}/** stops a 'C' MIDI note
* @throws InvalidMidiDataException **/privatevoid stopNoteC(){
Log.i(DEBUG_TAG,"Stopping note C");ShortMessage msg =newShortMessage();try{
msg.setMessage(ShortMessage.NOTE_ON, 60, 0);
out_queue.add(msg);}catch(InvalidMidiDataException e){
Log.e(DEBUG_TAG,"InvalidMidiDataException caught");}}/**
* This is the thread on which all the IOIO activity happens. It will be run
* every time the application is resumed and aborted when it is paused. The
* method setup() will be called right after a connection with the IOIO has
* been established (which might happen several times!). Then, loop() will
* be called repetitively until the IOIO gets disconnected.
*/class IOIOThread extends AbstractIOIOActivity.IOIOThread{private Uart midi_out_;/** the output stream used to send the midi bytes **/privateOutputStream out;/**
* Called every time a connection with IOIO has been established.
* Typically used to open pins.
*
* @throws ConnectionLostException
* When IOIO connection is lost.
*
* @see ioio.lib.util.AbstractIOIOActivity.IOIOThread#setup()
*/
@Override
protectedvoid setup()throws ConnectionLostException {
midi_out_ = ioio_.openUart(null,new Spec(7,Mode.OPEN_DRAIN), 31250,Parity.NONE,StopBits.ONE);
out = midi_out_.getOutputStream();}/**
* Called repetitively while the IOIO is connected.
*
* @throws ConnectionLostException
* When IOIO connection is lost.
*
* @see ioio.lib.util.AbstractIOIOActivity.IOIOThread#loop()
*/
@Override
protectedvoid loop()throws ConnectionLostException {if(!out_queue.isEmpty()){try{
out.write(out_queue.poll().getMessage());}catch(IOException e){
Log.e(DEBUG_TAG,"IOIOException caught");}}}}/**
* A method to create our IOIO thread.
*
* @see ioio.lib.util.AbstractIOIOActivity#createIOIOThread()
*/
@Override
protected AbstractIOIOActivity.IOIOThread createIOIOThread(){returnnew IOIOThread();}}