germabooking.blogg.se

Electronic workbench clock sch
Electronic workbench clock sch




electronic workbench clock sch
  1. #Electronic workbench clock sch generator#
  2. #Electronic workbench clock sch serial#
  3. #Electronic workbench clock sch code#

beginTransaction( SPISettings( 8000000, MSBFIRST, SPI_MODE0)) ĭDSBuffer. Uint32_t DeltaPhase // DDS expects MSB first!ĭouble DDSClock = 180.0e6 // nominal DDS oscillatorĭouble CountPerHertz, HertzPerCount // DDS delta-phase incrementsĭouble Crystal = 20.0e6 // nominal DDS frequencyĭouble Deviation = 5.0e3 // nominal FM signal deviation (one-sided)ĭigitalWriteFast(pin,! digitalRead(pin)) ĭigitalWriteFast(PIN_DDS_FQUD,HIGH) // latch previously shifted bitsĪdc-> startSingleRead(PIN_AUDIO, ADC_0) // start ADC conversionĪnalogWriteDAC0(AnalogSample) // show previous audio sampleĪnalogSample = adc-> readSingle() // fetch just-finished sample Int SamplePeriod = 25 // microseconds per analog sample

#Electronic workbench clock sch code#

The TeensyDuino source code as a GitHub Gist: Now, to begin paying attention to those pesky hardware details … Which means I can avoid screwing around with fixed-point arithmetic until such time as clawing back a few microseconds makes a meaningful difference. Nicely inside the range of values reported by the main loop, whew.

  • Add 2048 to get the actual ADC sample: 2047.
  • Multiply by half the ADC range (4096/2) to get ADC counts: -1.003.
  • Divide by nominal 5.0 kHz deviation to get fractional modulation: -4.89.9e-6.
  • Subtract nominal 20.0 MHz crystal to get modulation: -2.4494 Hz.
  • DDS delta-phase register bytes: 1C 71 C6 E2 = 477218530 decimal.
  • You can confirm the SPI data by working backwards with a calculator: The program calculates and displays various “constants” I set for convenience: SPI.endTransaction() // do not raise FQ_UD until next timer tick!Ī closer look lets the scope decode and present the SPI data: DDS Mock – 0 VAC – SPI detail SPI.transfer((uint8_t)DDSBuffer.DeltaPhase) SPI.transfer((uint8_t)(DDSBuffer.DeltaPhase > 8)) If (Audio > AudioMax) // ignore race conditions SPI.transfer((uint8_t)(DDSBuffer.DeltaPhase > 24)) // MSB first! SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0)) ĭDSBuffer.DeltaPhase = (uint32_t)((((double)Audio / 2048.0) * Deviation + Crystal) * CountPerHertz) The 1.9 μs gap between the first and second burst of SPI clocks contains all the floating-point calculations required to convert an ADC sample to DDS delta-phase bits:ĪnalogSample = adc->readSingle() // fetch just-finished sampleĪudio = AnalogSample - 2048 // convert to AC signal

    #Electronic workbench clock sch generator#

    However, the “circuit” is an open-air hairball on the bench, driven from the scope’s arbitrary waveform generator in high-Z mode, so things can only get better with more any attention to detail. The loop() dumps the min and max ADC values (minus half the ADC range (4096/2= 2048):Ī span of half a dozen counts = 3 bits means the 12 bit ADC really delivers 9 bits = 0.2% resolution = 54 dB dynamic range = probably not good enough. The purple trace shows the analog input voltage hovering close to a constant V CC/2 (about 1.6+ V), rather than the sine-wave I used earlier, again courtesy of the scope’s arbitrary function generator.

    electronic workbench clock sch

    The vertical cursors show the combination of fast conversion and averaging requires 7 μs (-ish) from start to finish: long enough to justify separating the two by an interrupt and short enough to allow calculations after fetching the result. The ADC hardware can return the average of several sample taken in quick succession, so I set it to average four samples. I set the ADC to HIGH_SPEED conversion and sampling, reducing the time between the start of conversion (first pulse in D1) and the ADC end-of-conversion interrupt (rising edge in D2) from 4.7 μs to 2.6 μs, more-or-less, kinda-sorta. The ARM Teensy connects the board's built-in LED to the same SPI clock as on the AVR Arduinos, so it's only useful during startup, but having some hint will come in handy the next time it jams for another reason.ĭoing the DDS calculations in full-frontal double floating point turns out to be maybe fast enough: DDS Mock – 0 VAC – SPI

    #Electronic workbench clock sch serial#

    The serial startup delay seems to vary unpredictably between 8 ms, so 3000 ms may be too short: Serial.printf(" serial wait: %d ms\n\n",waited) The gotcha happens when the USB port doesn’t become available, in which case the conditional remains true and the loop continues forever, which is precisely what happened when I powered the Teensy from a USB battery pack on the Squidwrench Operating Table.Īfter some flailing around, this startup snippet falls through after ahem awhile: Needed for native USBĪs it happens, you must also use that test on the ARM-based Teensy 3.6. The Arduino Serial doc says the USB hardware on the (now obsolescent) Leonardo requires a test-for-open before using the serial port:






    Electronic workbench clock sch