napoleon leoni / Mbed 2 deprecated DirectionalMicrophone

Dependencies:   C12832_lcd crossCorrelation mbed-rtos mbed

Files at this revision

API Documentation at this revision

Comitter:
nleoni
Date:
Wed Mar 26 05:44:21 2014 +0000
Commit message:
MBED RTOS Microphone array processing; Currently operating with two microphones; Correlataion calculation not yet fully functional

Changed in this revision

C12832_lcd.lib Show annotated file Show diff for this revision Revisions of this file
crossCorrelation.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C12832_lcd.lib	Wed Mar 26 05:44:21 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/dreschpe/code/C12832_lcd/#468cdccff7af
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crossCorrelation.lib	Wed Mar 26 05:44:21 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/nleoni/code/crossCorrelation/#0de5b990cf2d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Mar 26 05:44:21 2014 +0000
@@ -0,0 +1,281 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "C12832_lcd.h"
+#include "stdint.h"
+#include <string.h>
+#include <math.h>
+#include <stdio.h>
+
+#define DEBUG
+
+
+#define SAMPLINGPERIOD 60 //us, 20 us would correspond to a 50 kHz sampling rate
+#define EVENTLENGTH 1000//number of sample to collect a full event
+#define EVENTLOGSIZE 20 //Events are stored in this log, eventually read and cleared
+#define TRIGGERHIGH 0xC000
+#define TRIGGERLOW 0x4000
+#define PRETRIGSAMPLES 20  //samples to keep prior to trigger time.
+#define SAMPLEDELAY 20
+#define BUFFER 20           //serial terminal input command buffer
+
+
+//define signals
+#define COMPARESIGNAL 0x01//use this signal to signal the onDAQ thread to check for a trigger.
+#define PROCESSINGSIGNAL 0x10 //use this signal to start the processing thread
+
+//There will be a thread checking on error conditions
+//this Thread will print to a terminal causes of error conditions and the exit 
+//the program
+//signals related to error conditions
+#define NULLPOINTER 0xE1
+
+
+AnalogIn FLMic(p20),FRMic(p19);
+AnalogOut FLMout(p18);
+DigitalOut ISRcheck(p26);
+DigitalOut circularCheck(p24);
+LocalFileSystem local("local"); //use the MBED file system to store debug files
+
+uint16_t FLMbuffer[EVENTLENGTH],FRMbuffer[EVENTLENGTH],flmLastValue,frmLastValue;
+float eventLog[2][EVENTLOGSIZE]; //down the line make an event class, and have an array of events.
+uint16_t *ptrflm,*ptrflmStart,*ptrfrm,*ptrfrmStart; //These pointers are used to implement a dual circular buffer architecture
+int indexMax,delayMax;
+int Max;
+
+Ticker audioDAQ;
+
+void acquireISR(void);//ISR routine for acquiring the microphone audio data
+Thread *onDAQTrigger;
+Thread *processingCrossCorr;
+Serial pc(USBTX, USBRX);   //serial communication terminal
+
+//define DirMic state type  
+typedef enum {
+    ACQUIRING,
+    TRIGGERED,
+    PROCESSING,
+    IDLE            //state to enter for debugginr purposes    
+} DicMicStateType;
+
+DicMicStateType dicMicState;
+
+/******************************************************************
+*
+*This 
+*
+*******************************************************************/
+void readTerminal(void const *args){
+    int tempLFM,tempRFM,i;
+    char buffer[BUFFER];
+    int filecounter;
+    char *ptrChar;
+    ptrChar=buffer;
+    FILE *fp;
+    char filename[16],outputstr[16];
+    //Test pointers
+    uint16_t testbuffer[10];
+    pc.printf(">Enter a command: (a..arm acquisition; t..trigger acquisition; s..state; r..results)\n>");
+    filecounter=0;
+    while(1){
+    //Note the choice of using getc instead of scanf to read the fortune cookie,
+    //this is a non-blocking call and allows the rest of our threads to continue operating
+    //only when a new character is typed this thread executes its body otherwise
+    //it immediately yields to other threads.
+        if( pc.readable() ){
+            *ptrChar=pc.getc();
+            pc.putc(*ptrChar);
+            if((*ptrChar=='\n') || ((ptrChar-buffer)>=(BUFFER-1)) ){
+                    if((ptrChar-buffer)>=(BUFFER-1)) *++ptrChar='\n';
+                    *ptrChar='\0';
+                    //Check the entered command
+                    switch(buffer[0]){
+                        case 'a': //arm command, to be used after a trigger event
+                            dicMicState=ACQUIRING;
+                            audioDAQ.attach_us(&acquireISR,200);
+                           #ifdef DEBUG
+                            pc.printf("State is %i\n",dicMicState);                         
+                            #endif
+                        break;
+                        case 's': //check current state command
+                        pc.printf("State is %i\n>",dicMicState); 
+                        break;
+                        case 'r': //check current state command
+                        pc.printf("Last Correlation results: delay=%d\n>",delayMax); 
+                        break;
+                        case 'f': //pointer test command
+                        fp=fopen("/local/out.txt", "w");
+                        fprintf(fp, "Hello World!");
+                        fclose(fp);
+                        break;
+                        case 'o': //output file
+                        filecounter++;
+                        sprintf(filename,"/local/data%d.txt",filecounter);
+                        pc.printf("Data file:%s\n>",filename);
+                        fp=fopen(filename, "w");  // Open filename on the local file system for writing
+                        if(fp!=NULL){
+                            for(i=0;i<EVENTLENGTH;i++){
+                                tempLFM=(int)FLMbuffer[i]-0x8000;
+                                tempRFM=(int)FRMbuffer[i]-0x8000;
+                                sprintf(outputstr,"%d,%d%c",tempLFM,tempRFM,13);
+                                pc.printf("%s",outputstr);
+                                fprintf(fp,outputstr);
+                            }//for i loop
+                            fclose(fp);
+                        } else {
+                            pc.printf("Error Opening File\n>");
+                        }//if fp!=null
+  
+                    }//end of switch
+                    pc.printf(">Enter a command: (a..arm acquisition; t..trigger acquisition)\n>");
+                    ptrChar=buffer;
+            } else {
+                ptrChar++;
+            }//if ptrchar... check for buffer overflow
+        }//if pc readable
+        //A 100 ms wait seems like reasonable delay which allows operation of the remaining threads.
+    Thread::wait(100);
+    }//while(1)
+}//thread function
+
+//*****************************************************************************************
+//Comparison thread
+//This thread is called with a signal from the timer interrupt
+//it checks whether a trigger level is exceeded and if so chanegs the state 
+//to storage
+void onDAQ(void const *args){
+int sampleCounter=0;
+    while(1){
+        Thread::signal_wait(COMPARESIGNAL);
+        //Here we check if signal exceeded trigger, currently only triggering on one mic
+        switch(dicMicState){
+        case ACQUIRING:
+            if( ( (flmLastValue) > TRIGGERHIGH ) || ( (flmLastValue) < TRIGGERLOW ) ){//signal exceeded trigger
+
+                dicMicState=TRIGGERED;
+                #ifdef DEBUG
+                pc.printf("State is %i\n>",dicMicState);
+                #endif
+            }
+            sampleCounter=0;
+            break;
+        case TRIGGERED:
+            if(sampleCounter==0) pc.printf("Entered countdown trigger phase\n>");
+            sampleCounter++;
+            if(sampleCounter>(EVENTLENGTH-PRETRIGSAMPLES)){
+            //if(sampleCounter>100){
+                dicMicState=PROCESSING; //switching states should be done prior to detaching the interrup...   
+                #ifdef DEBUG
+                pc.printf("State is %i\n>",dicMicState);
+                Thread::wait(10);
+                #endif
+                processingCrossCorr->signal_set(PROCESSINGSIGNAL);           
+                audioDAQ.detach();//detach interrupt, this allows gathering data after the trigger yet leaving PRETRIGSAMPLES before trigger time   
+            }
+        break;
+        }
+    }
+}
+
+
+//Processing thread 
+void crossCorrelationThread(void const *args){
+int i,j,k,ndelays,delay;
+
+ndelays=2*SAMPLEDELAY+1;
+int correlationArray[ndelays],tempLFM,tempRFM;
+    //This thread waits for the processing signal and then perform one correlation calculation
+    //This very simple cross correlation will for the time being have no Thread::wait....as it runs alone
+    while(1){
+        Thread::signal_wait(PROCESSINGSIGNAL); 
+        Max=0;  //Store max computed value of correlation
+        indexMax=0;
+        delayMax=2*SAMPLEDELAY;//safe value to know if it did not run
+        for(j=0;j<ndelays;j++){
+            correlationArray[j]=0;
+            delay=-SAMPLEDELAY+j;
+            for(i=0;i<EVENTLENGTH;i++){
+                //compute k
+                    k=i+delay;
+                    if(k<0) k=EVENTLENGTH+k; 
+                    if(k>(EVENTLENGTH-1)) k=k-EVENTLENGTH;
+                    tempLFM=(int)FLMbuffer[i]-0x8000;
+                    tempRFM=(int)FRMbuffer[k]-0x8000;
+                    correlationArray[j]+=tempLFM*tempRFM;
+                }  //end of for i
+            if(correlationArray[j]>Max){ 
+                Max=correlationArray[j];
+                indexMax=j;
+                delayMax=delay;
+            }
+            #ifdef DEBUG//debugging printout of calculated correlation values
+            pc.printf("Correlation[%i]=%.0f\n>",j,(double)correlationArray[j]);
+            pc.printf("Max=%.0f\n>",(double)Max);
+            pc.printf("delayMax=%.0f\n>",(double)delayMax);
+            #endif
+        }//end of for j loop
+        pc.printf("Correlation results: delay=%i\n>",delayMax); 
+        #ifdef DEBUG
+        dicMicState=IDLE;//processing is done set to idle until manually armed
+        #else
+        dicMicState=ACQUIRING;  //the systems goes back to aqcuiring after finished processing
+        audioDAQ.attach_us(&acquireISR,SAMPLINGPERIOD);
+        #endif
+    }//end of while loop for thread
+}
+
+
+int main() {
+    pc.printf("Directional Microphone\n");
+    audioDAQ.attach_us(&acquireISR,SAMPLINGPERIOD);
+    ptrflm=FLMbuffer;
+    ptrfrm=FRMbuffer;
+    dicMicState=IDLE;
+    #ifdef DEBUG
+    pc.printf("State is %i\n",dicMicState);
+    #endif
+    Thread thread(onDAQ);
+    onDAQTrigger=&thread;
+    Thread thread2(crossCorrelationThread);
+    processingCrossCorr=&thread2;
+    Thread thread3(readTerminal);
+    
+    while(1) {
+        
+    }
+}
+
+void acquireISR(void){
+    if(dicMicState==ACQUIRING || dicMicState==TRIGGERED ){
+        #ifdef DEBUG
+        ISRcheck=1;
+        #endif
+        if(ptrflm && ptrfrm){//check if pointer not null
+        //Note that two calls to read_u16 take overall 50 us!!!
+            *ptrflm=FLMic.read_u16();
+            flmLastValue=*ptrflm;
+            #ifdef DEBUG
+            FLMout.write_u16(*ptrflm);
+            #endif 
+            *ptrfrm=FRMic.read_u16();
+            frmLastValue=*ptrfrm;
+            if( ((ptrflm-FLMbuffer)) >= (EVENTLENGTH-1) ){
+                    ptrflm=FLMbuffer;//here we should wrap the pointer around the eventlength
+                    ptrfrm=FRMbuffer;
+                    #ifdef DEBUG//Confirm that pointer wraps to beginning of array
+                                //Test passed!
+                    circularCheck=!circularCheck;
+                    #endif
+                    } else {
+                    ptrflm++;  
+                    ptrfrm++;
+               }
+        } else {
+            onDAQTrigger->signal_set(NULLPOINTER);
+            exit(1);
+        }
+        onDAQTrigger->signal_set(COMPARESIGNAL);
+        #ifdef DEBUG
+        ISRcheck=0;
+        #endif
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Wed Mar 26 05:44:21 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#f88660a9bed1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Mar 26 05:44:21 2014 +0000
@@ -0,0 +1,1 @@
+http://world3.dev.mbed.org/users/mbed_official/code/mbed/builds/824293ae5e43
\ No newline at end of file