Jim's
Tutorials

Spring 2016
course
navigation

Bass range!

I mostly read this week. After the progress of actually getting noise out of an arduino last week, I tried to make it faster.
I read an article about using a trick with the OCRxA registers to produce ultra sonic noise on an arduino. I also found out this is the same trick used in the advances synthesis tutorial that I have read before. To problem with it is that the frequency is defined is an 8-bit register, which only allows me to operate within a 256 HZ range. OCRxA also has hard dependencies on very low level settings in the Atmel timers, which makes them very finicky (or more honestly, I am not that good at manipulating the AVR timers yet). I read a longer tutorial about goofing around with arduino PWM . This actually provided some really good explanations of PWM timers and register settings. The problem with all of these tutorials is that the frequency is fixed in all of them and their scripts are doing a lot less then mine. I am going to try and find some more relevant sources and schematics. A lot of the tutorials also told me to just read the Atmel spec sheet for the 328p (the uno's CPU). I found it and it is 660 pages long. I will try to dig into some one it over the next week.
I did get around to altering some code. I fiddled with some the PWM registers given my knew found knowledge and it did actually felt speed up the loop! I am actually in a singable range now. I also stopped polling the audio output using a call to micro(). The removal of two 64-bit numbers on an 8-bit processor helped a fair amount. The dealyMicroseconds() also provides a smoother transitions between pitches then the polling method.
I recorded the sounds the board is now making for documentation.
Here is the new code: /* Synth.ino ---------------------------------------------------------- Description: A sketch to generate sound waves for audio processing with an arduino uno. State: "in early developement" (AKA not functioning yet). Something is slowing down the cycles to the point where it just sounds like a speaker-pop. All the coret values are beings processed, just not quickly enough. ---------------------------------------------------------- References: http://makezine.com/projects/make-35/advanced-arduino-sound-synthesis/ https://www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM ---------------------------------------------------------- Contact: ldavis@marlboro.edu https://github.com/SafeCamp https://safecamp.github.io/ Logan Davis | 1/27/16 | Arduino 1.6.7 * * * */ #include <avr/pgmspace.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 11 /*------------------------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}; byte i = 0; byte old_choice = 0; byte current_choice = 0; unsigned long int time_since_input = 0; unsigned long int current_time_millis = 0; void setup(){ /* Set PWM pin to OUTPUT */ pinMode(AUDIO_PORT, OUTPUT); TCCR2A = _BV(WGM21) | _BV(WGM20); //Enter fast PWM mode TCCR2B = _BV(CS20); // set prescale to 1/1 (every cycle) } void loop() { /*check to see if the user wants a different wave * if the selection is different, change waveforms. * After that check, output waveform value and * increase index. */ current_time_millis = millis(); if (current_time_millis - 100 >= time_since_input){ current_choice = map(analogRead(WAVESELECT),0,1024,0,5); time_since_input = current_time_millis; if(old_choice != current_choice){ old_choice = current_choice; choose_wave(current_choice); } } digitalWrite(AUDIO_PORT, current_wave_form[i]); i++; delayMicroseconds(analogRead(FREQ)); } 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/ February_12th
last modified Monday February 15 2016 11:45 am EST