Gas station without pumps

2014 June 22

Loudspeaker relaxation oscillator

Filed under: Circuits course — gasstationwithoutpumps @ 18:56
Tags: , ,

Yesterday I played around a little with a hysteresis oscillator (relaxation oscillator) using a loudspeaker as the feedback device, rather than a resistor, as shown in the schematic below:

Hysteresis oscillator with loudspeaker for feedback.  Changing the value of C1 should produce different frequencies.

Hysteresis oscillator with loudspeaker for feedback. Changing the value of C1 should produce different frequencies. I used 3.3v from the KL25Z board as my power supply.

I was hoping that I could get the oscillator to resonate at a predictable frequency, based on the gain or the phase shift of the voltage divider consisting of the loudspeaker and the capacitor. Of course, a relaxation oscillator that relies on the hysteresis of a Schmitt trigger is emphatically not a linear circuit, and there is no reason to think that using a loudspeaker instead of a resistor for the feedback element will simplify anything.

I did have a few questions:

  • Would it oscillate? (I saw no reason it shouldn’t.)
  • At what frequency would it oscillate? Was there any relationship to the gain or phase shift of the loudspeaker and C1 voltage divider?
  • How stable was the frequency?
  • Would it be loud enough to hear on the loudspeaker?

Before even wiring up the circuit, I ran some gnuplot scripts with my model of the loudspeaker to see what the gain and phase of the voltage divider would be:

Gain from the voltage divider, with different C1 values.  Note that I've also added a line for an RC low-pass voltage divider, for comparison.

Gain from the voltage divider, with different C1 values. Note that I’ve also added a line for an RC low-pass voltage divider, for comparison.

Phase change from the voltage divider, with different C1 values. Again I've added a line for an RC low-pass voltage divider, for comparison.

Phase change from the voltage divider, with different C1 values. Again I’ve added a line for an RC low-pass voltage divider, for comparison.

Note that the loudspeaker+capacitor provides a bigger phase change at high frequency and a faster rolloff in gain than an RC filter would. I was hoping that the resonant peaks at high frequency might capture the oscillator and provide a moderately stable output.

To avoid load on the oscillator from a multimeter (used to measure frequency) or oscilloscope, I buffered the output with a couple more Schmitt triggers.

C1 frequency
electrolytic measured with Fluke 8060A
 470µF  27Hz
 220µF  50–55Hz
 47µF  265–285Hz
 33µF  375–406Hz
 4.7µF  3077–3401Hz
ceramic measured with Fluke 8060A
 4.7µF  2.56–2.66kHz
 0.1µF  116–122kHz
ceramic measured with Bitscope oscilloscope
 47nF  245kHz
 22nF  286kHz
 10nF  587kHz
 2.2nF  1.1MHz

The frequencies were not stable, but shifted unpredictably within a fairly wide range. The Fluke 8060A meter is not capable of frequency measurements above about 100kHz, so I used the FFT on the Bitscope USB oscilloscope for the higher frequencies. For the Bitscope measurements, I took whichever frequency seemed to come up most often—usually the lowest frequency.

The audio-range frequencies 27Hz to 3.4kHz were clearly audible on the loudspeaker (even annoying at the higher frequencies), and the fluctuations in frequency were audible also—they are not an artifact of the measuring equipment.

Looking at the input and output of the oscillating Schmitt trigger for a moderately large capacitor is instructive:

The green trace is the input to the Schmitt trigger—it seems to be a fairly clean triangle wave.  The yellow trace is the output—it jumps when the inverter switches, but the current limitation of the Schmitt trigger seems to keep it from being a square wave. C1 was 33µF here, and the timebase is 2ms/div.

The green trace is the input to the Schmitt trigger—it seems to be a fairly clean triangle wave.
The yellow trace is the output—it jumps when the inverter switches, but the current limitation of the Schmitt trigger seems to keep it from being a square wave.
C1 was 33µF here, and the timebase is 2ms/div.

