From 731c5abbbc7f390d9a9408c46c628f6a9e7735fa Mon Sep 17 00:00:00 2001 From: Cynopolis Date: Sun, 10 Oct 2021 13:17:34 -0500 Subject: [PATCH] First draft of the waveform generator. --- Waveform Converter.xlsx | Bin 34145 -> 0 bytes src/main.cpp | 118 ++++++++++++++++++++++++++++------------ 2 files changed, 82 insertions(+), 36 deletions(-) delete mode 100644 Waveform Converter.xlsx diff --git a/Waveform Converter.xlsx b/Waveform Converter.xlsx deleted file mode 100644 index 762943d5731e7a1262568f1e6c1488777d4cd3aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 34145 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°0pgA;qJ=KRpy9Lm;+)-PN-T$JCw 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 #include #include -#include -//#include + //uncomment to enable serial output for debugging #define enable_serial_debug @@ -27,8 +29,11 @@ #define waveform_pin DAC0 #define amplitude_pin DAC1 #define sync_pin 2 +#define single_pulse_flag_pin 28 +#define single_pulse_trig_pin 29 +#define slow_pulse_flag_pin 30 -// Number of waveforms available +// Number of waveforms available. Change this if you add or remove waveforms #define waveform_num 4 // Array of waveform arrays. Currently holds four waveforms with 600 samples each. int waveforms[waveform_num][600] = { @@ -54,35 +59,64 @@ long new_waveform = 2; long old_waveform = 2; int waveform_select = 2; -//Setup LCD Display -LiquidCrystal_I2C lcd(0x27,16,2); -// Timer to regulate the step width -int timer = 0; + unsigned int millis_period = 13; +//Used to debounce the trigger input +boolean has_single_pulsed = false; +unsigned long deb_timer = 0; + + +/* Cycle through the waveform samples over a given period of time +* The time scalar argument changes how many samples it will skip. +* A value of 1 will not skip any samples, a value of 2 will use every 2nd sammple, and a value of 5 will use every 5th sample. +* This allows you to sacrifice resolution for speed. A value of 2 will take half the time to create a waveform pulse +*/ +void generate_waveform(int time_scalar){ + // The period of time each sample in the array should take in microseconds + // The 1000 converts from milliseconds to microseconds, and the 600 deivides by the number of samples in the array + // The -3 offset compensates for a 3 millisecond overhead created by the time it takes to do all of the calculations + unsigned int sample_period = (new_period-3)*1000/600; + + // Timer to regulate the step width + int timer = 0; + + //Loop through all of the samples in the array and output them to Dac 0 + for(int i = 0; i < 600; i=i+time_scalar){ + while(micros()-timer < sample_period); + analogWrite(waveform_pin, waveforms[new_waveform][i]); + timer = micros(); + } +} void setup() { //The sync pin can be run into an oscilliscope's trig channel to easiy find the waveform pinMode(sync_pin, OUTPUT); + pinMode(single_pulse_flag_pin, INPUT_PULLUP); + pinMode(single_pulse_trig_pin, INPUT_PULLUP); + pinMode(slow_pulse_flag_pin, INPUT_PULLUP); + //Change the resolution of the analog ourput to its maximum (12 bit res) analogWriteResolution(12); - //If serial debugging is enabled set up serial - #ifdef enable_serial_debug - Serial.begin(115200); - #endif + // Initialize timers and encoders - timer = micros(); amp_encoder.write(new_amp*4); period_encoder.write(new_period*4); waveform_encoder.write(new_waveform*4); - lcd.init(); // initialize the lcd - lcd.backlight(); + // Only executes this block of code if serial debug is enabled + #ifdef enable_serial_debug + Serial.begin(115200); + Serial.print("Ampltidue: "); + Serial.println(map(new_amp, 0, 127, 0, 4095)); + Serial.print("Period: "); + Serial.println(new_period); + Serial.print("Waveform #: "); + Serial.println(new_waveform); + #endif } void loop() { - lcd.setCursor(0,0); - lcd.print("Hello"); // Read in encoder values new_amp = amp_encoder.read()/4; new_period = period_encoder.read()/4; @@ -102,6 +136,10 @@ void loop() { amp_encoder.write(new_amp*4); } old_amp = new_amp; + #ifdef enable_serial_debug + Serial.print("Ampltidue: "); + Serial.println(map(new_amp, 0, 127, 0, 4095)); + #endif } //Handles period encoder @@ -117,6 +155,10 @@ void loop() { period_encoder.write(new_period*4); } old_period = new_period; + #ifdef enable_serial_debug + Serial.print("Period: "); + Serial.println(new_period); + #endif } //Handles waveform encoder @@ -131,6 +173,10 @@ void loop() { waveform_encoder.write(new_waveform*4); } old_waveform = new_waveform; + #ifdef enable_serial_debug + Serial.print("Waveform #: "); + Serial.println(new_waveform); + #endif } // Creates a synch signal so an oscilliscope can more easily read irregular pulses @@ -138,26 +184,26 @@ void loop() { // Output a signal to control the amplitude analogWrite(amplitude_pin, map(new_amp, 0, 127, 0, 4095)); + + // Check to see if the single pulse pin has been pulled LOW + if(!digitalRead(single_pulse_flag_pin)){ + if(deb_timer-millis() > 100){ + if(!digitalRead(single_pulse_trig_pin) && has_single_pulsed == false){ + generate_waveform(1); + has_single_pulsed = true; + deb_timer = millis(); + } + else if(digitalRead(single_pulse_trig_pin)) { + has_single_pulsed = false; + deb_timer = millis(); + } + } - // The period of time each sample in the array should take in microseconds - // The 1000 converts from milliseconds to microseconds, and the 600 deivides by the number of samples in the array - // The -3 offset compensates for a 3 millisecond overhead created by the time it takes to do all of the calculations - unsigned int sample_period = (new_period-3)*1000/600; - - #ifdef enable_serial_debug - Serial.print("Ampltidue: "); - Serial.println(map(new_amp, 0, 127, 0, 4095)); - Serial.print("Period: "); - Serial.println(new_period); - Serial.print("Waveform #: "); - Serial.println(new_waveform); - delay(500); - #endif - - // Cycle through the waveform samples over a given period of time - for(int i = 0; i < 600; i++){ - while(micros()-timer < sample_period); - analogWrite(waveform_pin, waveforms[new_waveform][i]); - timer = micros(); } + else{ + generate_waveform(1); + // Slows down the output pulse if the slow pulse pin is pulled LOW + if(!digitalRead(slow_pulse_flag_pin)) delay(500); + } + } \ No newline at end of file