When you start an audio project, the sensitiviy of your microphone might be crucial.
Compare two mics using an Arduino UNO R3This is an easy way to compare the characteristics of two microphones. They usually have three pins: Vcc, Gnd and audioOut next to each other.
As you can see in the picture on top, you can attach these two different modules at the same time without the need of an additional breadboard. You can plug them into the analog pins A0 through A5, which also supply the power.
// Mic 1
const byte audioIn1 = A2;
const byte GND1 = A1;
const byte Vcc1 = A0;
// Mic 2
const byte audioIn2 = A3;
const byte GND2 = A4;
const byte Vcc2 = A5;
void setup() {
Serial.begin(115200);
pinMode(Vcc1, OUTPUT);
pinMode(GND1, OUTPUT);
digitalWrite(Vcc1, HIGH);
pinMode(GND2, OUTPUT);
pinMode(Vcc2, OUTPUT);
digitalWrite(Vcc2, HIGH);
ADCSRA = B11000011;
}
void loop() {
#define N 100 // limit for recursion
int s[] = {
#include "tab.h" // read samples
};
for (int k = 0; k < 4 * N; k) {
Serial.print(s[k++]);
Serial.print(" ");
Serial.print(s[k++]);
Serial.println();
}
//Serial.println(F("470 500"));
delay(1000);
}This is file "tab.h" included in the loop (notice: this file includes itself many times):
analogRead(audioIn1),
analogRead(audioIn2),
analogRead(audioIn1),
analogRead(audioIn2),
analogRead(audioIn1),
analogRead(audioIn2),
analogRead(audioIn1),
analogRead(audioIn2),
#if __COUNTER__< N
#include __FILE__
#endifAs you can see in the graph below the amplitudes of the signals are very different.
This obviously does not work with the UNO R3 as it offers only 2 kByte RAM. But with the 32 kByte RAM of the R4 and its higher speed it is no problem to sample 500 int values of all six analog channels and display them on the Serial Plotter.
The only problem is that the Serial Plotter of the new IDE always only shows the last 50 samples. To overcome this limitation, see this Software Instructions.
The program is not much longer:
void setup() {
Serial.begin(115200);
}
void loop() {
#define N 100 // limit for recursion
int s[] = {
#include "tab.h" // read samples
};
for (int k = 0; k < 25 * N; ) {
Serial.print(s[k++]);
Serial.print(" ");
Serial.print(s[k++]);
Serial.print(" ");
Serial.print(s[k++]);
Serial.print(" ");
Serial.print(s[k++]);
Serial.print(" ");
Serial.print(s[k++]);
Serial.print(" ");
Serial.println();
}
delay(1000);
}and this is the tab.h file:
#include "read.h"
#include "read.h"
#include "read.h"
#include "read.h"
#include "read.h"
#if __COUNTER__< N
#include __FILE__
#endifand there is the read.h file which does all the work:
analogRead(A0),
analogRead(A1),
analogRead(A2),
analogRead(A3),
analogRead(A4),Final remarkThese remarks only refer to the AVR version (Arduino UNO R3).
You probably have noticed that incrementing of the COUNTER is done at compile time, not at runtime. Do not use this code for high-quality recording, as the compiler is optimizing storing the array elements in the range of +/-62 places relative to the start of the array. Accessing all the rest requires two more instructions (adiw *** and sbiw ***) per sample. Actually, it must be admitted that doing it this way makes the program not only faster but also much longer. The expanded loop will take 16614 bytes compared to only 2266 bytes for the for-loop of the 32256 bytes of flash memory of the Arduino UNO.
...
analogRead(audioIn1),
6b8: 80 e1 ldi r24, 0x10 ; 16
6ba: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6be: 9a af std Y+58, r25 ; 0x3a
6c0: 89 af std Y+57, r24 ; 0x39
analogRead(audioIn2),
6c2: 81 e1 ldi r24, 0x11 ; 17
6c4: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6c8: 9c af std Y+60, r25 ; 0x3c
6ca: 8b af std Y+59, r24 ; 0x3b
analogRead(audioIn1),
6cc: 80 e1 ldi r24, 0x10 ; 16
6ce: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6d2: 9e af std Y+62, r25 ; 0x3e
6d4: 8d af std Y+61, r24 ; 0x3d
analogRead(audioIn2),
6d6: 81 e1 ldi r24, 0x11 ; 17
6d8: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6dc: 21 96 adiw r28, 0x01 ; 1
6de: 9f af std Y+63, r25 ; 0x3f
6e0: 8e af std Y+62, r24 ; 0x3e
6e2: 21 97 sbiw r28, 0x01 ; 1
analogRead(audioIn1),
6e4: 80 e1 ldi r24, 0x10 ; 16
6e6: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6ea: 23 96 adiw r28, 0x03 ; 3
6ec: 9f af std Y+63, r25 ; 0x3f
6ee: 8e af std Y+62, r24 ; 0x3e
6f0: 23 97 sbiw r28, 0x03 ; 3
analogRead(audioIn2),
6f2: 81 e1 ldi r24, 0x11 ; 17
6f4: 0e 94 fa 01 call 0x3f4 ; 0x3f4 <analogRead>
6f8: 25 96 adiw r28, 0x05 ; 5
6fa: 9f af std Y+63, r25 ; 0x3f
6fc: 8e af std Y+62, r24 ; 0x3e
6fe: 25 97 sbiw r28, 0x05 ; 5
...If you take samples in the standard way like this
for (int k = 0; k < N; k++) {
s1[k] = analogRead(audioIn1);
s2[k] = analogRead(audioIn2);
}the compiled code looks like this
732: 80 e1 ldi r24, 0x10 ; 16
734: 0e 94 fe 01 call 0x3fc ; 0x3fc <analogRead>
738: 89 93 st Y+, r24
73a: 99 93 st Y+, r25
73c: 81 e1 ldi r24, 0x11 ; 17
73e: 0e 94 fe 01 call 0x3fc ; 0x3fc <analogRead>
742: f5 01 movw r30, r10
744: 81 93 st Z+, r24
746: 91 93 st Z+, r25
748: 5f 01 movw r10, r30
74a: f7 e0 ldi r31, 0x07 ; 7
74c: c8 3f cpi r28, 0xF8 ; 248
74e: df 07 cpc r29, r31
750: 81 f7 brne .-32 ; 0x732 <main+0x12c>which has to perform two compares and a conditional jump at the end of each loop.
See also
https://en.wikipedia.org/wiki/Loop_optimization
and
Arduino Oscilloscope Projects by Robert J Davis II published: 10 August, 2015


_ztBMuBhMHo.jpg?auto=compress%2Cformat&w=48&h=48&fit=fill&bg=ffffff)




_3u05Tpwasz.png?auto=compress%2Cformat&w=40&h=40&fit=fillmax&bg=fff&dpr=2)
Comments