PDA

View Full Version : Resonant frequency of an oscillating circuit



RobinLi
03-03-2016, 11:56 AM
Hello,
I'm trying to measure the impedance of a loudspeaker. The resonant frequency where the impedance has its maximum should be at about 60Hz.
So I programmed a sine sweep from 20 to 120Hz and send it through a resistor in series to the loudspeaker. Between them I am trying to measure the av voltage with analogread() but it doesn't work. Is there an other way to measure it? I Think the problem is, that a measure at a very short time the DC voltage....


#include <Audio.h> // Bibliotheken
#include <Wire.h> //
#include <SPI.h> //
#include <SD.h> //
#include <SerialFlash.h> //
///////////////////////////////////////////////////////////////////////////// Audio Library
AudioSynthWaveformSine sine; // Sinus
AudioOutputI2S LineOut; // Output = LineOut
AudioConnection patchCord1(sine,0, LineOut,1); // Sinus -> LineOut + Headphone(r)
AudioConnection patchCord2(sine,0, LineOut,0); // Sinus -> LineOut + Headphone(l)
AudioControlSGTL5000 sgtl5000_1; // Audioshield
///////////////////////////////////////////////////////////////////////////// Variablen
int f_i; // Laufindex der Frequenz
int f_start = 20; // Startfrequenz
int f_end = 120; // Endfrequenz
int dt; // Delaytime
int voltage; // Spannung am 1K Widerstand
///////////////////////////////////////////////////////////////////////////// Setup für den Sweep
void setup()
{
AudioMemory(20); // 20*128Bit reserviert
sgtl5000_1.enable(); // Audio Shield aktivieren
sgtl5000_1.volume(1); // Lautstärke zwischen 0-1
sine.amplitude(0.1); // Amplitude des Sinus
}

///////////////////////////////////////////////////////////////////////////// Loop
void loop()
{
for(f_i=f_start;f_i<=f_end;f_i++) // Schleife von Start- bis Endfrequenz
{
sine.frequency(f_i); // Frequenz des Sweeps
voltage= analogRead(14);
Serial.print(f_i);
Serial.print("\t");
Serial.println(voltage);
delay(1000/f_i); // Jede Frequenz wird genau eine Periodenlänge gespielt
}
}

PaulStoffregen
03-03-2016, 01:39 PM
Well yeah, analogRead measures only once at 1 point within the waveform, so this very simple way can't work.

How you're connecting this matters, and how you connect back to Teensy is important. You could easily kill your Teensy if the speaker produces a large voltage unexpectedly.

To do this well, you're probably going to need a power amplifier to drive the speaker with several watts of power. The amp should always produce the same voltage... you'll be able to observe the speaker resonance by the current it draws from the amp. To do that, I'd try putting a small resistor, like half to 1/10th an ohm, in series with the speaker. For starters, I'd try using a true RMS multimeter with mV AC mode (cheap meters don't have this... you'll need a good one). Hopefully you'll see different voltages at different frequencies. For measuring with Teensy, I'd use an audio isolation transformer to couple the voltage from the resistor to the line-in on the audio shield. Then you can feed the I2S input object to the RMS analysis object, to give you a really good reading. You could also adjust the SGTL5000 input signal level range as needed.

PaulStoffregen
03-03-2016, 01:43 PM
About speaker resonance... I'm not an expert on such things, but I'd expect the resonant frequency will change quite a lot depending on the enclosure you put the speaker into. Supposedly ported enclosures change resonance frequency depending on the length of the tube on the port.

Also, be careful about driving any speaker with a continuous sine wave at substantial power. You should probably stay under 10% of the speaker's rated power. I tried this sort of thing many years ago and discovered many speakers can't handle anywhere near their rated power level when driving with a continuous sine wave.

