• 0
Denci

Pmodmic3 - Strange behaviour or normal?

Question

Posted (edited)

Hi everyone!

I just created an account here because I really need some help. I'm using the 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 example code that I found on your website 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 your website from an example project called "Library and example code" :

https://reference.digilentinc.com/reference/pmod/pmodmic3/start

The code after rewriting it for my board:

Main

#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.

 

sound_one.png

sound_one_again.png

sound_two.png

Edited by Denci

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hi @Denci,

It's hard to say from your setup for sure; the main reason for this is that a rat trap snapping sound does not last very long (presuming it's about the same length as a snap of your fingers, this thread shows it might only last for about 5 milliseconds including the aftershocks), so during your 10 millisecond delay that you have in your main, you can very easily miss the snap happening. I presume the demo that was posted on our website presume a more continuous sound would be used so the implemented delay could be still be used and have the board be verified as working.

Since the ADC runs at 1 MSPS, you can likely reduce the delay to 1 or 2 ms and hopefully get a cleaner result, though you may have to also increase your SPI clock frequency from 1 MHz to the stated maximum of 20 MHz (as per the ADC datasheet) to get this result.

Let me know if you have any more questions.

Thanks,
JColvin

 

Share this post


Link to post
Share on other sites
  • 0

Hi @JColvin,

Thank you for the fast response. I think it might be very possible that the main reason for this is that the sound doesn't last long enough but shouldn't the microphone be able to handle it anyway? I also forgot to mention in my post that I tried using different sample rates. The microphone itself measures between 100Hz-15kHz so I tried for example with a sample rate of 100Hz, 8000 Hz and 15000 Hz. The pictures I posted above were taken when I used a sample rate of 15000Hz if I recall correctly.

I tried using the settings you mentioned above too but I didn't get any better results unfortunately. Do you have any other suggestions?

Share this post


Link to post
Share on other sites
  • 0

Hi @Denci,

I don't have the same setup as you so I do not have a nice graph to show, but I was able to set up a Pmod MIC3 to have data collected to a host board, send the serialized data to a digital-to-analog converter (also 12bits just like the PmodMIC3) which then provides the analog output directly to an audio output module (such as a PmodAMP2). The host board I was using (a microcontroller) had limited storage capabilities so I was only able to store a limited amount of sound to memory before sending it to the audio output at various sampling rates (ranging from 13 kHz to 45 kHz, corresponding to delays between each sample of about 75 microseconds to 22 microseconds, respectively). Each sampling and output rate sounded noisy to me, but I am inclined to think my setup involving lots of jumper wires and cheap headphones on a breadboard didn't help very much. I don't know if the Pmod MIC3 microphone is limited to a 15 kHz frequency as much as the sensitivity goes up; since it continually produces an audio signal there is no real limitation on how often it is sampled.

Regardless, I was able to reliably get a "click" response from snapping my fingers though (presuming I snapped while it was sampling rather than playing out audio data), though I do not know how the response looks on an oscilloscope.

Let me know if you have any questions.

Thanks,
JColvin

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.