The current limitation on the Schmitt trigger output seems to be the controlling factor here, so we should be modeling this as a current source and capacitor, with the feedback impedance being irrelevant until it gets large enough that the Schmitt trigger output is voltage-limited instead of current-limited.

I tested this by replacing the loudspeaker by a 22Ω resistor, and got a very similar result (though without the voltage spikes from switching the loudspeaker inductance):

The nearly constant difference between the input and the output (across the 22Ω resistor) indicates nearly constant current flow.

The nearly constant difference between the input and the output (across the 22Ω resistor) indicates nearly constant current flow.

If we look at the voltage across the resistor, we can measure the current:

The current through the 22Ω resistor is about ±18mA, though it isn't quite as constant as I had thought from the previous plot.  (This plot is 200mV/division, so about 9.11mA/division.)

The current through the 22Ω resistor is about ±18mA, though it isn’t quite as constant as I had thought from the previous plot. (This plot is 200mV/division, so about 9.11mA/division.)

With a 3.9Ω feedback resistor, I again see waveforms consistent with a ±18.5mA current limit (dropping gradually to ±15mA before it switches to the other phase). I can get the same triangle wave at the input if I use a wire for the feedback, with the output only a few mV different from the input (for a wire resistance equivalent to about 130mΩ). The period is about the same also, indicating that the current is what is determining the charging time of the capacitor, not the feedback resistor.

With a 200Ω feedback resistor, I see a little current limitation just as the output switches, but it becomes voltage-limited soon after. The period increases, as we would expect when the voltage limitation reduces the current.

So the loudspeaker in the feedback loop was not very interesting—it was behaving much like any other low-impedance feedback. At least, that is what is happening with low frequencies, where the loudspeaker is reasonably modeled as an 8Ω resistor.

With a 10nF capacitor and a 22Ω feedback resistor the oscillator oscillates at 1.27MHz, but with the loudspeaker only at 589kHz, so the loudspeaker is behaving more like a large impedance at these frequencies.  The output with the 22Ω resistor is a triangle wave, but with the loudspeaker is a square wave (with a little high frequency ringing).  I can’t see these frequencies well on the Bitscope oscilloscope, so I had to switch to my analog Kikusui COS5060 60MHz oscilloscope.  With 47Ω and no oscilloscope load, I get a frequency around 965kHz, with 22Ω around 1.13MHz, with 81Ω around 768kHz,  with 100Ω 687kHz, with 120Ω around 613kHz, with 150Ω around 526kHz, and with the loudspeaker around 590kHz.  So the loudspeaker is behaving like a 125–130Ω impedance around 590kHz, which is consistent with the measurements made of the loudspeaker impedance around that frequency. Similarly with a 3.3nF capacitor, I get 150Ω 1.23MHz, 180Ω 1.1MHz, 200Ω 1.03MHz, 220Ω 972 kHz, and loudspeaker 987kHz.  The output waveforms with the 220Ω or loudspeaker as feedback are fairly good square waves, so the oscillator feedback is voltage limited, not current limited.

So it looks like the simple analysis of the oscillator as being either a current-limited or a voltage limited output suffices for modeling the relaxation oscillator—the phase changes don’t seem to matter much, just how fast the capacitor charges or discharges, which depends mainly on the magnitude of the impedance.

Incidentally, the fluctuations in frequency for the oscillator occur with the resistors and the loudspeaker alike, and so don’t seem to be due to any physical or electrical properties of the loudspeaker.  They also occur with both electrolytic and ceramic capacitors.

2014 April 14

Hysteresis lecture

Filed under: Circuits course — gasstationwithoutpumps @ 23:16
Tags: , , ,

Today’s class started with feedback on their second design reports (the electret mic lab). Everyone in the class got a “redo” on this assignment.  Some of them actually had pretty good write-ups, but I had warned them that errors on schematics or with units would trigger automatic redos, and every report had at least one serious error (like 200A, instead of 200µA, or short-circuiting the mic). I’m going to hold them to getting their schematics and units right—details matter in engineering, and they have got to develop a habit of double-checking what they write.

