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

Dependents:   MicIO-Example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicIO.cpp Source File

MicIO.cpp

00001 #include "MicIO.h"
00002 
00003 MicIO::MicIO(PinName micOut, PinName clockIn) : _micOut(micOut), _clockIn(clockIn) {
00004     clockPeriod = 0.25;
00005     wait(0.015);        // Wait 15ms to ensure powered up
00006     _genSinTable();    //Generate the sin table
00007 }
00008 
00009 /* Send byte array through micIO */
00010 void MicIO::send(const char * inputStr, int length) {
00011     unsigned char * outputStr;
00012     outputStr = (unsigned char*) inputStr;
00013     int numberOf4BitPairs = length * 2;
00014     int current4BitIndex = 0;
00015     int fourBits;
00016     float sinSeed; //default at something ridculously high to stop an inf loop occuring
00017     int clockState = clock(); //default the clock state to correct value
00018     
00019     /*
00020                 Parse out the 4 bits we're sending this clock cycle
00021         */
00022         if(current4BitIndex %2 == 0) { //upper 4 bits
00023             fourBits = upper4Bits(outputStr[current4BitIndex/2]);
00024         } else { //lower 4 bits
00025             fourBits = lower4Bits(outputStr[current4BitIndex/2]);
00026         }
00027         sinSeed = _getSinSeed(fourBits); //get new sinSeed
00028     
00029     
00030     while(current4BitIndex < numberOf4BitPairs) {
00031         if(clock() == 0) { //Clock changed to low
00032             
00033             /*
00034                 Output sinusoid pulse
00035             */
00036              _sendSin(sinSeed);
00037             /*
00038                 We're at the next clock cycle, and recieved a low. 
00039                 master done reading the sinusoid. Lets move on to the next 4bits
00040             */
00041             clockState = 0;
00042             ++current4BitIndex;
00043             /*
00044                 Parse out the next 4 bits we're sending this clock cycle
00045             */
00046             if(current4BitIndex %2 == 0) { //upper 4 bits
00047                 fourBits = upper4Bits(outputStr[current4BitIndex/2]);
00048             } else { //lower 4 bits
00049                 fourBits = lower4Bits(outputStr[current4BitIndex/2]);
00050             }
00051             sinSeed = _getSinSeed(fourBits); //get new sinSeed
00052         }
00053     }
00054 }
00055 /* Read the current value of the input clock */
00056 int MicIO::clock() {
00057     static int clockState = 0; //start clock @ low
00058     float average = 0;
00059     for(int i =0; i < 10; ++i) {
00060         average += _clockIn.read();
00061     }
00062     average = average/10;
00063     //Foce there to be high->low->high->low pattery w/clockState static int
00064     if(average > 0.6 && clockState == 0){ //actually ~0.71
00065         clockState = 1;
00066         return 1;
00067     } else if (average < 0.485 && clockState == 1) { //actually ~0.43
00068         clockState = 0;
00069         return 0;
00070     } 
00071     return -1; //NO CHANGE TO CLOCK
00072 }
00073 /* Extracts the lower 4 bits of a byte */
00074 unsigned char MicIO::lower4Bits(unsigned char byte) {
00075     return (byte & 0x0F);
00076 }
00077 /* Extracts the upper 4 bits of a byte */
00078 unsigned char MicIO::upper4Bits(unsigned char byte) {
00079     return (byte >> 4) & 0x0F;
00080 }
00081 /* Send a sin Wave  - bursts of 40 cycles*/
00082 void MicIO::_sendSin(float sinSeed) {
00083     int cycles = _numCycles(sinSeed);
00084     for(int c = 0; c < cycles; ++c) {
00085         for(float i = 0; i < 360; i+=sinSeed) {
00086             _micOut = _sinTable[(int) i];
00087         }
00088     }
00089     _micOut = 0.5; //Null Output
00090         
00091 }
00092 /* Generate a sin Table */
00093 void MicIO::_genSinTable() {
00094     for(int i = 0; i < 361; ++i) {
00095         float temp = i;
00096         _sinTable[i] = sin(temp/180*3.141)*0.5+0.5;
00097     }
00098 }
00099 /* Go from 4 bits to a sin seed */
00100 float MicIO::_getSinSeed(unsigned char bits4) {
00101     /*
00102         By having sinSeed @ 1024 by default, if for some reason its not assigned, graceful
00103         degradation occurs.
00104     */
00105     float sinSeed = 1024; //Default it to a large number for graceful degregation.
00106     switch(bits4 & 0xF) { //switch just the 4 bits (force to 4 bits)
00107         case 0x0 : sinSeed = 0.75; break;
00108         case 0x1 : sinSeed = 1.00; break;
00109         case 0x2 : sinSeed = 1.25; break;
00110         case 0x3 : sinSeed = 1.50; break;
00111         case 0x4 : sinSeed = 1.75; break;
00112         case 0x5 : sinSeed = 2.00; break;
00113         case 0x6 : sinSeed = 2.25; break;
00114         case 0x7 : sinSeed = 2.50; break;
00115         case 0x8 : sinSeed = 2.75; break;
00116         case 0x9 : sinSeed = 3.00; break;
00117         case 0xA : sinSeed = 3.25; break;
00118         case 0xB : sinSeed = 3.50; break;
00119         case 0xC : sinSeed = 3.75; break;
00120         case 0xD : sinSeed = 4.00; break; 
00121         case 0xE : sinSeed = 4.25; break;
00122         case 0xF : sinSeed = 4.50; break;
00123     }
00124     return sinSeed;
00125 }
00126 /*
00127    number of cycles sinusoid needs to run...kind of guesswork
00128 */
00129 int MicIO::_numCycles(float sinSeed) { 
00130     float quarterPeriod = clockPeriod/2;
00131     float timePerSinusoidPeriod =  1/(sinSeed*1000);
00132     return static_cast<int>((quarterPeriod/timePerSinusoidPeriod)); //floor to integer
00133 }