From 7131e46ff06d3f2a11b39fb92af7da17551423b1 Mon Sep 17 00:00:00 2001 From: Stephen Olesen Date: Sat, 4 Jul 2015 18:31:18 -0600 Subject: [PATCH] Allow refclkOffset to be set on the fly in DDS and the calibration tool. --- DDS.cpp | 2 +- DDS.h | 11 ++++++- .../Crystal-Calibration.ino | 31 +++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/DDS.cpp b/DDS.cpp index e4141bd..8772fc7 100644 --- a/DDS.cpp +++ b/DDS.cpp @@ -89,7 +89,7 @@ ddsAccumulator_t DDS::calcFrequency(unsigned short freq) { newStep = (600.0 / (DDS_REFCLK_DEFAULT+DDS_REFCLK_OFFSET)) * pow(2,ACCUMULATOR_BITS); } } else { - newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+DDS_REFCLK_OFFSET); + newStep = pow(2,ACCUMULATOR_BITS)*freq / (refclk+refclkOffset); } return newStep; } diff --git a/DDS.h b/DDS.h index 79b23ef..441e22e 100644 --- a/DDS.h +++ b/DDS.h @@ -181,7 +181,8 @@ static const int8_t ddsSineTable[256] PROGMEM = { class DDS { public: - DDS(): refclk(DDS_REFCLK_DEFAULT), accumulator(0), running(false), + DDS(): refclk(DDS_REFCLK_DEFAULT), refclkOffset(DDS_REFCLK_OFFSET), + accumulator(0), running(false), timeLimited(false), tickDuration(0), amplitude(255) {}; @@ -244,6 +245,13 @@ public: return refclk; } + void setReferenceOffset(int16_t offset) { + refclkOffset = offset; + } + int16_t getReferenceOffset() { + return refclkOffset; + } + uint8_t getDutyCycle(); // Set a scaling factor. To keep things quick, this is a power of 2 value. @@ -263,6 +271,7 @@ private: volatile ddsAccumulator_t accumulator; volatile ddsAccumulator_t stepRate; ddsAccumulator_t refclk; + int16_t refclkOffset; static DDS *sDDS; }; diff --git a/examples/Crystal-Calibration/Crystal-Calibration.ino b/examples/Crystal-Calibration/Crystal-Calibration.ino index f59b256..58c8b89 100644 --- a/examples/Crystal-Calibration/Crystal-Calibration.ino +++ b/examples/Crystal-Calibration/Crystal-Calibration.ino @@ -31,7 +31,8 @@ enum Sets { SET_REF, SET_TONE, SET_AMPLITUDE, - SET_ADC_HALF + SET_ADC_HALF, + SET_OFFSET } setting = SET_TONE; char freqBuffer[8]; @@ -47,6 +48,7 @@ void loop() { static uint16_t samples = 0; static uint16_t pulse; static uint32_t lastOutput = 0; + static float pulseFloat = 0.0; if(recordedPulse) { uint32_t pulseAveraging; uint16_t tmpPulse; @@ -56,9 +58,11 @@ void loop() { sei(); if(samples++ == 0) { pulse = tmpPulse; + //pulseFloat = tmpPulse; } else { pulseAveraging = (pulse + tmpPulse) >> 1; pulse = pulseAveraging; + pulseFloat = pulseFloat + 0.01*((float)pulse-pulseFloat); } if((lastOutput + 1000) < millis()) { Serial.print(F("Pulse: ")); @@ -74,7 +78,17 @@ void loop() { Serial.print(F("Freq: ")); // F = 1/(pulse*(1/ref)) // F = ref/pulse - Serial.println((float)(dds.getReferenceClock()+(float)DDS_REFCLK_OFFSET)/(float)pulse); + Serial.print((float)((float)dds.getReferenceClock()+(float)dds.getReferenceOffset())/(float)pulse); + Serial.print(F(" / ")); + Serial.print((float)((float)dds.getReferenceClock()+(float)dds.getReferenceOffset())/pulseFloat); + Serial.print(F(" / ")); + Serial.println(pulseFloat); + Serial.print(F("Freq2: ")); + // F = 1/(pulse*(1/ref)) + // F = ref/pulse + Serial.print((float)dds.getReferenceClock()/(float)pulse); + Serial.print(F(" / ")); + Serial.println((float)dds.getReferenceClock()/pulseFloat); samples = 0; lastOutput = millis(); } @@ -87,6 +101,7 @@ void loop() { Serial.println(F("Commands:")); Serial.println(F("RefClk: u = +10, U = +100, r XXXX = XXXX")); Serial.println(F(" d = -10, D = -100")); + Serial.println(F("Offset: s XXX = Set refclk offset")); Serial.println(F("Radio: T = transmit, R = receive")); Serial.println(F("Tone: t XXXX = XXXX Hz")); Serial.println(F("Amp.: a XXX = XXX out of 255")); @@ -164,6 +179,9 @@ void loop() { case 'm': setting = SET_ADC_HALF; break; + case 's': + setting = SET_OFFSET; + break; case 'o': dds.on(); Serial.println("> "); @@ -173,7 +191,7 @@ void loop() { Serial.println("> "); break; default: - if(c >= '0' && c <= '9') { + if(c == '-' || (c >= '0' && c <= '9')) { *freqBufferPtr = c; freqBufferPtr++; } @@ -200,6 +218,11 @@ void loop() { adcHalf = freq&0xFF; Serial.print(F("ADC midpoint set to ")); Serial.println((uint8_t)(freq&0xFF)); + } else if(setting == SET_OFFSET) { + dds.setReferenceOffset((int16_t)atoi(freqBuffer)); + dds.setFrequency(lastFreq); + Serial.print(F("Refclk offset: ")); + Serial.println(dds.getReferenceOffset()); } Serial.println("> "); } @@ -211,9 +234,11 @@ void loop() { ISR(ADC_vect) { static uint16_t pulseLength = 0; static uint8_t lastADC = 127; + cli(); TIFR1 = _BV(ICF1); PORTD |= _BV(2); dds.clockTick(); + sei(); if(listening) { pulseLength++; if(ADCH >= adcHalf && lastADC < adcHalf) {