After a little more feedback (on how to improve their plots, for example, and little details like capitalizing “Figure 1″ or using the prepositions with voltage and current), I switched to new material on hysteresis that they’ll need for tomorrow’s lab.  I actually gave them a fairly detailed description of hysteresis in the lab handout (I wonder if anyone has read it yet?), but I covered it again anyway. I also talked about DIP vs. SMD parts (the 74HC14N chip they’ll use is in a DIP), and introduced them to a simple relaxation oscillator.  We worked through how it functioned to produce a triangle wave on the input and square wave on the output, but I did not mention the capacitive coupling from the output to the input that changes the triangle wave rather dramatically when the capacitor in the RC circuit is small.

Input and output of a Schmitt-trigger relaxation oscillator (approx 67kHz). Note that the large output step is capacitively coupled to the input, causing a small step in addition to the expected triangle wave.

Input (yellow) and output (green) of a Schmitt-trigger relaxation oscillator (approx 67kHz). Note that the large output step is capacitively coupled to the input, causing a small step in addition to the expected triangle wave.  Note, the two traces are separate sweeps and the frequency modulation by 60Hz noise is big enough that the periods are not exactly the same on the two sweeps.  (click to embiggen)

The funny step in the input is not visible if large capacitors are used, but accounts for a big part of the charge transfer for small capacitors (throwing off the RC calculations that determine period).

With a 680kΩ resistor and a 10pF capacitor, attaching a BitScope probe to the input changes the period from about 4.5µs to about 14µs. With the same resistor and a 30pF capacitor, attaching the probe changes the period from 17.5µs to 28.5µs—the change due to the input impedance of the scope makes a big difference in the behavior of the circuit. I’ll have to make sure that the students observe the effect that a scope probe has on their circuit—they’re probably still thinking of the measurements as being non-disruptive.  (They may get even bigger changes in period with standard oscilloscope probes—with the 30pF capacitor I get periods of 220µs for a 1× probe and 30µs with a 10× probe on my Kikusui oscilloscope—the BitScope input is similar to the 10× probe.)

Last year’s hysteresis oscillator lab ran quite long, but I’m hoping for better time tomorrow. I went through the behavior of the oscillator a bit more thoroughly, and I think I impressed on them the importance of doing the algebra and calculations before lab time. I also suggested how they could find the input threshold voltages using PteroDAQ at home (triggering on both rising and falling edges).

2014 April 5

Hysteresis lab on KL25Z

Relaxation oscillator used in the hysteresis lab.  The "variable capacitor" in this schematic is a person's finger and a touch plate made from aluminum foil and packing tape.

Relaxation oscillator used in the hysteresis lab. The “variable capacitor” in this schematic is a person’s finger and a touch plate made from aluminum foil and packing tape.

I spent today writing code for the KL25Z board to act as a period or frequency detector for the hysteresis lab, where they build a relaxation oscillator using a 74HC14N Schmitt trigger inverter and use it to make a capacitance touch sensor (pictures of last year’s setup in Weekend work). I had written code for the Arduino boards last year, and I started by trying to do the same thing on the KL25Z, using the MBED online development system.  The Arduino code used “PulseIn()” to measure pulse duration, and the MBED system does not have an equivalent function.  I could have implemented PulseIn() with a couple of busy waits and a microsecond-resolution timer, but I decided to try using “InterruptIn” to get interrupts on each rising edge instead.

The basic idea of last year’s code (and the first couple versions I wrote today) was to determine the pulse duration or period when the board is reset, finding the maximum over a few hundred cycles, and using that as a set point to create two thresholds for switching an LED on or off. I got the code working, but I was not happy with it as a tool for the students to use.

