Arduino Measurement Lab
Arduino Measurement Lab
Burkhard Kainka
Copyright © 2022 Burkhard Kainka
All rights reserved.
ISBN: 9798831847703
Independently published
Foreword
After several attempts with other systems the choice fell on the Arduino
Nano. On this basis, a PC interface as versatile as possible for measurement
and control is to be developed. It simply hangs on a USB cable and,
depending on the software, forms the measuring head of a digital voltmeter
or PC oscilloscope, a signal generator, an adjustable voltage source, a
frequency counter, an ohmmeter a capacitance meter, a characteristic curve
recorder and much more.
The circuits and methods collected here are not only relevant for exactly
these tasks in the electronics laboratory, but many details can also be used
in completely different contexts. Often one encounters complex tasks in the
field of measurement technology during development work with
microcontrollers. In many cases, the methods from this book can then be
used. You have a starting point and can develop the software in the desired
direction.
Stay creative!
Burkhard Kainka
1 Preparations
1.1 Choice of controller
1.2 The Arduino Nano
1.3 Voltage supply
2 Preliminary tests
2.1 Port outputs
2.2 Analog inputs and outputs
2.3 The serial plotter
2.4 PWM signal generator
2.5 A sawtooth generator
2.6 Direct digital synthesis
3 GCC programming
3.1 Fast port outputs
3.2 PWM output
3.3 Timer interrupt
3.4 Fast sine wave generator
3.5 AD buffering
4 The MSR Laboratory
4.1 Dual-channel DDS generator
4.2 Binary serial transmission
4.3 Frequency setting
4.4 Deflection times and dual-channel operation
4.5 Triggering
4.6 DC voltage output
5 Additional inputs and outputs
5.1 Phase adjustment of the DDS
5.2 Signal generator up to 8 MHz
5.3 Frequency measurement
5.4 Additional analog inputs
5.5 Capacitance measurement from 1 pF
5.6 Resistance measurement up to 1 MΩ
5.7 Resistance measurement from 1Ω
6 Measurements and experiments
6.1 Subsampling
6.2 Investigation at higher frequencies
6.3 Measurement on a synchronous signal
6.4 Frequency response of a low-pass filter
6.5 An LC low pass
6.6 LC resonance
6.7 Transistor test circuit
7 Firmware extensions
7.1 Alternative DDS functions
7.2 Reduced amplitude
7.3 Triangle and sawtooth
7.4 XY representation
7.5 Frequency sweep
7.6 Ramp function
7.7 Measurement of characteristic curves
8 Application examples
8.1 The emitter follower
8.2 Emitter follower as impedance converter
8.3 Sallen key filter
8.4 Beat generator
8.5 Operational amplifier
8.6 Voltage doubling
8.7 All-pass filter
8.8 Bandpass filter
Appendix
List of components used
1 Preparations
The first considerations for a universal measuring system went in the
direction of a digital PC oscilloscope combined with a signal generator. The
decisive factor is the achievable cut-off frequency.
The experiments went quite far, but in the end some interfering factors
came to light. For the chosen tasks it is important that the measuring sample
and the outputs run in a fast and very accurate time frame. Sampling rates
up to 100 kHz at a PWM frequency of 125 kHz with two output and two
input channels each were achieved. But there was a permanent slight flutter
in the time frame, the cause of which was to be found in the simultaneous
demands of the USB interface. If the actual measurement and signal output
is executed in a timer interrupt with 100 kHz, no other interrupt should be
allowed. As soon as a second timer interrupt or as in this case a USB
interrupt is added, the absolutely uniform time grid is over.
There are also other STM controllers. A development board STM32 Nucleo
with a Cortex-M0 controller F040R8 with up to 64 MHz was used. The
crucial difference was that it has no internal USB interface and transfers its
data via the serial interface. The controller transmits its data only when it is
measured and is hardly loaded by it serial data transmission. In fact, this
completely eliminated signal processing flutter. Actually the project was on
a good way. But I would have had to build a separate board with the
STM32 controller and a USB/serial converter, which would have been
relatively expensive in the end.
When you enter the 32-bit world, the high clock rate is usually the first
thing that catches your eye. This should allow fast signal processing in real
time. However, disappointment often follows. The more complex software
eats up the advantage. This and the procurement problems have led to
existing 8-bit controllers becoming more interesting again.
That was four attempts with the same goal. The winner so far has been the
ATmega328 on an Arduino Nano. The system is very cheap and widely
used. Many readers should already have this board. However, this is not
necessarily true for Bascom. Therefore now the wish came up to work with
the Arduino IDE if possible. However, Arduino sketches are not real-time
capable, because there are still things going on in the background that you
don't necessarily see. This is the reason why Bascom is much faster than the
Arduino-C in most cases.
The decisive breakthrough came with the realization that the Arduino IDE
can also be used for pure C. This makes it possible to use the familiar
programming environment with its reliable bootloader and simple
operation, while at the same time achieving maximum working speed of the
controller.
You don't need much more than a solderless breadboard and a nano. There
is still room on the board for an operational amplifier and other components
for filters or circuits to be tested. This also demonstrates the correct use of
digital measurement devices. Many possible measurement errors can occur
in the same way with this simple low sampling rate device as with a fast
DSO. If you work with it on a small scale, you will be less likely to be
surprised on a large scale. Working with the small measurement laboratory
is thus at the same time a useful basic course.
All measurement programs presented in this book run on the Arduino Uno
as well as on the Arduino Nano. It only depends on the controller, the
ATmega328. The Arduino Nano has the advantage that it can be put on a
breadboard together with other components.
Arduino Nano on the breadboard
Besides the original Arduino Nano, there are several very inexpensive
replicas. All of them use the same pinout and can be used for the
experiments in this book. They differ in some technical details and often
also in the USB socket. Mostly a USB mini connector is used. It has the
advantage of greater mechanical stability, which benefits experimental
work. However, USB micro or USB C cables are now more common.
The original Arduino Nano uses a USB converter FT232RL, whose internal
voltage regulator also provides the 3.3 V to the outside. Besides there are
several replicas which use the cheaper USB converter CH340. It also has a
3.3V output, but with less current. Some replicas therefore use an additional
voltage regulator, others use the output of the CH340 or leave the 3.3V
output completely free.
Like any Arduino, the Nano can get its operating voltage of 5 V either from
the USB or from an external voltage source with at least 7 V to Vin. The
original Nano uses a Schottky diode in series with the USB supply, whose
forward voltage reduces the operating voltage by up to 0.3 V. This diode
prevents damage to the PC if a higher voltage is ever accidentally applied to
the NANO.
Overvoltage, something like that can never happen to me, everyone would
say. But during the work on this book it happened nevertheless. Because the
Arduino Nano was programmed as an oscilloscope and as a signal generator
adjustable within wide limits at the same time, it should examine the
switching behavior of a reed relay, which was connected to the laboratory
power supply with 30 V via a switching transistor. There must have been a
mistake and the 30 V came directly to the analog input A0 and from there
via the internal protection diode at the port connector of the ATmega to the
VCC line. The nano survived this almost unharmed, only the pin A0 had an
internal termination against GND afterwards. But a USB hub and a webcam
connected to it at the same time were destroyed. Later it was found out that
the USB hub had a series diode, which probably prevented an even bigger
damage to the PC.
By the way, the replica version of the Nano mostly used in Franzis
packages would have prevented this damage just like the original Nano,
because both have the Schottky diode in series with the USB supply.
Another pitfall lurks with all Nanos: The VIN connection normally remains
free when the controller is supplied via USB. If you connect it to GND, the
5V voltage regulator gets into a forbidden state, which can lead to a latchup.
The regulator then triggers like a thyristor and can get extremely hot. Also a
relatively large capacitor between VIN and GND can trigger this state at the
moment of power-up by its charging current. So this pin should be left free
if you don't want to connect an external power supply.
Whenever I want to test an Arduino, I first load the program Blink from the
examples (group 01. Basics).
void setup() { pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(1000);
digitalWrite(LED_BUILTIN, LOW);
delay(1000);
}
The built-in LED will then flash at a rate of 0.5 Hz, as it is turned on for
one second and turned off for one second.
The internal LED is connected with its series resistor to pin D13. Here you
can connect an additional external LED with its own series resistor. With
modern, high-efficiency LEDs, a low current far below 1 mA is sufficient.
Therefore a resistor of 10 kΩ is suggested here.
Additional connection of an external LED
Now you can experiment with the waiting times. Is flashing at 25 Hz still
clearly perceptible to the eye? The waiting times must be reduced to a total
of 40 ms.
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(20);
digitalWrite(LED_BUILTIN, LOW);
delay(20);
}
A loop without any waiting times gives an even better impression. The
decisive question is what speed is then achieved. The test first shows that
the LED seems to be permanently lit. And an audible sound is no longer
produced.
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
digitalWrite(LED_BUILTIN, LOW);
}
int sensorValue = 0;
int outputValue = 0
void setup() {
Serial.begin(9600);
}
void loop() {
sensorValue = analogRead(analogInPin);
outputValue = map(sensorValue, 0, 1023, 0, 255);
analogWrite(analogOutPin, outputValue);
Serial.print("sensor = ");
Serial.print(sensorValue);
Serial.print("\t output = ");
Serial.println(outputValue);
delay(2);
}
For the first tests it is a good idea to connect an LED to D9. Additionally
you can connect the piezo transducer to get an impression of the PWM
signal.
If you start the serial plotter instead of the serial monitor, you get a diagram
of the measured data. Text and numbers are separated and the numerical
values are plotted in different colors. The plotter automatically adjusts its y-
axis to the occurring numerical values. The x-axis has a width of 500
measuring points.
The Sketch was reduced to the absolute minimum in the interest of higher
speed. In addition, the highest standard baud rate was set to 115200 bits per
second.
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.println(analogRead(A0));
}
void loop() {
Serial.println(analogRead(A0));
}
Despite the low PWM frequency, the basic principle of digital signal
generation can already be tested. One outputs new voltage values of the
desired waveform in regular intervals. The PWM output serves here as a
simple DA converter and needs in addition an RC element as a low pass
filter.
void setup() {
Serial.begin(1000000);
}
void loop() {
Serial.println(analogRead(A0));
out++;
analogWrite(9, out);
}
void setup() {
Serial.begin(1000000);
for (n=0; n<256; n++){
sinus[n]= 127+127*sin(PI*2*n/256);
}}
void loop() {
Serial.println(analogRead(A0));
phase += 256;
out = sinus[phase >> 8];
analogWrite(9, out);
}
The sinusoidal signal filtered with 100 kΩ and 100 nF
In the same loop not only the DDS signal is generated, but also the
measuring points for the oscillogram are measured and sent. The
oscillogram shows a sine function and remnants of the PWM signal, using a
low pass filter with 100 kΩ and 100 nF. It is noticeable that there are
smooth spots, which should actually be at the highest and lowest points of
the sine, where the PWM signal changes to a DC voltage. However, the
low-pass filter provides a phase shift, so that the extreme values are reached
only a little later.
The sinusoidal signal in this case is very slow and has a frequency of only
about 16 Hz. It is difficult to determine the frequency from the self
measurement because the measurement loop runs slower by an unknown
factor due to the additional calculation steps. However, the image recorded
with an external oscilloscope shows that an undisturbed sinusoidal signal of
low frequency is produced overall.
The generated sinusoidal signal
The experiments so far show that a common Arduino sketch is too slow to
process signals in an interesting range. So the task must be to increase the
speed. This is achieved by pure C programming and an optimization of all
steps. The end result is an extensive measurement lab with a sampling rate
of 62.5 kHz.
3 GCC programming
The first tests have shown that Arduino sketches are not really real-time
capable. Things run in the background that you can't see. Many time-critical
tasks cannot be solved this way. One way out is that the IDE can also
compile pure C code, because the GCC compiler is used in the background.
Usually every sketch contains a function void setup() and a function void
loop() . If you delete these two, everything stays clean. Instead a function int
main(void)is needed.
The first pure C program is to switch port B0 (Arduino D9) and generate a
fast square wave signal. The whole port is written with one command, so
that also fast 8-bit outputs are possible.
int main(void)
{
DDRB=255;
while(true){
PORTB=1;
PORTB=0;
}}
The ATmega328 has three timers, which can form two PWM outputs each.
Only timer 1 is a 16 bit timer. It can generate PWM signals with a
resolution of 10 bits. Timers 0 and 2 generate 8-bit PWM signals. Arduino
sketches use timer 1 with the outputs at B1 and B2 in the interest of
unifying all six PWM outputs also with a resolution of 8 bits. Here now the
timer 0 shall be used to keep the timer 1 free for other tasks.
All three timers can be used for quite different tasks. The data sheet reveals
which registers must be used in detail. For a fast PWM with timer 0 the
control register TCCR0A must be written with 0xA3. The timer is
controlled directly by the 16 MHz clock of the controller or by a prescaler.
The highest speed is reached with TCCR0B = 0x01 . Now there are two PWM
outputs at the ports PD5 (OC0B) and PD6 (OC0A), which are controlled by
the registers OCR0B and OCR0A. Both are initially set to half the final
value 128.
Controller connections and functions
At pin D5 (OC0B) the PWM signal can be measured with a pulse width of
50% and a frequency of 62.5 kHz. The PWM frequency results with 16000
kHz / 256 = 62.5 kHz, because a full period needs 256 clocks. So this is the
fastest output if you want to have a resolution of 8 bits.
The first PWM output OC0A (PD6) is incremented in a fast loop. However,
the oscillogram shows that counting up is considerably faster than the PWM
output. Therefore there are only three outputs per 256 counting steps.
With this slowing down one recognizes now the sawtooth signal formed by
the low pass filter with approx. 160 Hz. By shortening the counting loop,
higher frequencies can be obtained.
unsigned char d;
ISR (TIMER0_OVF_vect)
{
d+=8;
OCR0A=d;
}
int main(void)
{
unsigned char n;
DDRD = 254;
TCCR0A = 0xA3; //Timer0 Fast PWM at PD5/6
TCCR0B = 0x01; //16 MHz
TIMSK0 = 0x01; //Timer0 Overflow Interrupt
OCR0A =128;
OCR0B =128;
be();
while(true);
}
From here it is only a small step to a sine DDS generator. First, an array
unsigned char dds[256] is declared and filled with 256 values of a full sine wave.
The sine function used in it comes from the Math library, which is included
at the beginning with #include < math.h>. In addition, a 16-bit wide phase acc
ph is required, which is repeatedly incremented by a constant amount in the
timer interrupt. The upper eight bits of the phase accumulator then serve as
address pointer into the sine table.
ISR (TIMER0_OVF_vect)
{
ph+=500;
OCR0A=dds[ph>>8];
}
int main(void)
{
unsigned int n;
for (n=0;n<256;n++) dds[n]= 127+127*sin(PI*n/128.0);
DDRD = 254;
TCCR0A = 0xA3; //Timer0 Fast PWM at PD5/6
TCCR0B = 0x01; //16 MHz
TIMSK0 = 0x01; //Timer0 Overflow Interrupt
OCR0A =128;
OCR0B =128;
be();
while(true);
}
A DDS sinus signal with 500 Hz
Instead of the previous sawtooth signal, a sinusoidal signal with 1953 Hz is
now generated. You can change the constant value 500 within wide limits to
create completely different frequencies.
ISR (TIMER0_OVF_vect)
{
PORTD |= 4;
ph+=500;
OCR0A=dds[ph>>8];
Serial.println(ADCH);
PORTD &= ~4;
}
int main(void)
{
unsigned int n;
Serial.begin(1000000);
for (n=0;n<256;n++) dds[n]= 127+127*sin(PI*n/128.0);
DDRD = 254;
TCCR0A = 0xA3; //Timer0 Fast PWM at PD5/6
TCCR0B = 0x01; //16 MHz
TIMSK0 = 0x01; //Timer0 Overflow Interrupt
OCR0A =128;
OCR0B =128;
ADMUX = 0x60; //ADC Ref = VCC, Left adjusted;
ADCSRB = 4; //Timer0 Start
ADCSRA = 0xE4; //ADC Enable, Start, Auto Trigger, 1MHz;
be();
while(true);
}
So all in all the DDS signal is now generated in the same clock and the
result is measured and sent to the PC. The result in the Arduino plotter now
actually looks very good.
If you look at the data transmission directly at the TXD line, you can see
that the five bytes are transmitted directly one after the other. However,
there is a longer pause between two data packets. This is probably caused
by the preparation of the data and its conversion into a text.
Signals on the TXD line
The best way to solve this problem is to actually send only one byte for one
measured byte. This means that the measured data in byte format is sent
directly as such and not first converted into a text. However, this requires a
modified evaluation of the data. The Arduino plotter can then no longer be
used, but you have to develop your own software.
3.5 AD buffering
For the beginning the serial plotter is very convenient, because you don't
have to work on two construction sites at the same time. As an intermediate
solution, it is advisable to first save the data in an array and only then send
it.
#include < math.h>
unsigned char dds[256];
unsigned char osz[500];
unsigned int ph, n, i, j;
ISR (TIMER0_OVF_vect)
{
PORTD |= 4;
ph += 256;
OCR0A = dds[ph >> 8];
if (i < 500) {
osz[i] = ADCH;
i++;
}
PORTD &= ~4;
}
int main(void)
{
unsigned int n;
Serial.begin(1000000);
for (n = 0; n < 256; n++) dds[n] = 127 + 127 * sin(PI * n
/ 128.0);
DDRD = 254;
TCCR0A = 0xA3; //Timer0 Fast PWM at PD5/6
TCCR0B = 0x01; //16 MHz
TIMSK0 = 0x01; //Timer0 Overflow Interrupt
OCR0A = 128;
OCR0B = 128;
ADMUX = 0x60; //ADC Ref = VCC, Left adjusted;
ADCSRB = 4; //4 'Timer0 Start 0= free running
ADCSRA = 0xE4; //ADC Enable, Start, Auto Trigger, 1MHz;
be();
while (true) {
i = 0;
for (n = 1; n < 65000; n++) {
for (j = 1; j < 20; j++){ asm ("nop");}
}
for (n = 0; n < 500; n++) {
Serial.println(osz[n]);
}
}
}
The storage is started when i is set to 0 from outside and terminated when i
= 499 is reached. The output of the 500 measured values is done in the
main program. In addition, a waiting loop was inserted so that the
oscillogram stands still for about one second after each output.
A full sinusoidal oscillation is output here in 256 points, so that almost two
full oscillations fit on the screen with its 500 measuring points. The
frequency of the signal is 244 Hz, as already calculated above in connection
with sawtooth signals: 16 MHz / 256 / 256 = 244 Hz.
A look at the signal at PD2 shows the low utilization of the interrupt routine
of only about 10% of the available 16 µs.
Measurement of time utilization at D2
The program now also allows higher signal frequencies. At a sine frequency
of 2 kHz ( ph += 2098; ) one can already recognize remains of the PWM
frequency. That these remainders are at the extreme values of the sinusoidal
oscillation is indicated by a phase shift of approx. 90 degrees. This means at
the same time that the low pass filter is already operated far beyond its
cutoff frequency of 160 Hz and that the amplitude of the useful signal with
200 mV becomes accordingly small. The basic problem is that the PWM
frequency should be as far as possible above the useful frequency, but with
a resolution of 8 bits it is limited to 62.5 kHz. A possible solution lies in a
multi-pole low-pass filter with a steeper slope. This topic will be discussed
in more detail below.
The generated 2 kHz signal across 10 kΩ at 100 nF
The own measurement with the Arduino plotter shows that a signal of 2
kHz is already represented very well. For this measurement the cutoff
frequency of the low pass filter was increased to 1.6 kHz (10 kΩ and 10
nF), so that the signal voltage fits better to the measuring range 5 V.
Remnants of the PWM signal cannot be detected here. But this is due to the
fact that the AD sampling is synchronous to the PWM signal. A residual
signal still present at 62.5 kHz would always be measured in the same
phase and thus appear as smooth. So you have to keep in mind that the
synchronous measurement makes the signal look a bit more perfect than it
actually is. The comparison measurement with an external oscilloscope and
higher sampling rate, on the other hand, still shows residuals of the PWM
under the same conditions (2 kHz, 10 kΩ and 10 nF).
Measurement of the own 2 kHz signal over 10 kΩ at 10 nF
Comparison measurement with an external oscilloscope
With its sampling rate of 62.5 kHz, the oscilloscope is already fully suitable
for the entire AF range. The decisive factor is that the sampling rate is at
least twice as high as the highest occurring signal frequency. In the audio
sector, a sampling rate of 44.1 kHz is often used for the frequency range up
to 20 kHz, although very steep-edged filters are used. So the sampling rate
is higher than required. Therefore, the oscilloscope realized with the
Arduino can already correctly display typical audio signals.
The user program is developed in VB6 and will be presented here only in
passing. The task is also solvable with other programming languages. The
decisive factor is that this enables further development of the firmware.
The central goal is that all functions of the measuring laboratory can be
used simultaneously. The individual inputs and outputs can therefore be
used as if they belonged to independent devices. Later on, further functions
are to be added.
In the interrupt function now two sinusoidal signals are generated via both
PWM outputs. For this there are two separate phase accumulators a1 and
a2. This time they are not increased by constants, but by the variables ph1
and ph2, which can be used to specify the frequency externally. In addition,
two square wave signals with the same frequency are generated at the
outputs D4 and D7 by copying the most significant bit of the phase
accumulator to the output in each case. Thus there are altogether four DDS
outputs and one auxiliary output:
ISR (TIMER2_OVF_vect)
{
PORTB |= 1;
a1+=ph1;
a2+=ph2;
if (ds1) OCR2A=(dds[a1>>8]);
if (ds2) OCR2B=(dds[a2>>8]);
PORTD = (PORTD & ~128)|((a1>>8)&128);
PORTD = (PORTD & ~16)|((a2>>11)&16);
if (adn<628){
UDR0 = ADCH;
adn++;
}
ADCSRA |= 0x40; //AD Start
PORTB &= ~1;
}
Towards the end of the function the AD converter is retriggered via a direct
start command ( ADCSRA = 0xD2; ) because automatic triggering by timer 2 is
not possible. This command also consists of only a single byte transfer. The
AD converter then has enough time until the next interrupt.
The firmware does completely without the transmission of text and uses
binary data in the form of single bytes instead. Therefore the Arduino
typical commands for data transmission cannot be used. For the byte
transfer there are now the functions USART_Transmit and USART_Receive . In
both directions only one byte is written to or read from UDR0. Before this,
the USART waits until it is ready or has received a byte. The byte
transmission from the interrupt function could do without this waiting time,
because with a transmission clock of 16 µs it is clear that the USART is
ready for a new byte.
In the main function first the USART, the timer 2, the AD converter and the
ports are initialized. Timer 2 provides two PWM outputs with 62.5 kHz and
triggers a timer interrupt at each overflow. The PWM pulse widths are first
initialized with 128. The AD converter operates left-adjusted, so that the
upper 8 bits can be read with a byte access in register ADCH.
The converter clock is set to the highest possible speed. The AD clock is set
to Clk/16, i.e. 1 MHz. The data sheet recommends 200 kHz for best
accuracy. However, because only 8 bits of the available resolution are used
here, the faster clock can be used without losses. The AD converter needs
13 clocks for one measurement. Therefore the conversion time of 13 µs is
shorter than the interrupt period of 16 µs. The serial transmission of the last
measured value and the measurement of the following value run
simultaneously with their separate hardware blocks without burdening the
controller's computing time.
int main()
{
UBRR0H = 0; //USART
UBRR0L = 0; //1 MBaud
UCSR0B = 0x18; //TX, RX on
UCSR0C = 0x06; //8N1
DDRB = 255;
DDRD = 254;
while(true) {
c=USART_Receive();
if (c==65) adn=0; //Oszi Start}
In an endless loop the program waits for commands in the form of single
bytes. In the first expansion stage only one command is recognized. If a
byte 65 was received, a measurement with 628 points is started by setting
adn=0. The command can also be sent as a single capital A. Both ways of
reading the data can be processed by the simple serial terminal program
Ternimal.exe. The received data shows the sinusoidal signal smoothed with
a RC filter. You can clearly see the maximum at 240 and the minimum at
15.
Start and reception of the measured values
Picture5.Cls
For n = 1 To 9
Picture1.Line (62.5 * n, 2)-(62.5 * n, 258), vbGreen
Next
For n = 0 To 10
Picture5.Line (0, 258 - n * 25.5)-(625, 258 - n * 25.5), vbGreen
Next n
alast = 258 - READBYTE
alast = 258 - READBYTE
For n = 0 To 625
Ain = 258 - READBYTE
Picture5.Line (n - 1, alast)-(n, Ain), vbBlack
alast = ain
Next n
End Sub
The next stage of the extension concerns the setting of the DDS
frequencies. For this the contents of ph1 and ph2 must be reassigned. The
commands 67 and 68 were defined for this. Because both variables have a
width of 16 bits, two data bytes must be transmitted in each case.
while(true) {
c=USART_Receive();
//cli();
if (c==65) adn=0; //Oszi Start
if (c==80){ //DDS Freq 1
ph1 = USART_Receive()<<8;
ph1 = ph1+ USART_Receive();
}
if (c==81){ //DDS Freq 2
ph2 = USART_Receive()<<8;
ph2 = ph2+ USART_Receive();
}
}
An example: With a value of 512 one generates approx. 500 Hz. To set this
frequency for the second DDS channel, the command and its data is: 80, 2,
0. In the terminal you can see the slowed down progress of the sine
function.
In the user program there are two sliders for the two DDS frequencies. Both
convert the adjustable frequency from 0 to 5000 Hz into frequency
parameters from 0 to 5242, which are then sent after the control command
66 or 67 as highbyte and lowbyte. The limit of 5 kHz is set arbitrarily. One
could also generate up to 10 kHz, But then each oscillation would have only
six support values, which would require much better low pass filters.
So far there are two DDS outputs, but only one analog input. For the test it
is useful to lead both DDS outputs with 10 kΩ each or also different
resistors to the common input A0 and to smooth with 10 nF. The
oscilloscope then shows the sum of both signals. If you set slightly different
frequencies, the typical beatings appear.
In addition to the two sine outputs, there are two square wave outputs with
the same frequency. DDS1 supplies a signal to D7, DDS2 to D4. These
signals can also be examined directly with the oscilloscope. If they are sent
through a low-pass filter, the typical shark teeth with an exponential rise
and fall of the edges are created.
Square wave signal with 500 Hz at D7
Square wave signal with 800 Hz after low pass filtering with 10 kΩ and 10
nF
Previously, the sampling rate was constant at 62.5 kHz, which resulted in a
deflection factor of 1 ms/div in the oscilloscope. There are 62.5 measuring
points between two parts of the scale. Now, however, lower rates are to be
made possible. As usual, the deflection speed shall be adjustable in 1-2-5
steps.
In addition, a dual-channel operation is now built in. If you set duo=1 via a
command, the function switches to the other channel at each pass. For this
the least significant bit in adn is used. The multiplexer is switched
continuously in this way and is ADMUX=0x60 at one call and ADMUX=0x61 at
the next. This leads to a halved sampling rate for each of the two input
channels A0 and A1, which however is still sufficient for many
applications.
Four new commands must now be added to the command interpreter loop:
while(true) {
c=USART_Receive();
//cli();
if (c==65) adn=0; //Oszi Start
if (c==80){ //DDS Freq 1
ph1 = USART_Receive()<<8;
ph1 = ph1+ USART_Receive();
ds1 = 1;
}
if (c==81){ //DDS Freq 2
ph2 = USART_Receive()<<8;
ph2 = ph2+ USART_Receive();
ds2 = 1;
}
if (c==68){ //Oszi deflection
dv = USART_Receive();
}
if (c==69){ //Oszi Ch1
ADMUX = 0x60;
duo = 0;
ch = 0x60;
}
if (c==70){ //Oszi Ch1+2
ADMUX = 0x60;
duo = 1;
ch = 0x61;
}
if (c==71){ //Oszi Ch2
ADMUX = 0x61;
duo = 0;
ch = 0x61;
}
}
The channel switching is controlled via the slider Hscoll4. Here only one
command byte must be sent at a time without additional parameters.
The display of the measured values must also be extended for the second
channel. Channel 1 is displayed in black, channel 2 in red. In case of ch=3
both channels are plotted together.
If ch = 1 Then
alast2 = 258 - READBYTE
End If
If ch = 1 Then
For n = 0 To 625
Ain = 258 - READBYTE
Picture5.Line (n - 1, alast)-(n, Ain), vbBlack
alast = ain
Next n
End If
If ch = 2 Then
For n = 0 To 625
Ain = 258 - READBYTE
Picture5.Line (n - 1, alast)-(n, Ain), vbRed
alast = ain
Next n
End If
If ch = 3 Then
For n = 1 To 628 Step 2
Ain = 258 - READBYTE
Picture5.Line (n - 1, alast)-(n + 1, Ain), vbBlck
alast = ain
Ain = 258 - READBYTE
Picture5.Line (n - 2, alast2)-(n, Ain), vbRed
alast2 = Ain
Next n
End If
DELAY 10
CLEARBUFFER
Now both AD channels can be used simultaneously. Because there are also
two DDS channels, you can now display two different sine frequencies at
the same time. The setup must now be extended to two low pass filters.
The two-channel oscilloscope at 2 ms/div
The oscilloscope now delivers a new image once per second. If you want to
freeze an image, click Halt. This stops timer 2, i.e. further data acquisition
is suspended. Clicking again will restart the measurement.
4.5 Triggering
Up to now, each measurement was initiated with command 65, which set
the counter adn to zero. Now there are the two new commands 66 and 67,
which need one byte parameter each for the trigger level. With two
interrogation loops the trigger point is reached. Only when the trigger level
is just reached, adn=0 starts the measurement.
if (c==66){ //+Trigger
level = USART_Receive();
timeout=0;
while (ADCH>=level) {timeout++; if(timeout>10000) break;}
while (ADCH<level) {timeout++; if(timeout>10000) break;}
adn=0;
}
if (c==67){ // trigger
level = USART_Receive();
timeout=0;
while (ADCH<=level) {timeout++; if(timeout>10000) break;}
while (ADCH>level) {timeout++; if(timeout>10000) break;}
adn=0;
}
When working with an oscilloscope, one knows the problem that the trigger
point has been chosen unfavorably and no image appears. To avoid this
situation, a timeout has been built in. If the searched condition is not
reached for too long, the query loop is exited.
Trigger point in the upper third
Two sliders are already on the user interface, which have not been used yet.
These are two sliders with which one can set a desired DC voltage. Here the
same PWM outputs are used, with which also the sine signals are generated.
Although one could have used timer 1 for the DC outputs, it will be needed
later as a frequency counter. In addition, the double use of the Timer2 PWM
outputs has the further advantage that one gets by with a total of two low-
pass filters.
If you press one of the DC voltage adjusters, the DDS output is stopped and
a DC voltage is output instead. It is also possible to use one of the outputs
for a sine signal and the other for a DC voltage. For the DC outputs there
are the two new commands 83 and 84. The additionally transferred
parameter is assigned directly to the PWM registers.
ISR (TIMER2_OVF_vect)
{
PORTB |= 1;
a1+=ph1;
a2+=ph2;
if (ds1) OCR2A=(dds[a1>>8]);
if (ds2) OCR2B=(dds[a2>>8]);
PORTD = (PORTD & ~128)|((a1>>8)&128);
PORTD = (PORTD & ~16)|((a2>>11)&16);
dvn++;
if (dvn >= dv){
if (adn<628){
UDR0 = ADCH;
if (duo==1) ADMUX = 0x60+(adn & 0x0001);
adn++;
dvn=0;
}
}
ADCSRA |= 0x40; //AD Start
PORTB &= ~1;
}
The previous commands for frequency setting must also be extended so that
they can now switch on the DDS output. For this ds1 = 1 and ds2 = 1 is
inserted.
Now one channel can be used for the sine output and the other for a DC
voltage. By adding both signals it is then possible to shift the average level
of the signal.
Sine signal with shifted DC level
5 Additional inputs and outputs
The Arduino Nano has a lot more to offer. Several ports, analog inputs and
timers are still free. Here we try to exhaust all possibilities that can be used
at the same time. The goal remains to use all functions as if they belonged
to independent devices. The MSR laboratory thus becomes more extensive
without the need for additional hardware.
For a good overview even with much more inputs and outputs all functions
are now named according to the pin designations on the Arduino.
Adjustable phase shift between the two DDS outputs as long as the
same frequency is set.
Square wave generator up to 8 MHz at D6
10-bit analog inputs at A2 and A3
Frequency counter up to 8 MHz at D5
Capacitance meter 1 pF ... 10 nF at A4
Ohmmeter up to 1 MΩ also at A4
Ohmmeter 1 Ω ... 100 kΩ at A7
The sine table of the DDS generators has a length of 256 bytes. For a
complete oscillation, the high byte in the phase accumulator must pass
through the range between 0 and 255. Thus, with the same frequency of
both channels, a phase relationship of 360 degrees in total is mapped in this
range. Accordingly, a1=0x0000 is set and a received byte parameter is shifted
into the high byte of a2. Command 82 thus triggers a phase jump at both
channels after which the desired phase relationship exists.
In the user program, the desired phase difference is set with the HScroll9
slider. At each operation the command 82 is sent together with the new
phase byte.
In the user program every change at the frequency control HScroll8 leads to
a new output. For the finest possible setting, five ranges with different
prescalers (1, 8, 64, 256, 1024) are used. The output frequency is calculated
and displayed on the surface.
Many important frequencies can be set exactly, but most frequencies are
crooked parts of 16 MHz. The resolution is high at small frequencies and
becomes coarser towards the end. The four highest frequencies are 2 MHz,
2.667 MHz, 4 MHz and 8 MHz. For comparison: The DDS generator has a
resolution of about 1 Hz everywhere, but only reaches up to 5 kHz.
With the square wave generator, frequencies far above the sampling rate of
the oscilloscope can be set. However, reliable measurements with the
oscilloscope are only possible up to half the sampling rate, i.e. up to about
31 kHz. Near the sampling rate or its multiples, completely wrong images
are delivered. The double sampling rate is 125 kHz. If you set the square
wave generator to 127 kHz, an apparent signal of 2 kHz appears, i.e. the
difference frequency. In principle, this problem can be observed with any
DSO, while it never occurs with an analog oscilloscope.
Measurement of supposed 2 kHz at actual 127 kHz
Also noticeable are the sloping edges in the oscillogram despite the actual
rectangular shape. They are caused by the finite sampling time of the AD
converter. The sample-and-hold capacitor needs some time to charge up to
the actual voltage. However, at very high frequencies, the state already
changes within the sampling time. As a result, voltages between the
extreme values are measured in the transitions. At very high frequencies,
even triangular voltages are displayed.
Triangle display at 308 kHz
ISR (TIMER1_OVF_vect)
{
fh1++;
}
...
TCCR1A = 0x00;
TCCR1B = 0x07; //Timer1 Input
TIMSK1 = 0x01; //Timer1 Overflow Interrupt
TCCR1C = 0;
ISR (TIMER2_OVF_vect)
{
PORTB |= 1;
...
t++;
if(t==0){ TCCR1B = 0x00; TCNT1=0; fh1=0;}
if(t==1){ TCCR1B = 0x07;}
if(t==62501){ TCCR1B = 0x00;f=TCNT1; fh2=fh1;}
...
PORTB &= ~1;
}
The lower 16 bits are then in f . In addition, there are the upper 8 bits in
fh2 . Command 91 was defined for transmission to the PC.
In the user program, the frequency is displayed anew once per second. For
this purpose, the measured value must be read out within the timer
function. A total of three bytes are combined to form a 24-bit number.
CLEARBUFFER
SENDBYTE 91
f = READBYTE
f = 256 * f
f = f + READBYTE
f = 256 * f
f = f + READBYTE
Label9 = "D5 " + Str(f) + " Hz"
The square wave output D7 or D4 is best suited for measuring the DDS
frequency. Here one can find deviations of one Hertz partly caused by
rounding errors. Usually the lowest digit of a frequency counter fluctuates
because the signal frequency is mostly completely asynchronous to the time
base of the counter.
High resolution analog inputs are welcome and useful in the MSR lab. The
user interface contains two displays for external voltages at inputs A2 and
A3. They are to work with a resolution of 10 bits, which requires a
completely different initialization. The measured values shall be output
right-justified, so that the lower 8 bits are in ADL and the upper two bits are
in ADH. In addition, the converter must be clocked slower to achieve the
full accuracy.
For the measurement at any input channels first the command 75 is sent and
then the desired channel. This initializes the AD converter accordingly and
prepares it with an idle measurement. After the actual measurement, the
measurement result is sent to the PC in the range 0 to 1023 in two bytes.
Afterwards, the original setting of the AD converter is restored so that fast,
left-justified measurements can be performed for the oscilloscope.
In the timer function in the user program, two channels are measured at a
time after an oscillogram has been recorded. Thus the time sequence is clear
and there can be no conflict in the use of the AD converter.
SENDBYTE 75
SENDBYTE 2
u1 = READBYTE
u1 = 256 * u1
u1 = u1 + READBYTE
u1 = 5 * u1 / 1023
u1 = (Round(u1 * 1000)) / 1000
Label7 = "A2 " + Str(u1) + " V"
CLEARBUFFER
SENDBYTE 75
SENDBYTE 3
u2 = READBYTE
u2 = 256 * u2
u2 = u2 + READBYTE
u2 = 5 * u2 / 1023
u2 = (Round(u2 * 1000)) / 1000
Label8 = "A3 " + Str(u2) + " V"
Measurement at 3.3 V and 5 V
For testing, A2 was connected to 3V3 and A3 to 5V. VCC was apparently
measured with high accuracy, but 3.3V was displayed too high. In fact, it is
the other way around because VCC serves as a reference during the
measurement. The AD converter measures its own reference and returns the
value 1023. Assuming that Vcc = 5.0 V, the user program calculates a
measured value of 5 V from this. In fact, however, VCC can deviate from
5.0 V. In this case, the controller was operated via a USB hub without an
additional power supply. The actual voltage was measured with 4.68 V. In
contrast, the auxiliary voltage of 3.3 V was very accurate and was measured
with an external digital voltmeter as 3.30 V.
If Cx also has 1000 pF, half the operating voltage should be measured. For
very small capacitors the measured voltage is close to Vcc. With the 10-bit
AD converter, a resolution of 1 pF is achieved for small capacitors.
Theoretically, 1 µF should also still be measurable, but only with very
coarse resolution. However, reasonable measurements up to 10 nF are
possible.
For the capacitance measurement the command 76 was defined. Here again
the AD converter must be reinitialized. Waiting loops were inserted
between the individual phases of the measurement, so that the capacitors
can sufficiently discharge and recharge themselves. The code is relatively
long, because with the same command also a resistance measurement is
executed. So it is also possible to check unknown components of which it is
not yet clear whether it is a capacitor or a resistor.
CLEARBUFFER
SENDBYTE 76
uc = READBYTE
uc = 256 * uc
uc = uc + READBYTE
ur = READBYTE
ur = 256 * ur
ur = ur + READBYTE
The measurement of a resistor also at port A4 against GND uses the internal
pullup of port PC4. This does not promise great accuracy, but is sufficient
for simple measurements up to about 1 MΩ. The unknown resistor forms a
voltage divider with the pullup resistor of about 30 kΩ. From the measured
partial voltage the searched resistance can then be calculated.
Resistance measurement
The pullup is subject to strong specimen scatter and also depends on the
operating voltage. For the best possible accuracy, the value of 30 kΩ should
be determined more precisely and used in the calculation. Here, a resistance
of 33.5 kΩ was determined, which led to good results.
CLEARBUFFER
SENDBYTE 75
SENDBYTE 7
ur = READBYTE
ur = 256 * ur
ur = ur + READBYTE
If ur < 1023 Then
Rx2 = Int(1000 * ur / (1023 - ur))
Label14.Caption = "A7 " + Str(Rx2) + " R"
Else: Label14.Caption = "A7 >100 k"
End If
6.1 Subsampling
The following applies to every digital oscilloscope: The set deflection time
must match the measurement signal. This has already been confirmed in
many tests. Now a typical measurement error caused by undersampling
shall be provoked. The measurement is performed with a simple low-pass
filter with 10 kΩ and 10 nF between the DDS output D11 and the
oscilloscope input A0.
The oscilloscope is set to 20 ms/div for this purpose. In this case, only one
of 20 possible measuring points is used. The sampling rate is then 62.5 kHz
/ 20 = 3125 Hz. If one now sets the DDS generator exactly to this
frequency, the oscilloscope should always sample exactly the same point of
the oscillation after every twenty oscillations. Thus, one should only see a
DC voltage.
In fact, however, one sees a section of a very slow sine wave with a
frequency below 1 Hz. This throws light on the possible frequency
deviations of the DDS generator. In fact, there are rounding errors here,
because due to the use of integer phase accumulators, the smallest
frequency step is 62500 Hz / 256 / 256 = 0.95367. If one sets one Hz
higher, i.e. 3126 Hz, an apparent frequency of 1 Hz should be measured.
Sub-sampling of 3126 Hz
Measurement at 3135 Hz
When the DDS frequency is increased to 3135 Hz, two complete sinusoidal
oscillations with a period of 100 ms become visible. The displayed
frequency is therefore 10 Hz. This is explainable because the real frequency
is now exactly 10 Hz above the sampling frequency. That the real frequency
cannot be 10 Hz but must be much higher can be seen from the lower
amplitude.
This time the signal is filtered with 1 kΩ and 10 nF. The oscillogram shows
a symmetrical triangular signal with 1 Vpp and an apparent frequency of 2
kHz. The comparison measurement with a faster oscilloscope shows that
the waveform and the amplitude of the signal were displayed correctly even
with undersampling.
Comparison measurement
At the output D8 (PB0) a square wave signal with 62.5 kHz appears, which
is mainly used to monitor the computing time within the interrupt function.
It is clear that one cannot observe this signal directly with the oscilloscope
with the same sampling rate. But if you try it anyway, a DC voltage with
low ripple appears, which is a little bit different at each measurement, but
always range 0 V to 0.5 V.
Measurement at D8 with 62500 Hz
ISR (TIMER2_OVF_vect)
{
PORTB |= 1;
...
ADCSRA |= 0x40; //AD Start
PORTB &= ~1;
}
With a faster oscilloscope you can see that the computing time is about 50%
utilized, which is about 8 µs.
With the own oscilloscope in the MSR laboratory, only the frequency
response up to 5 kHz can be examined. At 5 kHz, one finds only 1.7 Vpp
compared to 5 Vpp at the lowest frequencies.
Measurement at 5 kHz
One could assume that this ripple should affect all previous measurements
that used the same low-pass filter. However, this was not observed because
the oscilloscope runs synchronously with the PWM signal, whereby the
disturbances cancel each other out. This is an advantage of synchronous
measurement that should not be overlooked. Compared to other devices, the
measurement results appear significantly glossed over. On the other hand,
synchronous measurement allows very simple filters, which is an advantage
for small experiments.
An LC low pass
In the real setup, a resistor of 470 Ω was used because the fixed inductance
itself already has a certain wire resistance. The measurement shows a
straight frequency response up to approx. 2.2 kHz.
The LC low pass at 2 kHz
At the same time, the residual ripple of the PWM signal has become so low
that it is hardly detectable. The test was again performed with the square
wave generator at D6 at approx. 63 kHz and with undersampling.
The smoothed signal at approx. 63 kHz
6.6 LC resonance
The DDS signal is reduced for the experiment with a voltage divider and an
additional electrolytic capacitor with 10 µF so that the excessive resonance
voltage still fits into the measuring range of the AD converter.
With the tuning of the sinus generator and the display in the oscilloscope,
one gets a quick overview and finds the resonance frequency very quickly.
For more detailed investigations, you can record some measuring points
more precisely and display them graphically with a spreadsheet. For
occasional investigations this manual evaluation is sufficient. But it is only
a question of software to automate such measurements. For automatic
recording of frequency responses no change in the firmware is necessary,
because all necessary measurement functions are already included.
The first PWM channel is used as a DDS sine wave generator with 1 kHz.
The low-pass filter was intentionally dimensioned with 10 kΩ and 100 nF
so that a relatively low AC voltage is applied. The second PWM output is
used as an adjustable voltage source to set the base current via the 470 kΩ
resistor.
The signal looks different with a very large base quiescent current. Here a
control voltage of 2.12 V was set. The transistor switches fully in the idle
state, so that the collector current only decreases in the negative peaks of
the input voltage. This results in positive peaks of the collector voltage.
Up to now, the DDS generator could only produce sine oscillations with full
amplitude, i.e. between 0 V and 5 V. However, this can lead to problems if,
for example, an LC low-pass filter is used that partially leads to an increase
in amplitude.
The solution in this case brings a reduction of the amplitude to 50%. But
then quite different signal shapes can be realized at once. Both channels can
also generate different signals. Therefore there shall now be two separate
DDS tables, which are filled with the same sine waveform with full
amplitude for initialization.
for (n=0;n<256;n++){
dds1[n]= 128+127.9*sin(PI*n/128.0);
dds2[n]= 128+127.9*sin(PI*n/128.0);
}
Via own commands now also alternative table functions can be initialized
for the first DDS channel at D11.
if (c==85){ //sine
for (n=0;n<256;n++) dds1[n]= 128+127.9*sin(PI*n/128.0);
}
if (c==86){ //sine /2
for (n=0;n<256;n++) dds1[n]= 128+64*sin(PI*n/128.0);
}
if (c==87){ //triangle
for (n=0;n<128;n++) dds1[n]= 2 * n;
for (n=128;n<256;n++) dds1[n]= 255 - 2 * (n - 128);
}
if (c==88){ //sawtooth
for (n=0;n<256;n++) dds1[n]= n;
}
A new slider was installed as selection switch for the four possible DDS
functions. Here only the single command bytes 85 to 88 are sent. The
firmware then calculates the required DDS table in each case.
Private Sub HScroll10_Change()
Select Case HScroll10.Value
Case 0
SENDBYTE 85
Label16.Caption = "D11 Sine"
Case 1
SENDBYTE 86
Label16.Caption = "D11 Sine/2"
Case 2
SENDBYTE 87
Label16.Caption = "D11 Triangle"
Case 3
SENDBYTE 88
Label16.Caption = "D11 Sawtooth"
End Select
End Sub
The switching of the waveform works without any noticeable time delay.
The left position of the slider sets the full sine amplitude again.
The same applies even more to the sawtooth. Especially the steep slope is
strongly changed at higher frequencies by the low pass filter.
While a sine wave contains only the fundamental frequency, square, triangle
and sawtooth have numerous even or odd harmonics. The signals therefore
differ greatly in sound when listened to directly through a piezo
loudspeaker without a low-pass filter, for example.
Sawtooth with 15 Hz.
Triangular signal over 10 kΩ at 100 nF
7.4 XY representation
Until now, the x-axis of an oscillogram was always the time axis. Now,
however, both input channels A0 and A1 are plotted against each other. For
this and further representations the channel switch was extended by some
positions. The XY representation is called A1(A0) here, according to the
mathematical notation f(x). On the firmware side, only the normal two-
channel measurement is triggered, so that both channels alternate in the
data.
If ch = 4 Then
aylast = 258 - READBYTE
axlast = 2.45 * READBYTE
For n = 1 To 624 Step 2
Ay = 258 - READBYTE
Ax = 2.45 * READBYTE
Picture5.Line (axlast, aylast)-(Ax, Ay), vbBlck
aylast = ay
axlast = Ax
Next n
End If
Two phase-shifted sinusoidal signals of the same frequency
The XY plot can be used to create Lissajous figures from which frequency
relationships and phase relationships can be read. Two sinusoidal signals
with the same frequency and amplitude should result in a circle with a
phase shift of 90 degrees. Because the width and height differ here, a better
approximation to a circle is obtained with half the amplitude. In addition,
the phase was set to 90 degrees. However, the time-shifted sampling of both
channels results in an additional phase shift. Therefore, the set phase had to
be corrected to 94 degrees in this case.
With integer frequency ratios special Lissajous figures arise. With a little
experience one can recognize the ratio. Even small frequency deviations
can be recognized, because they continuously lead to a slow change of the
phase relations.
Frequency ratio 1 : 2
Frequency ratio 1 : 5
Different curve shapes can also be plotted against each other. The sampling
rate used is also important. With low sampling rates, such as a setting to 20
ms/div, additional delays occur between the x- and y-sampling. Instead of a
closed Lissajous figure, you then get complex line patterns.
Sine vs. sawtooth plotted at low sampling rate
if (c==73){ //f-Sweep
ADMUX = 0x60;
duo = 0;
ds1 = 1;
ch = 0x60;
adn=0;
while (adn<629){
asm ("nop");
n = adn;
ph1 = n<<3;
}
ph1=0;
a1=0;
}
In the timer function of the user program the command 73 is now sent
instead of the start command 65. The actual display on the oscilloscope
does not differ from a simple single-channel oscillogram.
If trigger = 0 Then
If ch < 5 Then SENDBYTE 65
If ch = 5 Then SENDBYTE 73
If ch = 6 Or ch = 7 Then SENDBYTE 72
End If
...
If ch = 5 Then 'Frequency sweep
alast = 258 - READBYTE
For n = 0 To 625
Ain = 258 - READBYTE
Picture5.Line (n - 1, alast)-(n, Ain), vbBlack
alast = ain
Next n
End If
Sub-sampling of the sweep frequency
For a correct display of the sweep signal, only the fast settings with 1
ms/div and 2 ms/div are suitable. If the measurement is too slow,
undersampling will occur.
if (c==72){
ADMUX = 0x60;
ds1 = 0;
adn = 0;
ph1 = 0;
while (adn<629){
asm ("nop");
n = adn;
OCR2A = (n<<6)/157;
}
ph1=0;
a1=0;
}
Ramp 0...5 V
The silicon diode has a characteristic with a similar curve, which is,
however, shifted to lower voltages. A noticeable current flows here from
0.5 V. The same applies to the BE diode of a transistor. The characteristic
curve of a resistor, on the other hand, is straight.
Characteristic of the base-emitter diode of a transistor
Characteristic of a resistor with 10 kΩ
8 Application examples
The last chapter deals with typical measurements from the electronics
laboratory, their problems and also solutions to them. As with the previous
applications, the focus is on analog electronics. More complex circuits with
operational amplifiers are also examined here.
The DDS outputs with their low pass filters used to be very high
impedance, which meant no problem when connected to a high impedance
analog input. But if you connect a low impedance load, the signal voltage
will collapse. For such cases you need a buffer amplifier as impedance
converter. The usual way is to use an operational amplifier.
But also the emitter follower can be used as impedance converter. For this
purpose the signal voltage should be reduced to half, because the emitter
follower does not work at voltages close to 0 V. The measurement shows
that the output voltage is about 0.7 V below the input voltage at every
point.
Voltage curve at the base and at the emitter
The emitter follower works like a control loop. The collector and emitter
current depends strongly on the base-emitter voltage. When this increases,
the emitter current increases, which leads to a greater voltage drop across
the emitter resistor and thus reduces the base-emitter voltage. Thus, an
equilibrium is established in which each base voltage has a matching
emitter voltage. Because an increase of the base-emitter voltage by only 20
mV leads to a doubling of the emitter current, the voltage difference
between base and emitter remains almost constant.
You can see a relatively straight range of low frequencies up to about 1.6
kHz and a steeper drop in signal amplitude above that. If you remove the
left capacitor to the emitter terminal from the circuit, you have only a first
order filter with a cutoff frequency of 800 Hz. The transition to the
stopband is less steep, and at 5 kHz you have a higher signal amplitude.
Filter curve with only one capacitor
Because an emitter follower is used in the filter circuit, you also have a
buffered, low impedance output. Therefore you can put a dynamic
headphone in series to the emitter resistor to hear the filtered sweep signal.
Alternatively, a piezo speaker can be connected in parallel to the emitter
capacitor. Interesting are different sweep speeds and the associated sounds
between 20 ms/div and 1 ms/div.
If two signals with similar frequency are added, a beat with a modulation of
the amplitude occurs. The beat frequency is then the difference frequency of
the two added signals.
This experiment is about demodulating the sum signal to obtain the beat
frequency itself. The circuit is similar to an AM demodulator in radio
technology. Usually a diode is used for this purpose. Here a transistor in
common collector circuit is used, because the sum signal has a very high
impedance. At first sight the circuit looks like an emitter follower. But the
emitter resistor is very high impedance and forms with the parallel capacitor
a low pass filter with a cutoff frequency of 160 Hz. The circuit thus works
as a peak rectifier. The transistor conducts only in the short moments of the
voltage maxima at the input. After that, the emitter voltage drops only due
to the discharge of the filter capacitor.
The doubler circuit with two diodes and two capacitors requires an AC
voltage signal or a square wave signal, which in this case is available with
adjustable frequency (here 50 kHz) at port D6. To the operating voltage of 5
V the voltage of the square wave signal with 5 Vpp is added, minus the
double forward voltage of a diode. Here two Si diodes 1N4148 with an
expected forward voltage of 0.7 V were used. Thus, the output voltage
should be 10 V - 1.4 V = 8.6 V, which is sufficient for the OPA. The real
test showed a voltage of 4.5 V at A2. The operating voltage of the OPA is
therefore 9 V.
Mainly because of the internal resistance of port output D6, the doubler
circuit supplies only a limited current, which is sufficient for the OPA, but
is not a great danger in case of possible errors.
Near 0 ° at 10 Hz
Near 180 ° at 2 kHz
The advantage of the measuring rectifier is that you can now pass through
the frequency as slowly as you like in order to give the filter sufficient time
to settle. In this case the setting 10 ms/div was chosen.
Appendix
List of components used
Arduino Nano
Breadboard SYB-46
USB cable
Piezo speaker
LM358 double OPA
LED red
Diodes: 3 x 1N4148
Transistor: BC547C
Resistors: 470 Ω, 1 kΩ, 3*10 kΩ, 27 kΩ, 2*100 kΩ, 220 kΩ, 470 kΩ
Capacitors: 3 x 10 nF, 2 x 100 nF
electrolytic capacitors: 10 µF, 100 µF
Fixed inductance 22 mH