Wozzy
Well-known member
I developed this frequency locked sine wave generator to emulate a strain gauge signal from a piece of rotating machinery that has a 1/REV encoder output.
The program is not very elegant. It consists of a mashup between FreqMeasure and IntervalTimer and Pauls analog output example.
The machine I need to emulate only goes up to 2000 RPM so 0 to 35 Hz was sufficient for my purpose.
The resultant output wave is quite nice at these low frequencies.
I'd love to hear any suggestions for other methods to achieve this in a more efficient way.
I'm sure the Teensy 3.1 is capable of producing smooth frequency and phase locked sine waves at much higher frequencies.
I'd actually like to generate a more complicated waveform, but I either need limit my frequency, or live with a steppier sine wave output.
Here's a photo showing the Sine wave locked to the input signal
(Click here for YouTube video)
Full code is attached below:
The program is not very elegant. It consists of a mashup between FreqMeasure and IntervalTimer and Pauls analog output example.
The machine I need to emulate only goes up to 2000 RPM so 0 to 35 Hz was sufficient for my purpose.
The resultant output wave is quite nice at these low frequencies.
I'd love to hear any suggestions for other methods to achieve this in a more efficient way.
I'm sure the Teensy 3.1 is capable of producing smooth frequency and phase locked sine waves at much higher frequencies.
I'd actually like to generate a more complicated waveform, but I either need limit my frequency, or live with a steppier sine wave output.
Here's a photo showing the Sine wave locked to the input signal
(Click here for YouTube video)
Full code is attached below:
Code:
/* Frequency Locked Sine Wave Generator
* R. Wozniak 09/13/2014
* Generates an analog sine wave that is locked to the frequency of
* a digital input pulse - Used to simulate strain gage on rotating
* machinery with 1/REV encoder signal
*
* Only runs on Teensy 3.1 which has a true Digital to Analog Converter
* Compile for 96 MHz <Tools/CPU Speed: "96MHZ (overclock)">
* Good for 0 to 35 Hz
*
* Wiring:
* Squarewave input on Teensy 3.1 Pin3 (approx 3.3V - must be less than 5 V}
* Analog sinewave output on Teensy 3.1 DAC pin (0 to 3.3V)
*
*
* FreqMeasure Library - Example with serial output
* http://www.pjrc.com/teensy/td_libs_FreqMeasure.html
*
* This example code is in the public domain.
*/
#include <FreqMeasure.h>
IntervalTimer myTimer;
float clock = 95.99899; // Clock Calibration Factor for my teensy 3.1 at 96 MHz
volatile float period;
float phase = 0.0;
float twopi = 3.14159265 * 2;
float amplitude;
int steps = 500; // number of phase angle steps for sinewave generation
// a smaller number will here allow to go to higher frequency
// but will result in a steppier sine curve.
float phasestep = twopi/(steps);
void setup() {
analogWriteResolution(12);
FreqMeasure.begin();
}
void loop() {
if (FreqMeasure.available()) {
period = FreqMeasure.read()/(clock*steps/2);
myTimer.end();
phase = 0.0;
myTimer.begin(sinewave,period); // create step sinewave
}
}
void sinewave(void) {
amplitude = (sin(phase) * 2000.0) + 2050.0;
//amplitude = (cos(phase) * 2000.0) + 2050.0;
analogWrite(A14, (int)amplitude);
phase = phase + phasestep;
if (phase >= twopi) phase = 0;
}
Last edited: