Hi all,
For a while i have been using pedvide's ADC library to use PDB to trigger DMA to move ADC conversions.
I would like to add the Audio library for pulsing sine waves modulated using the envelope function.
To this end, i used the Audio generation tool.
Upon testing the sine wave alone, it works flawlessly sampling DAC0 on my scope looks exactly like it should.
However, including the ADC object into the code instantly makes any output disappear.
I tried ploughing through the ADC.cpp and ADCmodule.cpp source code to find the origin of this error but cannot find it.
My code:
I found in some posts on the ADC library that the ADC object should be called first before any audio stuff is done, but that does not solve the problem.
Basically, commenting all the ADC stuff except for even calling the ADC object stops DAC output.
I'm stuck. Can anybody offer any insights as to what the reason is and how to fix it?
Thanks in advance for reading
For a while i have been using pedvide's ADC library to use PDB to trigger DMA to move ADC conversions.
I would like to add the Audio library for pulsing sine waves modulated using the envelope function.
To this end, i used the Audio generation tool.
Upon testing the sine wave alone, it works flawlessly sampling DAC0 on my scope looks exactly like it should.
However, including the ADC object into the code instantly makes any output disappear.
I tried ploughing through the ADC.cpp and ADCmodule.cpp source code to find the origin of this error but cannot find it.
My code:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Arduino.h>
#include <ADC.h>
#include <DMAChannel.h>
#define MeasurementPin A11 // read signal connected to analog pin 0, Connects to ADC1
// Samples
int pts = 3000; // this is the default amount of measurement points transfered to the Serial interface
const int ptsmax = 32767; // maximum # of measurement points. (2^15-1) ( due to register bit CITER in TCD (15-bit if channel linking disabled) ), any larger and the DMA wont work.
uint16_t samples[ptsmax]; // saving the samples that are read to the internal memory
volatile boolean sampleDone = false;
String readInput = ""; // String used to determine what the MCU has to do
uint32_t Fs = 12000; // sample rate in Hz
//ADC object and DMA channel used for sampling.
// CREATE THE ADC OBJECT FIRST, BEFORE ALL AUDIO STUFF!!
ADC *adc = new ADC(); // adc object. Use ADC1 (and thus PDB0_CH1C1) since the Audio library already uses ADC0 (and thus PDB0_CH0C1)
int adcStat = 0; // status of ADC, keeps check of status for either default measurement(0) or other (1)
DMAChannel dmaADC; // dmaADC Channel used to move data from the ADC to the memory location o samples[]
// GUItool: begin automatically generated code // DEFINE ANY AUDIO STUFF AFTER ADC has been called!!!!!!!!!
AudioSynthWaveformSine sine1;
AudioEffectEnvelope envelope1;
AudioOutputAnalog dac0;
AudioConnection patchCord1(sine1, envelope1);
AudioConnection patchCord2(envelope1, dac0);
void measure() { // To start measuring, all that needs to happen is to start the PDB, the rest happens automatically.
adc->adc1->startPDB(Fs); //frequency in Hz
}
void pdb_isr() {
PDB0_SC &= ~PDB_SC_PDBIF; // clear interrupt
Serial.println("pdb isr");
}
void adc1_isr() {
Serial.println("adc1 isr"); // you can uncomment this, but the dmaADC already clears the interrupt so this should never print!
}
void dmaADC_isr() {
dmaADC.clearInterrupt();
adc->adc1->stopPDB();
sampleDone = true;
//Serial.println("dmaADC isr");
}
void dmaADCInit() {
dmaADC.source(*(uint16_t*) &ADC1_RA);
dmaADC.destinationBuffer(samples, sizeof(samples));
dmaADC.attachInterrupt(dmaADC_isr);
dmaADC.interruptAtCompletion();
dmaADC.triggerAtHardwareEvent(DMAMUX_SOURCE_ADC1);
dmaADC.enable();
}
void setAdcSig() {
adc->enableInterrupts(ADC_1); // it's necessary to enable interrupts for PDB to work
adc->enableDMA(ADC_1); // enable DMA requrest; ADC1_SC2 |= | ADC_SC2_ADTRG | ADC_SC2_DMAEN;
adcStat = 0;
}
void setup() {
// Setup the Audio output DAC sine and envelope values.
AudioMemory(20);
//sine1.phase(0);
sine1.frequency((float)2000);
sine1.amplitude(1); // default disable!
envelope1.delay(0);
envelope1.attack(0.5);
envelope1.hold(0);
envelope1.decay(0);
envelope1.sustain(1); //when the note is in the sustain phase, it is ON.
envelope1.release(0.5);
// setup DMA
dmaADCInit(); delay(50);
// initialize the ADC for ADC1 (measurement signal pin)
adc->setReference(ADC_REFERENCE::REF_3V3, ADC_1); // set voltage reference
adc->setAveraging(8, ADC_1); // set number of averages
adc->setResolution(12, ADC_1); // set bits of resolution
// it can be any of the ADC_CONVERSION_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED_16BITS, HIGH_SPEED or VERY_HIGH_SPEED
// where the numbers are the frequency of the ADC clock in MHz and are independent on the bus speed.
adc->setConversionSpeed(ADC_CONVERSION_SPEED::MED_SPEED, ADC_1); // change the conversion speed
// it can be any of the ADC_SAMPLING_SPEED enum: VERY_LOW_SPEED, LOW_SPEED, MED_SPEED, HIGH_SPEED or VERY_HIGH_SPEED
adc->setSamplingSpeed(ADC_SAMPLING_SPEED::MED_SPEED, ADC_1); // change the sampling speed // max 35kHz with MED_SPEED, but 32kHz to get to the Hz accurate. (This is also the limit set in Matlab)
adc->analogRead(MeasurementPin, ADC_1); // call this to setup everything before the pdb starts
// setup final ADC; enable interrupts and enable DMA.
setAdcSig(); delay(50);
// initialize Serial communications to the host computer:
Serial.begin(9600); // the Teensy does not care at what speed it is running, will always be USB Full speed
}
void loop() {
if (Serial.available() > 0) { // some
readInput = Serial.readStringUntil('\n');
if (readInput == "on") {
Serial.println("note_on");
envelope1.noteOn();
} else if (readInput == "off") {
Serial.println("note_off");
envelope1.noteOff();
} else if (readInput == "measure") {
Serial.println("measuring");
// measure();
}
}
}
I found in some posts on the ADC library that the ADC object should be called first before any audio stuff is done, but that does not solve the problem.
Basically, commenting all the ADC stuff except for even calling the ADC object stops DAC output.
Code:
ADC *adc = new ADC(); // adc object. Use ADC1 (and thus PDB0_CH1C1) since the Audio library already uses ADC0 (and thus PDB0_CH0C1)
Thanks in advance for reading