PlainDSP (Part 4)
Here is the autonomous version of the sound meter which principle is described in PlainDSP (Part 3). The picture below shows the full schematics of the device
And here is the code of MicroSNDMTR_LCD, which includes the auto-ranging algorithm
/* MicroSNDMTR_LCD: Micro sound meter connected to LCD 2x16 display Exemple of use of the PlainDSP and PlainLCD libraries Tested with ATmega328 powered Arduino Copyright (C) 2012-2013 Didier Longueville This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <PlainDSP.h> /* Include DSP library */ #include <PlainLCD.h> /* Include LCD library */ /* Create objects */ PlainDSP DSP; PlainLCD LCD; /* Acquisition parameters */ const uint16_t _samples = 128; /* Max value depends upon available memory space */ const double _samplingFrequency = 22100.0; /* From 0.125 Hz to 80 kHz */ const uint16_t _defAdcChannel = 0; /* From 0 to 5 on ATmega328 powered Arduinos */ const uint16_t _refVoltage = DSP_REF_VOL_EXTERNAL; /* External: 3.3V */ const uint8_t _options = (DSP_OPT_DIS_TIM_0 | DSP_OPT_DIS_TIM_2 | DSP_OPT_NOI_CANCELLER); uint8_t _adcChannel; const float _refPressure = 20E-6; /* Custom data */ const float _vGains[] = {50.0, 10.0, 10.0}; /* gain of first stage on first place and so on */ const float _microphoneSensitivity = 2.5; /* unit Pa/mV, read from microphone datasheet */ /* Control led parameters */ #define LED_PORT &PORTB #define LED_PIN PINB5 void setup() { /* Initialize LCD: pins must belong to the same port in the order: data4, data5, data6, data7, reg_select, chip_enable, port connect the R/W pin to ground Attach contrast pin to trim pot */ LCD.InitializeLCD(2, 3, 4, 5, 6, 7, &PORTD); LCD.ClearDisplay(); /* Align. scale: 1234567890123456 */ LCD.PrintString("* MICRO DB MTR *", 1); /* Set data acquisition parameters */ DSP.SetAcquisitionEngine(_defAdcChannel, _refVoltage, _samplingFrequency, _samples, _options); }; void loop() { /* Start reading the most amplified signal from 3d stage */ _adcChannel = 3; uint8_t saturated = 1; /* Reads preamlifier stages sequentially, starting from the highest gain */ do { /* Set channel */ _adcChannel -= 1; /* Set channel */ DSP.Channel(_adcChannel); /* Acquire data */ DSP.GetScanData(); /* Check signal */ if ((DSP.Min() >= 1.0) && (DSP.Max() <= 1023.0)) { saturated = 0; } } while (saturated && (_adcChannel != 0)); /* Compute gain factor */ float gain = 1.0; for (uint8_t i = 0; i <= _adcChannel; i++) { gain *= _vGains[i]; } /* Compute scaling factor for mV */ float scalingFactor = (3.3 / (1.024 * gain)); /* Reset offset */ DSP.ResetOffset(); /* Rescale data */ DSP.Gain(scalingFactor); /* Compute and print statictics */ float rmsSignal = DSP.RMS(); float rmsPressure = (20 * log10(rmsSignal / (_refPressure * _microphoneSensitivity))); /* Print RMS in dB */ LCD.ClearBuffer(); LCD.InsertFloat(rmsPressure, 1, 4, LCD_ALI_RIGHT); LCD.InsertString("dB RMS", 5, LCD_ALI_LEFT); LCD.InsertString("[g:", 12, LCD_ALI_LEFT); LCD.InsertInteger((_adcChannel + 1), 15, LCD_ALI_RIGHT); LCD.InsertString("]", 16, LCD_ALI_LEFT); LCD.PrintBuffer(1); /* Print RMS in mV */ LCD.ClearBuffer(); LCD.InsertFloat(rmsSignal, 3, 5, LCD_ALI_RIGHT); LCD.InsertString("mV RMS", 6, LCD_ALI_LEFT); LCD.PrintBuffer(2); /* Uncomment next lines as appropriate */ // while(true); /* Run Once */ delay(1000); /* Repeat after delay */ };
Here are two pictures of the device. The device features an Arduino UNO board as well as a protoshield fitted with a small breadboard which receives the analog components. The LCD is wired to the shield too. The device is powered by a pack of batteries for autonomous operation.
On the first line of the display is printed the sound signal strength expressed in dB RMS. At the end of the line is an indicator of the number of gain stages involved. On the second line is the signal strength expressed in mV RMS.
The next picture is a closer look at the breadboard. Although it may look messy, the principle of wiring keeps the connexions short and the circuit is compact.
Hello,
Is it possible to aplly A Weighting in code, in order the result to be in db (A) ?
Thanks
Yes it is definitely possible: dBA, normalized dB, etc.
hi.. can or not from this code i want to do recording? I plan to record in sdcard some audio and do some analysis in Matlab.. It is possible to do with PlainDSP and PlainSDC?
Thanks