Hey all,
I am trying to simulate the output of a variable reluctance sensor that is typically mounted to read a tone wheel on the differential or axle of a vehicle. This particular signal is typically a sin wave of 4000 pulses per mile. If a vehicle is traveling at 1 mph that is 4000 pulses per hour or 1.11 pulses per sec (1 Hz).
Using my limited coding knowledge, I stripped down the simple waveform generator (https://docs.arduino.cc/tutorials/due/simple-waveform-generator/) as far as I could to hopefully output a sine wave signal from the DAC0 ADC port of my arduino DUE at a commanded frequency (freq).
The details on the generator mention it is sufficient for a frequency range of 1Hz to 170Hz for reasons beyond my understanding. That 170Hz is equivalent to 153 mph if my math is correct and should be fast enough to get us in the range.
The issue is that the waveform looks really funky below 3 hz (freq = 3) in a non interpolated serial plot oscilloscope I made with an arduino uno and it seems to be moving a LOT faster than 1 Hz on the plot when I set freq to 1Hz. That said, here are the codes...
Oscilloscope on Uno:
const int analogPin = A0;
void setup() {
//Setup serial connection
Serial.begin(9600);
}
void loop() {
//Read analog pin
int val = analogRead(analogPin);
//Write analog value to serial port:
Serial.write( 0xff );
Serial.write( (val >> 8) & 0xff );
Serial.write( val & 0xff );
}
Waveforms2 Library:
//
// Waveforms2.h
//
//
// "Simple Waveform Genetator with Arduino Due." Accessed: September 20, 2015. <https://www.arduino.cc/en/Tutorial/DueSimpleWaveformGenerator>
//
//
#ifndef _Waveforms2_h_
#define _Waveforms2_h_
#define maxWaveform 1
#define maxSamplesNum 120
static int waveformsTable[maxWaveform][maxSamplesNum] = {
/*
{ 2047, 2154, 2261, 2367
*/
// Sin wave
{
0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
}
};
#endif
Sine Wave Generator: (I have removed potentiometer but left the comments to see if there is a more elegant way to map or use the freq variable.)
/*
Simple Waveform generator with Arduino Due
*/
#include "Waveforms2.h"
#define oneHzSample 1000000/maxSamplesNum // sample for the 1Hz signal expressed in microseconds
int wave0 = 0;
int i = 0;
int sample;
int freq = 3;
void setup() {
analogWriteResolution(12); // set the analog output resolution to 12 bit (4096 levels)
}
void loop() {
// Read the the potentiometer and map the value between the maximum and the minimum sample available
// 1 Hz is the minimum freq for the complete wave
// 170 Hz is the maximum freq for the complete wave. Measured considering the loop and the analogRead() time
sample = map(freq, 0, 4095, 0, oneHzSample);
sample = constrain(sample, 0, oneHzSample);
analogWrite(DAC0, waveformsTable[wave0][i]); // write the selected waveform on DAC0
i++;
if(i == maxSamplesNum) // Reset the counter to repeat the wave
i = 0;
delayMicroseconds(sample); // Hold the sample value for the sample time
}