Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: C12832_lcd crossCorrelation mbed-rtos mbed
Revision 0:025037057a21, committed 2014-03-26
- 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
--- /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