The biggest problem is that the touch plate couples in 60Hz noise from the user’s finger, so the oscillator output signal is frequency modulated.  This frequency modulation can be large compared with the change in frequency from touching or not touching the plate (depending on how big C1 is), so setting the resistor and capacitor values for the oscillator got rather tricky, and the results were unreliable.

I then changed from reading instantaneous period to measuring frequency by counting edges in a 1/60th-second window.  That way the 60Hz frequency modulation of the oscillator gets averaged out, and we can get a fairly stable frequency reading.  The elimination of the 60Hz noise allows me to use less hysteresis in the on/off decision for the LED, making the touch sensor more sensitive without getting flicker on transitions. The code worked fairly well, but I was not happy with the maximum frequency that it could handle—the touch sensor gets more sensitive if C1 is small, which tends to result in high frequency oscillations. The problem with the code was that MBED’s InterruptIn implementation seems to have a lot of overhead, and the code missed the edge interrupts if they came more often than about every 12µsec.  Because I was interrupting on both rising and falling edges, the effective maximum frequency was about 40kHz, which was much lower than I wanted.

To fix the frequency limitation, I replaced MBED’s InterruptIn with my own interrupt service routine for PortD (I was using pin PTD4 as the interrupt input). With this change, I could go to about 800kHz (1.6e6 interrupts per second), which is plenty for this lab.  If I wanted to go to higher frequencies, I’d look at only rising edges, rather than rising+falling edges, to get another factor of two at the high end.  I didn’t make that change, because doing so would reduce the resolution of the frequency measurement at the low end, and I didn’t think that the tradeoff was worth it here.

The code is now robust to fairly large variations in the oscillator design.  It needs a 20% drop in frequency to turn on the green LED, but the initial frequency can be anywhere in the range 400Hz–800kHz.

To make it easier for students to debug their circuits, I took advantage of having an RGB LED on the board to indicate the state of the program: on reset, the LED is yellow, turning blue once a proper oscillator input has been detected, or red if the oscillator frequency is not in range. When the frequency drops sufficiently, the LED turns from blue to green, turning back to blue when the frequency goes up again.

For even more debugging help, I output the frequency that the board sees through the USB serial connection every 1/60th second, so that a program like the Arduino serial monitor can be used to see how much the frequency is changing.  I took advantage of that feature to make a plot of the frequency as the touch sensor was touched.

Plot of frequency of hysteresis oscillator, as the touch pad is touched three times.  Note that the thresholds are very conservatively set relative to the noise, but that the sensitivity is still much higher than needed to detect the finger touches.

Plot of frequency of hysteresis oscillator, as the touch pad is touched three times. Note that the thresholds are very conservatively set relative to the noise, but that the sensitivity is still much higher than needed to detect the finger touches.

Overall, I think that the code for the KL25Z is better than what I wrote last year for the Arduino—now I have to rewrite the lab handout to match! I actually need to update two lab handouts this weekend, since week 3 will have both the hysteresis lab and the sampling and aliasing lab. Unfortunately, the features needed for those labs (trigger on rising and falling edges and downsampling) are not working in PteroDAQ yet.

Here is the code that I wrote for the frequency detector:

// freq_detector_own_isr
// Kevin Karplus 
// 2014 Apr 5

// This program is intended to be used as a "capacitive touch sensor" 
// with an external relaxation oscillator whose frequency
// varies with the capacitance of a touch.

// The program expects a periodic square wave on pin PTD4 with a frequency between 
// about 400Hz and 800kHz. (LOW_FREQ_LIMIT and HIGH_FREQ_LIMIT).
// On reset, it displays a yellow light, then measures the frequency to store as the "off" frequency.
//
// If the frequency is out of range (say for a disconnected input), then the light is set to red, 
//     and the off frequency checked again.
// Otherwise the LED is turned blue.
// 
// After initialization, if the program detects a frequency 20% less than the initial freq, 
// it turns the light green, 
// turning it blue again when the the frequency increases to 90% of the original frequency.
//
// No floating-point is used, just integer arithmetic.
//
// Frequency measurements are made by counting the number of rising and falling edges
// in one cycle of the mains frequency (1/60 sec), giving somewhat poor resolution at lower 
// frequencies.  
// The counting time is chosen to that frequency modulation by the mains voltages is averaged out.
//
// This version of the code uses my own setup for the interrupt service routine, because InterruptIn has
// too much overhead.  I can go to over 800kHz (1.6e6 interrupts/second) with this setup, 
// but only about 40kHz (80e3) interrupts/sec with mbed's InterruptIn.

