First draft of the waveform generator.

This commit is contained in:
Cynopolis
2021-10-10 13:17:34 -05:00
parent 01d85538bb
commit 731c5abbbc
2 changed files with 82 additions and 36 deletions

Binary file not shown.

View File

@@ -12,14 +12,16 @@
* D25 - Period Encoder Input * D25 - Period Encoder Input
* D26 - Waveform Select Encoder * D26 - Waveform Select Encoder
* D27 - Waveform Select Encoder * D27 - Waveform Select Encoder
* D28 - Single pulse flag (LOW enables single pulse mode)
* D29 - Single pulse trigger. (LOW will cause the arduino to send 1 waveform pulse)
* D30 - Slow pulse flag (LOW enables a pulse rate of 3 pulses/second)
*/ */
#include <Arduino.h> #include <Arduino.h>
#include <Encoder.h> #include <Encoder.h>
#include <Wire.h> #include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include <LiquidTWI2.h>
//uncomment to enable serial output for debugging //uncomment to enable serial output for debugging
#define enable_serial_debug #define enable_serial_debug
@@ -27,8 +29,11 @@
#define waveform_pin DAC0 #define waveform_pin DAC0
#define amplitude_pin DAC1 #define amplitude_pin DAC1
#define sync_pin 2 #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 #define waveform_num 4
// Array of waveform arrays. Currently holds four waveforms with 600 samples each. // Array of waveform arrays. Currently holds four waveforms with 600 samples each.
int waveforms[waveform_num][600] = { int waveforms[waveform_num][600] = {
@@ -54,35 +59,64 @@ long new_waveform = 2;
long old_waveform = 2; long old_waveform = 2;
int waveform_select = 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; 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() { void setup() {
//The sync pin can be run into an oscilliscope's trig channel to easiy find the waveform //The sync pin can be run into an oscilliscope's trig channel to easiy find the waveform
pinMode(sync_pin, OUTPUT); 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) //Change the resolution of the analog ourput to its maximum (12 bit res)
analogWriteResolution(12); analogWriteResolution(12);
//If serial debugging is enabled set up serial
#ifdef enable_serial_debug
Serial.begin(115200);
#endif
// Initialize timers and encoders // Initialize timers and encoders
timer = micros();
amp_encoder.write(new_amp*4); amp_encoder.write(new_amp*4);
period_encoder.write(new_period*4); period_encoder.write(new_period*4);
waveform_encoder.write(new_waveform*4); waveform_encoder.write(new_waveform*4);
lcd.init(); // initialize the lcd // Only executes this block of code if serial debug is enabled
lcd.backlight(); #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() { void loop() {
lcd.setCursor(0,0);
lcd.print("Hello");
// Read in encoder values // Read in encoder values
new_amp = amp_encoder.read()/4; new_amp = amp_encoder.read()/4;
new_period = period_encoder.read()/4; new_period = period_encoder.read()/4;
@@ -102,6 +136,10 @@ void loop() {
amp_encoder.write(new_amp*4); amp_encoder.write(new_amp*4);
} }
old_amp = new_amp; old_amp = new_amp;
#ifdef enable_serial_debug
Serial.print("Ampltidue: ");
Serial.println(map(new_amp, 0, 127, 0, 4095));
#endif
} }
//Handles period encoder //Handles period encoder
@@ -117,6 +155,10 @@ void loop() {
period_encoder.write(new_period*4); period_encoder.write(new_period*4);
} }
old_period = new_period; old_period = new_period;
#ifdef enable_serial_debug
Serial.print("Period: ");
Serial.println(new_period);
#endif
} }
//Handles waveform encoder //Handles waveform encoder
@@ -131,6 +173,10 @@ void loop() {
waveform_encoder.write(new_waveform*4); waveform_encoder.write(new_waveform*4);
} }
old_waveform = new_waveform; 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 // 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 // Output a signal to control the amplitude
analogWrite(amplitude_pin, map(new_amp, 0, 127, 0, 4095)); 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);
}
} }