0
$\begingroup$

I just created an account here because I really need some help. I'm using a microphone pmodmic3 with a development board called Ublox C030-U201 which uses the mbed OS. The microphone is working for me but the output it outputs doesn't seem to be accurate. I am doing a project where the goal is to detect when a rat trap goes off. So I was about to gather some data where I manually activate a mechanical rat trap however the output I get from the serialport graph plotter shows me great variation of the signal and its amplitude when the rat trap goes off. I also tried to test with some pre recorded sounds however even those signals aren't identical but vary. Not as much as when I set off the rat trap but it's still not the same signal even though I play the same pre recorded sound over and over again.

So what I'm basically wondering is if this is normal behaviour of a microphone and if not then what could be wrong and how do I fix it so it gives me stable and accurate output?

How am I supposed to detect or find a specific sound (like in this case a rat trap going off) when the output that the microphone gives me varies more or less each time?

I used some example code however I rewrote it so I could use it with my development board. Working with development boards and coding them is also completely new to me so I appreciate any help with the code if something is wrong or missing there.

The code on their website from an example project called "Library and example code"

The code after rewriting it for my board:

Main.cpp

#include "MIC3.h"
#include "mbed.h"


// SPI object and CS pin object
MIC3 myMIC3(PE_6, PE_5, PE_2, PE_11);

// Serial object
Serial pc(USBTX, USBRX);

// Variables
int intValue;
float phyValue;


int main() {

  myMIC3.begin();

  while(1) {

           // Receive an integer value reading of the PmodMIC3
           intValue = myMIC3.GetIntegerValue();

           // Receive an physical, decimal value reading of the PmodMIC3
           phyValue = myMIC3.GetPhysicalValue();

       // Print out these readings
       pc.printf("$%i;\n", intValue); 

       // Wait a bit
       wait_ms(10);
 }

}

MIC3.cpp

/* ------------------------------------------------------------ */
/*              Include File Definitions                        */
/* ------------------------------------------------------------ */
#include "MIC3.h"
#include "mbed.h"


/* ------------------------------------------------------------ */
/*              Procedure Definitions                           */
/* ------------------------------------------------------------ */


/* ------------------------------------------------------------ */
/*        MIC3::MIC3
**
**        Synopsis:
**              
**        Parameters:
**
**
**
**        Return Values:
**                void 
**
**        Errors:
**
**
**        Description:
**          Class constructor. Performs variables initialization tasks
**
**
*/
MIC3::MIC3(PinName mosi, 
                 PinName miso, 
                 PinName sck, 
                 PinName cs) : spi_(mosi, miso, sck), nCS_(cs) {


}

/* ------------------------------------------------------------ */
/*        MIC3::GetIntegerValue
**
**        Synopsis:
**              wIntegerValue = GetIntegerValue();
**        Parameters:
**
**
**        Return Values:
**                uint16_t  - the 12 bits value read from PmodMIC3
**
**        Errors:
**          If module is not initialized (using begin), the function does nothing and returns 0
**
**        Description:
**          This function returns the 12 bits value read from the PmodMIC3, obtained by reading 16 bits through the SPI interface. 
**
**
*/
uint16_t MIC3::GetIntegerValue()
{
    uint16_t wResult = 0;
    uint8_t *pbResult = (uint8_t *)&wResult;
    //if(pdspi != NULL)
    //{
        // make SS active
        nCS_ = 0;       

        // read from SPI, two separate 8 bits values
        *(pbResult + 1) = spi_.write((uint32_t) 0); // high byte
        *pbResult = spi_.write((uint32_t) 0);   // low byte

        // make SS inactive
        nCS_ = 1;
    //}
    return wResult;
}

/* ------------------------------------------------------------ */
/*        MIC3::GetPhysicalValue
**
**        Synopsis:
**              dPhysicalValue = GetPhysicalValue();
**        Parameters:
**              - float dReference - the value corresponding to the maximum converter value. If this parameter is not provided, it has a default value of 3.3.
**                                  
**
**        Return Values:
**                float - the value corresponding to the value read from the PmodMIC3 and to the reference value
**
**        Errors:
**          If module is not initialized (using begin), the function does nothing and returns 0
**
**        Description:
**          This function returns the value corresponding to the value read from the PmodMIC3 and to the selected reference value.
**          If the function argument is missing, 3.3 value is used as reference value.
**
**
*/
#ifdef MIC3_FLOATING_POINT