#include "mbed.h"

#define PCR_PORT_TO_USE (PORTD->PCR[4])   // pin PTD3 is the pin to use

#define MAINS_FREQ (60)     // frequency of electrical mains in Hz
#define COUNTING_TIME (1000000/MAINS_FREQ)   // duration in usec of one period of electrical mains

// off_frequency must be between LOW_FREQ_LIMIT and HIGH_FREQ_LIMIT for program to accept it
#define LOW_FREQ_LIMIT (400)
#define HIGH_FREQ_LIMIT (800000)

// on-board RGB LED
PwmOut rled(LED_RED);
PwmOut gled(LED_GREEN);
PwmOut bled(LED_BLUE);
#define PWM_PERIOD (255)  // for the on-board LEDs in microseconds

// Set the RGB led color to R,G,B  with 0 being off and PWM_PERIOD being full-on
void set_RGB_color(uint8_t R, uint8_t G, uint8_t B)
{
    rled.pulsewidth_us(PWM_PERIOD-R);
    gled.pulsewidth_us(PWM_PERIOD-G);
    bled.pulsewidth_us(PWM_PERIOD-B);
}


// InterruptIn square_in(PTD4);
volatile uint32_t edges_counted;

uint32_t low_freq_threshold, high_freq_threshold;  // thresholds for detecting frequency changes


extern "C"{
// interrupt routine that counts edges into edges_counted
    void PORTD_IRQHandler(void) 
    {
       edges_counted++;
       PCR_PORT_TO_USE |= PORT_PCR_ISF_MASK;
    }
}

// return the frequency for the square_in input in Hz
uint32_t frequency(void)
{    
    PCR_PORT_TO_USE &= ~PORT_PCR_IRQC_MASK;  // disable interrupts on pin PTD3
    edges_counted=0;
    PCR_PORT_TO_USE |= PORT_PCR_ISF_MASK | PORT_PCR_IRQC(11);  // clear interrupt for PTD3, and enable interrupt on either edge
    wait_us(COUNTING_TIME);
    PCR_PORT_TO_USE &= ~PORT_PCR_IRQC_MASK;  // disable interrupts on pin PTD3
    uint32_t freq=edges_counted*MAINS_FREQ/2; 
    return freq; 
}



int main() 
{   
    rled.period_us(PWM_PERIOD);
    gled.period_us(PWM_PERIOD);
    bled.period_us(PWM_PERIOD);
    set_RGB_color(255,255,0);   // set light to yellow
    
    SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; // make sure port D has clocks on
    PCR_PORT_TO_USE &= ~PORT_PCR_MUX_MASK;  // clearing the MUX field
    PCR_PORT_TO_USE |= PORT_PCR_MUX(1);     // Setting pin as GPIO
    FPTD->PDDR &= ~ (1<<4);  // make sure pin is input pin
    NVIC_EnableIRQ(PORTD_IRQn);            // enable interrupts for port D
    
    __enable_irq();

    uint32_t off_frequency= frequency();
    while ( off_frequency<low_freq_limit ||="" off_frequency="">HIGH_FREQ_LIMIT)
    {   // timed out.  set color to red and keep trying
        set_RGB_color(255,0,0);
        printf("FREQ out of range: %luHz\n", off_frequency);
        off_frequency= frequency();
    }
    
    uint32_t low_freq= 8*off_frequency/10;  // 80% of off_frequency
    uint32_t high_freq= 9*off_frequency/10;  // 90% of off_frequency
    
    printf("off= %luHz lo_thresh=%luHz hi_thresh=%luHz\n",off_frequency, low_freq, high_freq);
    while(1) 
    {   uint32_t freq=frequency();
        printf("%lu Hz\n",freq);  
        if (freq < low_freq)
        {   // low_fequency found, turn LED green
            set_RGB_color(0,255,0);
        }
        else if (freq >= high_freq)
        {   // high frequency found, turn LED blue again
            set_RGB_color(0,0,255);
        }    
    }
}