RobinLi
03-14-2016, 09:50 AM
Hello, thanks for your answer. I need the speaker only for measuring and don't want to play any sound with it. The resonance depends on many factors and I want to change them to measure different resonance frequencies for different conditions. How much voltage and current can the Line In connection stand? The RMS analyses should work I think. That's what I need ;)

PaulStoffregen
03-14-2016, 01:45 PM
How much voltage and current can the Line In connection stand?

The SGTL5000 chip on the audio shield has programmable voltage levels. You can find this info in the design tool documentation:

http://www.pjrc.com/teensy/gui/?info=AudioControlSGTL5000

On the right-side panel, scroll down to "Signal Levels".

The line-level input is fairly high impedance. The SGTL5000 datasheet (http://www.pjrc.com/teensy/SGTL5000.pdf) says 100K. I recall seeing some errata that it can be lower (the datasheet gives no min or max, only 100K typical). So you might plan on as low as 10K. If you apply 1 volt to a 10K resistance, you can expect 0.1mA.

PaulStoffregen
03-14-2016, 01:47 PM
Regarding maximums, you should probably avoid applying more voltage that whatever signal level setting you use.

You can probably expect more than 3.3 volts peak-to-peak to damage the chip.

RobinLi
03-14-2016, 04:02 PM
okay, I connected the loudspeaker in series with a resistor to the Line In and the point between the resistor and loudspeaker to the Line In. But it's not what I expected...


#include <Audio.h> // Bibliotheken
#include <Wire.h> //
#include <SPI.h> //
#include <SD.h> //
#include <SerialFlash.h> //
///////////////////////////////////////////////////////////////////////////// Audio Library
AudioSynthWaveformSine sine; // Sinus
AudioOutputI2S LineOut; // Output = LineOut
AudioAnalyzeRMS RMS; // RMS for the voltage on the resistor
AudioInputI2S Input_RMS; // Input for RMS;
AudioConnection patchCord1(sine, 0, LineOut, 1); // Sinus -> LineOut + Headphone(r)
AudioConnection patchCord2(sine, 0, LineOut, 0); // Sinus -> LineOut + Headphone(l)
AudioConnection patchCord3(Input_RMS, 0, RMS, 0);// RMS -> Input_RMS;
AudioControlSGTL5000 sgtl5000_1; // Audioshield
///////////////////////////////////////////////////////////////////////////// Variablen
int f_i; // runningindex for frequency
int f_start = 20; // Startfrequency
int f_end = 120; // Stopfrequency
int dt; // delaytime
double voltage = 0.00000000; // voltage at 1k resistor
///////////////////////////////////////////////////////////////////////////// Setup for sweep
void setup()
{
AudioMemory(20); // 20*128Bit served
sgtl5000_1.enable(); // activate Audio Shield
sgtl5000_1.volume(5); // volume between 0-1
sine.amplitude(1); // amplitude of Sine
Serial.begin(9600);
}

///////////////////////////////////////////////////////////////////////////// Loop
void loop()
{
for (f_i = f_start; f_i <= f_end; f_i++) // Loop from start- bis stopfrequency
{
sine.frequency(f_i); // frequency of sweep
voltage = RMS.read();
voltage = voltage;
Serial.print(f_i);
Serial.print("\t");
Serial.println(voltage,5);
delay(300); // Every frequency played for T=1/f
}
}


and this is the autput of the serial monitor:

20 0.01328
21 0.00655
22 0.00599
23 0.00612
24 0.00610
25 0.00619
26 0.00619
27 0.00624
28 0.00632
29 0.00639
30 0.00643
31 0.00649
32 0.00661
33 0.00666
34 0.00675
35 0.00680
36 0.00691
37 0.00703
38 0.00709
39 0.00722
40 0.00727
41 0.00742
42 0.00759
43 0.00765
44 0.00780
45 0.00790
46 0.00806
47 0.00829
48 0.00839
49 0.00858
50 0.00884
51 0.00894
52 0.00931
53 0.00960
54 0.00988
55 0.01026
56 0.01058
57 0.01093
58 0.01132
59 0.01148
60 0.01165
61 0.01170
62 0.01156
63 0.01151
64 0.01127
65 0.01118
66 0.01100
67 0.01086
68 0.01079
69 0.01070
70 0.01069
71 0.01061
72 0.01060
73 0.01063
74 0.01066
75 0.01065
76 0.01065
77 0.01070
78 0.01073
79 0.01077
80 0.01083
81 0.01086
82 0.01095
83 0.01100
84 0.01105
85 0.01111
86 0.01116
87 0.01122
88 0.01129
89 0.01135
90 0.01141
91 0.01151
92 0.01155
93 0.01156
94 0.01161
95 0.01165
96 0.01173
97 0.01182
98 0.01182
99 0.01194
100 0.01196
101 0.01202
102 0.01210
103 0.01210
104 0.01223
105 0.01228
106 0.01231
107 0.01241
108 0.01244
109 0.01253
110 0.01255
111 0.01265
112 0.01270
113 0.01277
114 0.01280
115 0.01285
116 0.01295
117 0.01298
118 0.01304
119 0.01307
120 0.01315


The value rises from 20 to 120Hz and the amplitude is very low. That's a bit confusing. Can you help me?

PaulStoffregen
03-14-2016, 04:24 PM
For initial testing, perhaps run File > Examples > Audio > HardwareTesting > PassThroughStereo. See if the voltage you apply to the line in is copied to the line out, just to make sure your hardware is functioning properly.

Also check the sgtl5000_1.inputSelect(myInput); line....

RobinLi
03-22-2016, 02:51 PM
It works, thank! The Resonance Frequency should be 43Hz. Here are some plots from MATLAB with my measured impedances. Its not really stable. Do you think a Low-Pass-Filter could help or do you have better ideas? Any help is welcome!

edit: Higher voltage should work.

6787

Theremingenieur
03-22-2016, 11:15 PM
I see a potential problem in the timing. After changing the frequency, the speaker chassis will need some time to "swing in" until the impedance is not longer transitioning but becomes stable. Second question is the time window needed for the RMS measurement. I have no info about the internal working of that object and the number of samples which are taken into account, but measuring over a single cycle would already take 50ms @20Hz and I'd take at least 10 cycles and average these to get more stable results.

Thus, a delay() should not be at the end of the loop, but after sine.frequency(f_i); and before you start measuring.

RobinLi
03-23-2016, 09:22 AM
Yes thats true, I forgot to mention, that I did this already. I gave the wave two cycles to swing in.


void loop()
{
for (f_i = f_start; f_i <= f_end; f_i++) // Loop from start- to stopfrequency
{
sine.frequency(f_i); // frequency of sweep
delay(2000/f_i); // Every frequency played for T=2/f
voltage = RMS.read();
voltage = voltage*64;
//Serial.print(f_i);
//Serial.print("\t");
Serial.print(voltage,5);
Serial.println(";");
}
Serial.println("--------------");
}

Today I will try to use a opamp to get higher voltage. That should solve the problem.

RobinLi
03-23-2016, 10:47 AM
Now it looks much better. unfortunately the contacts of the breadboard are not the best, so I guess thats the reason why some measurements are still a bit shaky.
Or are there other ideas whats wrong and how I can solve it?

6799

Theremingenieur
03-23-2016, 04:22 PM
I'd solve that mathematically... doing 10 sweeps, storing the results in an array and then averaging.

RobinLi
04-01-2016, 01:42 PM
Hello, I put an Capacitor in parallel with the voltage source and its much better now. But now I have an other problem: I have to control a servo motor via PWM with the Teensy. Unfortunately the PWM Signal is also on the loudspeaker. I don't know why but you can hear it. For testing I used the Servo Sweep example and my circuit looks like that. 6894

Do you have an idea, whats the problem?
Thanks, Robin.