First off, I apologize if I am posting this in the wrong location as I am new to the forum.
I am planning to use the Teensy 3.1 to modulate a VCO tuning pin. Using the default DAC configuration supplied by the library code I was able to provide fairly coarse modulation. This produces a very clean output. At the hardware level, A14 is connected to a 2-pole LC filter with a corner frequency of about 20kHz which then feeds the VCO tuning pin.
I only need a signal with a DC level up to a few hundred mV and an AC component of around 6mV or so. I thought I would change the DAC reference from DACREF_2 (external AREF at 3.3V) to DACREF_1 which would supply an internally generated 1.2V reference and produce finer DAC step size. This did in fact change the DAC resolution but the odd thing is now there seems to be a significant amount of noise on the DAC output. There are 2 components to the noise. First is a ~6mV sine wave at ~33kHz. The second is a periodic event which appears to be some coupled switching every 3ms. The 6mV noise causes undesirable noise in my spectrum and can't be filtered because it's on the order of what I need to use for modulation. The switching noise could be snubbed with some sort of bandpass filter arrangement but I have not attempted to address this yet. What I am hoping is there is a firmware solution
.
The code is relatively simple. It creates an interval timer that at the moment just toggles a variable state which CAN be, but is currently not, used to create a high or low key for a binary FSK type modulation. The interval time is the modulation rate. Serial is used to change the DC offset for the DAC output and an LED is toggled when each serial DC value is processed. The reference voltage bit(6) in DAC0_C0 is cleared after the library call to analogWrite() so no changes to library code needed to be made. This might be the source of the trouble. See code below.
Any thoughts would be greatly appreciated.
Thanks, Mark
I am planning to use the Teensy 3.1 to modulate a VCO tuning pin. Using the default DAC configuration supplied by the library code I was able to provide fairly coarse modulation. This produces a very clean output. At the hardware level, A14 is connected to a 2-pole LC filter with a corner frequency of about 20kHz which then feeds the VCO tuning pin.
I only need a signal with a DC level up to a few hundred mV and an AC component of around 6mV or so. I thought I would change the DAC reference from DACREF_2 (external AREF at 3.3V) to DACREF_1 which would supply an internally generated 1.2V reference and produce finer DAC step size. This did in fact change the DAC resolution but the odd thing is now there seems to be a significant amount of noise on the DAC output. There are 2 components to the noise. First is a ~6mV sine wave at ~33kHz. The second is a periodic event which appears to be some coupled switching every 3ms. The 6mV noise causes undesirable noise in my spectrum and can't be filtered because it's on the order of what I need to use for modulation. The switching noise could be snubbed with some sort of bandpass filter arrangement but I have not attempted to address this yet. What I am hoping is there is a firmware solution
The code is relatively simple. It creates an interval timer that at the moment just toggles a variable state which CAN be, but is currently not, used to create a high or low key for a binary FSK type modulation. The interval time is the modulation rate. Serial is used to change the DC offset for the DAC output and an LED is toggled when each serial DC value is processed. The reference voltage bit(6) in DAC0_C0 is cleared after the library call to analogWrite() so no changes to library code needed to be made. This might be the source of the trouble. See code below.
Any thoughts would be greatly appreciated.
Thanks, Mark
Code:
#define COUNT_LIM 4096
//Global vars
int inputValue = 0; // an int to hold incoming data
String inputString = ""; // a string to hold incoming data
boolean valueComplete = false; // whether the string is complete
int fskState = LOW;
// Create an IntervalTimer object
IntervalTimer myTimer;
void setup()
{
// Initialize the DAC output pins
analogWriteResolution(12);
// Setup the Teensy LED as and output
pinMode(13, OUTPUT);
//Initialize the USB UART serial at 9600 baud with a RX buffer of 10 chars
Serial.begin(9600);
inputString.reserve(10);
// 1/8212.28 = 1.217688632146005737748834671979e-4
// myTimer.begin(event_timer, 122); // ~4106 baud
myTimer.begin(event_timer, 30); // Trying a higher data rate
}
// Loop forever
void loop()
{
if(Serial.available())
serialEvent();
if(valueComplete)
{
//Toggle the LED
digitalWrite(13, !digitalRead(13));
// Convert the string to an int
inputValue = inputString.toInt();
//Limit the input value to 12 bits
if(inputValue > COUNT_LIM)
inputValue = COUNT_LIM;
//Send back the new value for confirmation.
Serial.println(inputValue);
//Clear the flag and received string
valueComplete = false;
inputString = "";
}
}
// Handle serial reception
void serialEvent()
{
// get the new byte:
char inChar = (char)Serial.read();
inputString += inChar;
//Build the decimal value of the string
inputValue += (unsigned int)inChar;
// if the incoming character is a newline, set a flag
// so the main loop can do something about it:
if (inChar == '\n') {
valueComplete = true;
}
}
// Generates the modulation clock
void event_timer(void)
{
if (fskState == LOW)
{
fskState = HIGH;
}
else
{
fskState = LOW;
}
// analogWrite(A14, inputValue + (fskState));
analogWrite(A14, inputValue);
DAC0_C0 &= 0b10111111; //uses 1.2V reference for DAC instead of 3.3V
}