2013 March 23

Triangle-wave oscillator

Filed under: Circuits course — gasstationwithoutpumps @ 23:09
Tags: , , ,

One of the student suggestions from the “bar exam” was to design a protoboard for the class D amplifier, so that they could keep it as a permanent object (a more useful one than the pressure-sensor amplifier, since they don’t have any strain gauges).

I’ve been thinking about that and see a few problems:

  • The block diagram the students came up with this fall (with my guidance) calls for 3 power supplies, which makes the amplifier a bit impractical to power from a battery or wall-wart power supply.
  • The students used an external triangle-wave generator.
  • The protoboard would have to be fairly large to accommodate the FETs and inductor and enough wiring space, which would probably result in a larger board than 5cm × 5cm, and so $2/board rather than $1/board.

I’ve not given much thought yet to the power-supply problem, but I did think a little about the triangle-wave generator.  Since they only need to generate triangle waves at a single frequency (in the 60kHZ–100kHz range), it should be possible to use a hysteresis oscillator with an integrator rather than a simple RC timing circuit.  Something like the following might work:

triangle-wave-oscillator

The slew rate of the MCP6004 op amps is only 0.6 V/µs, but the triangle wave only swings from VIL to VIH, or about 1V, so the minimum period is about 3.3µs, for a maximum frequency of 300kHz. If we use another op amp to amplify the signal to make it swing almost 5v, instead of 1V, the maximum frequency would be only 60kHz.

I might want to try this circuit out this week, to see if it is worth having the students play with next year.

2013 February 25

Tinkering lab reports show problems

Filed under: Circuits course — gasstationwithoutpumps @ 11:53
Tags: , , , ,

I thought that the tinkering lab (lab handout)had gone ok, because students had done a lot of experimenting and had all ended up with functional circuits.  But the lab reports that I graded this weekend indicated some serious problems:

  • A lot of the students made serious errors on their schematics.  Shorts, missing wires, and mislabeled parts were common. I’m making the students who had serious errors redo the report, and keep redoing it until they can produce correct schematics.  It wasn’t just the weakest students in the class making errors on the schematics—almost everyone was.
  • A lot of the students did not check their predictions of the behavior of the board when components were added between pairs of terminals.  If their initial predictions had been accurate, this would not have been a problem, but students with predictions that were way off didn’t check them.
  • There was no evidence that anyone improved their mental model of how the hysteresis oscillator worked as a result of either making the observations (which about half the class did) or thinking about the model more (which those who did not check their predictions could have done).
  • Some of the students appear to have poor technique for recording observations, as they tabulated observations that were not really consistent with how the boards behave.  Either they mis-recorded the conditions under which they did the test or they shorted together some nodes without noticing.  No one checked for consistency of the observations to see whether things that should have been nearly the same were nearly the same.

I’ll probably rant in class about wrong schematics ruining otherwise fine reports, and hope the message gets through that they have to check their work much more carefully.  They’ll really suffer on the labs that they have to solder up on the protoboards if they continue to work with such sloppy, useless schematics. I may rant about lab notebook technique also, since that will be even more important in biomolecular labs.

Next year, I’ll want to split this lab into 2, with one lab dedicated to collecting data, a class in between to analyze the data, and the next lab dedicated to doing the design.

 

 

Next Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 275 other followers

%d bloggers like this: