Allows mbed to send data to an HTML5 web browser through a 4 pole mini jack.

### The Problem:

*Sending data from a microcontroller to any smartphone*

While you can use the usb interface on non-mobile devices, very few smartphones allow you to use this easily. For example iOS requires the purchasing of a 100k+ liscense.

Then there's bluetooth with its gazillions of native code libraries to hook into: OS X, Windows, Linux, iOS, Motorolla, HTC, Samsung, LG,....ew.

With HTML5's web audio API, we can create a hardware bus similar to how Square's Credit Card readers works.

I've successfully tested this with my Macbook Air with Firefox v28 and Chrome v33. IE will not work under any circumstances as it currently does not support the HTML5 Web Audio API.

### Protocol Overview

Javascript is asynchronous, and setIntervals can vary by +/- a few ms. The way around this is to create a master slave bus. Our JavaScript master dictates to the microcontroller slave when it wants data through a square wave clock signal. When the square wave goes from High (1) to low (0) (falling edge), the microcontroller should be sending the data payload. Here's a screenshot of this in action:

And here's is one of the sinusoids zoomed in:

This is a video of the bus in action:

Each data playload is a sinusoid. As of right now the library generates 16 distinct frequencies, where each frequency represents a number from 0 to 15.

The MicIO in its current form has an error rate of 5%, and transfer rate of 16bits/sec. This can easily be sped up by using a faster microcontroller, as well as modulating sinusoids in the payload. For example 0xFF would be represented by: sin(2π*1000) + sin(2π*1500) +sin(2π*2000).

HTML5's web audio api allows us to perform a mathematical operation called a Fast Fourier Transform (FFT - http:en.wikipedia.org/wiki/Fast_Fourier_transform. FFT's basically allow us to parse out the frequencies in our audio stream. Below is a table converting hex/decimal to its payload sinusoid frequency.

Hex | Sinusoid Frequency (Hz)

0x0 | 818

0x1 | 1076

0x2 | 1335

0x3 | 1335

0x4 | 1894

0x5 | 2153

0x6 | 2411

0x7 | 2670

0x8 | 2971

0x9 | 3229

0xA | 3488

0xB | 3746

0xC | 4048

0xD | 4306

0xE | 4565

0xF | 4823

NULL | < 500 or >5500

### Wiring

#### 4 pole mini jack

1. Left Music = Clock In/Out 2. Right Music = Master Data not yet implemented 3. Ground 4. Microphone In = Slave Data

Currently, MicIO does not support the sending of data to the microcontroller, but it'd be trivial to add in future versions.

Here is the actual wiring schematic with the mbed NXP LPC1768: https:www.sparkfun.com/products/9564. Do to my cad software not having a 4 pole mini jack, Its wired up to two 3 pole mini jacks. The left minijack should go to the mic prong, where-as the right minijack goes to left Music.

### Software

#### Slave - MBED

The Code repo can be found on the mbed webpage (http:mbed.org/users/cbookman3/code/MicIO/ I've also published an example micIO application http:mbed.org/users/cbookman3/code/MicIO-Example/.

Basically it takes in a string array (or number). Then micIO sends the data in half byte payloads each time the master requests more data. If there is no more data, it simply does not generate any sinusoids, aka frequency of 0.

#### Master

This code can be found on https:github.com/cobookman/HTML5.MicIO.

The HTML5 MicIO library when instantiated, will try to bind to the microphone. Upon sucessful binding, it'll begin to request for data. There's two javascript files you must include:

• js/clock.js - Generates a square wave clock for MicIO w/some helpers
• js/index.js - The MicIO library

make sure that the volume on your computer/mobile device is all the way up.

To create a new MicIO master instance you simply run:

#### Example javascript master usage

```var micIO = new MicIO(function onDataRecieved(halfByteArr) {
//do stuff with the data E.g:
var byteArr = [];
for(var i = 0; i < halfByteArr.length; ++i) {
var byteIndex = Math.floor(i/2);
if(i%2 === 0) {		      //first half of the byte
byteArr[byteIndex] = (halfByteArr[i] << 4) & 0xF0;
} else {  			//second half of the byte
byteArr[byteIndex] += halfByteArr[i] & 0x0F;
}
}
});
```
Revision:
2:c90f916f0b08
Parent:
1:1dfc4deed2cb
Child:
3:1630409f9bd6
```--- a/MicIO.cpp	Sun Mar 23 00:53:17 2014 +0000
+++ b/MicIO.cpp	Sun Mar 23 20:43:55 2014 +0000
@@ -1,11 +1,13 @@
#include "MicIO.h"
#include "TextLCD.h"
+TextLCD lcd(p24, p25, p26, p27, p28, p29);
+
MicIO::MicIO(PinName micOut, PinName clockIn) : _micOut(micOut), _clockIn(clockIn) {
+    clockPeriod = 0.25;
wait(0.015);        // Wait 15ms to ensure powered up
_genSinTable();    //Generate the sin table
}

-TextLCD lcd(p24, p25, p26, p27, p28, p29);
/* Send byte array through micIO */
void MicIO::send(const char * inputStr, int length) {
unsigned char * outputStr;
@@ -48,6 +50,7 @@
} else { //lower 4 bits
fourBits = lower4Bits(outputStr[current4BitIndex/2]);
}
+            lcd.printf("%i",fourBits);
sinSeed = _getSinSeed(fourBits); //get new sinSeed
}
}
@@ -55,7 +58,11 @@
/* Read the current value of the input clock */
int MicIO::clock() {
static int clockState = 0; //start clock @ low
+    float average = 0;
+    for(int i =0; i < 10; ++i) {
+    }
+    average = average/10;
//Foce there to be high->low->high->low pattery w/clockState static int
if(average > 0.6 && clockState == 0){ //actually ~0.71
clockState = 1;
@@ -76,7 +83,8 @@
}
/* Send a sin Wave  - bursts of 40 cycles*/
void MicIO::_sendSin(float sinSeed) {
-    for(int c = 0; c < 50; ++c) {
+    int cycles = _numCycles(sinSeed);
+    for(int c = 0; c < cycles; ++c) {
for(float i = 0; i < 360; i+=sinSeed) {
_micOut = _sinTable[(int) i];
}
@@ -118,3 +126,11 @@
}
return sinSeed;
}
+/*
+   number of cycles sinusoid needs to run...kind of guesswork
+*/
+int MicIO::_numCycles(float sinSeed) {
+    float quarterPeriod = clockPeriod/2;
+    float timePerSinusoidPeriod =  1/(sinSeed*1000);
+    return static_cast<int>((quarterPeriod/timePerSinusoidPeriod)); //floor to integer
+}
\ No newline at end of file
```