float MIC3::GetPhysicalValue(float dReference)
{
    uint16_t wIntegerValue = GetIntegerValue();
    float dValue = (float)wIntegerValue * (dReference /((1<<MIC3_NO_BITS) - 1));
    return dValue;
}

#endif

/* ------------------------------------------------------------ */
/*        MIC3::begin
**
**        Return Values:
**                void 
**
**        Description:
**              This function initializes the specific SPI interface used, setting the SPI frequency to a default value of 1 MHz.
**
**
*/
void MIC3::begin() {

    spi_.frequency(1000000);
    spi_.format(8,3); 

    nCS_ = 1;

    wait_us(500);

}

MIC3.h

/************************************************************************/
/*  File Description:                                                   */
/*  This file declares the MIC3 library functions and the constants */
/*  involved.                                                           */
/*                                                                      */
/************************************************************************/

#ifndef MIC3_H
#define MIC3_H

#define MIC3_FLOATING_POINT

/* ------------------------------------------------------------ */
/*              Include File Definitions                        */
/* ------------------------------------------------------------ */
#include "mbed.h"

/* ------------------------------------------------------------ */
/*                  Definitions                                 */
/* ------------------------------------------------------------ */
#define MIC3_NO_BITS        12

/* ------------------------------------------------------------ */
/*                  Procedure Declarations                      */
/* ------------------------------------------------------------ */


class MIC3 {

private: 

        SPI        spi_;
        DigitalOut nCS_;

public:

/**
         * Constructor.
         *
         * @param mosi mbed pin to use for MOSI line of SPI interface.
         * @param miso mbed pin to use for MISO line of SPI interface.
         * @param sck mbed pin to use for SCK line of SPI interface.
         * @param cs mbed pin to use for not chip select line of SPI interface.
*/

        MIC3(PinName mosi, PinName miso, PinName sck, PinName cs);

    uint16_t GetIntegerValue();

#ifdef MIC3_FLOATING_POINT
    float GetPhysicalValue(float dReference = 3.3);
#endif

    MIC3();
    void begin();
};



#endif

Here are also three pictures showing the output I get on the serialport graph plotter from two different pre recorded sounds I tested with. Picture 1 and 2 shows the output of the same sound. Picture 3 is the output of a different sound and looked much better than the other one.

Picture 1

Picture 2

Picture 3

$\endgroup$
  • $\begingroup$ You are sampling every 10ms, meaning $f_s=100Hz$? (while-loop in the first file) This cannot yield any useful output, as it is much to slow. Try like 20us. $\endgroup$ – Max Mar 14 at 9:05
  • $\begingroup$ Thank you for the response Max. I did try with a different sampling frequency earlier too but it didn't help. I double checked now with 20us like you suggested but it was still inaccurate. Do you have any other suggestions that may help? Also does it really work if I set a sampling frequency which doesn't correspond to the microphones specifications? The microphone can handle frequencies in the range of 100Hz-15kHz. $\endgroup$ – Denci Mar 14 at 11:14
  • $\begingroup$ mechanical systems can bounce a lot. you also don’t say anything about analog amplification and filtering or the mechanical setup of your microphone. there can be multiple reasons why you don’t get a clean signal $\endgroup$ – Stanley Pawlukiewicz Mar 14 at 13:58
  • $\begingroup$ Thanks for the response Stanley. The microphone sits on a module with a built in ADC that is capable of 1MSPs so I receive a digital signal to the development board. As for the mechanical setup I have the microphone connected to the board and the board is set inside a rectangular metal box. However I have tried by simply putting the microphone on the table next to my smartphone from which i play the pre recorded sounds from and it doesn't change much. Regarding filtering I'm not sure what you mean. I haven't done any kind of filtering myself. $\endgroup$ – Denci Mar 14 at 15:17
  • $\begingroup$ If you would like to check some specifics that I may not have mentioned then you can look up the microphone. It is called SPA2410LR5H-B and the ADC, ADCS7476. $\endgroup$ – Denci Mar 14 at 15:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.