Jim's
Tutorials

Spring 2016
course
navigation

Learning How To Interrupt Anything & Everything

So I decided to go back to the Uno after readying about interrupts. The Atmel ARM chips are great when needing to do things within the Arduino IDE, but the minute you need to get under it, everything begins to suck.
I read these tutorials for some insight into using interrupts with the Uno:
In a first pass I was able to match a high D on the 66 key piano (about 1179hz). Not great, but a start (this being a fully timer based process).
Here is the code: /* Synth.ino ---------------------------------------------------------- Description: A sketch to generate sound waves for audio processing with an arduino uno. State: Sound is being produced, but not in a wide range of frequencies. Further optimization is needed. ----------------------------------- References: http://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/ http://forum.arduino.cc/index.php?topic=45562.0 https://arduino-info.wikispaces.com/Timers-Arduino http://www.instructables.com/id/Arduino-Waveform-Generator/?ALLSTEPS http://www.instructables.com/id/Arduino-Timer-Interrupts/ ---------------------------------------------------------- Contact: ldavis@marlboro.edu https://github.com/SafeCamp https://safecamp.github.io/ Logan Davis | 4/22/16 | Arduino 1.6.7 * * * */ #include <avr/pgmspace.h> #include <avr/interrupt.h> //-----WAVE FORM NAMES-----// #define TRIANGLE 0 #define SAW 1 #define SQUARE 2 #define WHITENOISE 3 #define SINE 4 //-----PIN NAMES------// #define WAVESELECT A0 #define FREQ A1 #define AUDIO_PORT 9 /*------------------------WAVE FORMS------------------------------------*/ const PROGMEM byte saw_wave[256] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 255}; const PROGMEM byte square_wave[256] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const PROGMEM byte triangle[256] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 254, 255, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, 128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 40, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 254, 255, 248, 244, 240, 236, 232, 228, 224, 220, 216, 212, 208, 204, 200, 196, 192, 188, 184, 180, 176, 172, 168, 164, 160, 156, 152, 148, 144, 140, 136, 132, 128, 124, 120, 116, 112, 108, 104, 100, 96, 92, 88, 84, 80, 76, 72, 68, 64, 60, 56, 52, 48, 44, 40, 36, 32, 28, 24, 20, 16, 12, 8, 4}; const PROGMEM byte white_noise[256] = {104, 33, 220, 229, 128, 215, 44, 104, 212, 96, 63, 131, 36, 76, 27, 134, 138, 188, 67, 105, 149, 131, 116, 234, 175, 165, 198, 33, 2, 33, 240, 234, 16, 228, 135, 144, 80, 31, 240, 84, 190, 208, 101, 126, 137, 234, 155, 8, 0, 222, 55, 228, 219, 164, 3, 144, 233, 207, 13, 161, 198, 195, 241, 249, 219, 223, 33, 36, 223, 70, 119, 232, 32, 20, 219, 230, 16, 215, 63, 21, 163, 127, 54, 146, 133, 39, 237, 166, 78, 38, 199, 162, 167, 245, 207, 101, 195, 111, 21, 211, 224, 98, 11, 129, 254, 199, 29, 243, 144, 13, 253, 52, 223, 222, 10, 209, 251, 3, 146, 38, 41, 86, 39, 229, 88, 82, 5, 246, 156, 103, 21, 181, 67, 243, 193, 108, 85, 119, 176, 125, 114, 122, 116, 43, 104, 238, 136, 109, 139, 73, 120, 93, 35, 29, 97, 56, 141, 33, 123, 141, 56, 87, 167, 185, 195, 147, 40, 147, 135, 5, 124, 178, 150, 59, 163, 172, 223, 249, 95, 227, 57, 209, 156, 116, 219, 98, 226, 218, 100, 14, 246, 80, 140, 206, 43, 180, 45, 45, 34, 76, 61, 170, 216, 200, 97, 135, 150, 247, 82, 184, 50, 180, 199, 122, 23, 44, 74, 104, 14, 229, 213, 203, 1, 91, 220, 242, 171, 114, 60, 42, 2, 71, 161, 174, 153, 147, 67, 127, 189, 94, 83, 85, 62, 95, 22, 42, 153, 100, 180, 139, 165, 7, 136, 71, 74, 114}; const PROGMEM byte sine_wave[256] = {128, 131, 134, 137, 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 176, 179, 182, 185, 187, 190, 193, 195, 198, 201, 203, 206, 208, 210, 213, 215, 217, 219, 222, 224, 226, 228, 230, 231, 233, 235, 236, 238, 240, 241, 242, 244, 245, 246, 247, 248, 249, 250, 251, 251, 252, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 253, 253, 252, 251, 251, 250, 249, 248, 247, 246, 245, 244, 242, 241, 240, 238, 236, 235, 233, 231, 230, 228, 226, 224, 222, 219, 217, 215, 213, 210, 208, 206, 203, 201, 198, 195, 193, 190, 187, 185, 182, 179, 176, 173, 170, 167, 164, 161, 158, 155, 152, 149, 146, 143, 140, 137, 134, 131, 128, 124, 121, 118, 115, 112, 109, 106, 103, 100, 97, 94, 91, 88, 85, 82, 79, 76, 73, 70, 68, 65, 62, 60, 57, 54, 52, 49, 47, 45, 42, 40, 38, 36, 33, 31, 29, 27, 25, 24, 22, 20, 19, 17, 15, 14, 13, 11, 10, 9, 8, 7, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 17, 19, 20, 22, 24, 25, 27, 29, 31, 33, 36, 38, 40, 42, 45, 47, 49, 52, 54, 57, 60, 62, 65, 68, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, 106, 109, 112, 115, 118, 121, 124}; byte current_wave_form[256] = {0}; volatile byte i = 0; //set to volatile due to being mutated by an interrupt void setup(){ /* Set PWM pin to OUTPUT */ choose_wave(SINE); DDRD = 0xFF; //SET 0-7 as OUTPUT cli(); TCCR1A = 0;// clear some regs that could have been set by Arduino IDE TCCR1B = 0; OCR1A = 0; // Set frequency of interrupt TCCR1B |= (1 << WGM12); // Set CTC mode TCCR1B |= (1 << CS10); // Prescale = 1 TIMSK1 |= (1 << OCIE1A); //link interrupt sei();//enable interrupts } void loop() {} ISR(TIMER1_COMPA_vect){//timer 1 interrupt PORTD = current_wave_form[i++]; //direct write out to ports 0-7 } void choose_wave(byte choice){ /* Check to see what wave the user is choosing * then call swap_wave() on it. */ switch(choice){ case TRIANGLE: swap_waves(triangle); break; case SAW: swap_waves(saw_wave); break; case SQUARE: swap_waves(square_wave); break; case WHITENOISE: swap_waves(white_noise); break; case SINE: swap_waves(sine_wave); break; } } void swap_waves(const byte stored_wave[]){ /* Read a given waveform from programmable * memory into a global array stored in ram */ int i= 0; for(i = 0;i < 256;i++){ current_wave_form[i] = pgm_read_word_near(&stored_wave[i]); } }
http://cs.marlboro.edu/ courses/ spring2016/jims_tutorials/ ldavis/ April_22nd
last modified Friday April 22 2016 12:38 am EDT