• 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

5 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
  • 0
Posted (edited)

Hi @JColvin

Thanks for checking it yourself. I'm not sure what to make of it though. Too bad we don't have the same setup. 

I wanted to give you an update myself. I found out regarding the sample rate that I could run it at most with about 137Hz when the baud rate was set at 9600 because 10 bits per byte on serial, about 7 bytes per output = 7*10*sample_rate = 9600 bits/second, which results in a sample rate of approximately 137. So you need to run the UART at 9600 baud to output this amount of data. So I increased the baud rate and felt like I got the best response when using a baud rate of 115200 which let me use a sample rate of 1920 Hz at most. It still works if you increase the sample rate but if the UART doesn't keep up then the sample rate will drop but not in a completely predictable way so I found it safer to use what was theoretically correct.

The signals still aren't exactly the same but they seem a lot more consistent and stable. Below is a picture when the rat trap snapped at two occasions. I then put them together in paint so don't be confused by the values in X axis. Anyway the red signal represents the microphone and the other three signals represent the X, Y and Z axis of the accelerometer (PMODACL). The signal usually looks like the first one but sometimes it varies like the second one. Mainly the amplitude in the microphone signal gets a bit lower. One other thing I'd like to mention is that both the signal of the microphone and the signals of the accelerometer clip when they reach a height in their amplitude of about +-4000 from their reference value. This is hard to see in the picture especially since they have different reference values. I don't know why they have the same limitation. Is it supposed to be this way? And do you think it is fine even if they clip? Like I should still be able to do an analysis on it? Because the waveform still looks good enough in my opinion.

 

rat trap snap signal.jpg

Edited by Denci

Share this post


Link to post
Share on other sites
  • 0

@Denci,

Your test setup has a large variety of problems.

  1. If the rat trap sound duration is 5ms, it's going to have kHz frequency components.  Viewing the output of the rat trap in frequency should confirm this: short time events have very high frequency components.  If you are subsampling, roughly at anything less than 8kHz for example and still perhaps even then, then you are losing important sound information.  Even at 8kHz, if you aren't using an antialiasing filter, you'll be still losing information.
  2. Are you checking for clipping?  For overdriving the microphone?  The PMic3 is a very sensitive microphone, and so it is easy to overload.  You might wish to check within your design that the output samples never go past 95% of the entire range.
  3. Physics is a really annoying thing.  To expect the exact same waveform from the rat trap from one snap to the next is ... more than you are likely to get.  Remember, if it stinks it's chemistry, if it crawls it's biology, and if it doesn't work it's physics.  Little things like moving the rat trap, opening or closing a cupboard, moving your circuit board, leaning back in your chair and more can adjust the received rat trap waveform.  For this reason, I'd probably use some sort of energy F-test rather than a waveform matching test.  If this is what your instructor wants, though, you might wish to note these realities.
  4. You should be able to push your serial port up to about 1MBaud, sometimes even as high as 4MBaud, using the FTDI devices.  They are rated for 12MBaud, although I've never managed to get speed anywhere near that high
  5. If you really want to check the shape of the rat trap audio waveforms, rather than just energy detection, I might recommend taking a snapshot of the waveform based upon an energy detect trigger.  You can use a simple LED to determine if the snapshot has triggered, and only dump the samples in that case.

Just some thoughts,

Dan

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now