putting code in loop() on arduino

putting code in loop() on arduino

Postby guest » Thu Aug 16, 2012 8:37 am

here is a quick tutorial if you want to put any code in the loop() part of your arduino code.

IMPORTANT: Download the latest libraries from the wiki if you got them before 8.16.12. there was a mistake in the original header files that would cause problems in the main loop() under some very, very rare conditions. but, its best to not have to wonder, so please redownload them.

first off, all of the examples in the AudioCodec library are written to process the data in the interrupt service routine (ISR). this has the advantage of being faster and lower jitter, but is also a bit more difficult to write. for things that don't have to happen on a strict timing schedule, and are very low processing overhead, they can fit into the main loop() part of the code. what this does, is allows these functions to run in the background, and not interfere with the audio processing that happens in the ISR. as an example of how to do this, here is a piece of code that will allow the pitch of the sine generator to be controlled by a serial connection:

Code: Select all
/*
sine_generator.pde
guest openmusiclabs 7.7.11
this program creates a sinewave of variable frequency and
amplitude, presented at both left and right outputs. there
isnt any interpolation, so you only get 256 discrete frequencies
across the span of 44Hz to 10kHz.
*/

// setup codec parameters
// must be done before #includes
// see readme file in libraries folder for explanations
#define SAMPLE_RATE 44 // 44.1kHz sample rate
#define ADCS 1 // use both ADCs

// include necessary libraries
#include <Wire.h>
#include <SPI.h>
#include <AudioCodec.h>

// create data variables for audio transfer
// even though there is no input needed, the codec requires stereo data
int left_in = 0; // in from codec (LINE_IN)
int right_in = 0;
int left_out = 0; // out to codec (HP_OUT)
int right_out = 0;

// create variables for ADC results
// it only has positive values -> unsigned
unsigned int mod0_value = 0;
unsigned int mod1_value = 0;

// create sinewave lookup table
// PROGMEM stores the values in the program memory
// it is automatically included with AudioCodec.h
PROGMEM  prog_int16_t sinewave[]  = {
  // this file is stored in AudioCodec.h and is a 1024 value
  // sinewave lookup table of signed 16bit integers
  // you can replace it with your own waveform if you like
  #include <sinetable.inc>
};
unsigned int location; // lookup table value location


void setup() {
  // call other setup stuff first
  Serial.begin(9600);
  // call this last if you are setting up other things
  AudioCodec_init(); // setup codec and microcontroller registers
}

void loop() {
  while (1) {
    if (Serial.available() > 0) {
      // read the oldest byte in the serial buffer:
       mod1_value = Serial.read() << 8;
     }
  }
}

// timer1 interrupt routine - all data processed here
ISR(TIMER1_COMPA_vect) { // changed to store registers (NAKED removed)

  // &'s are necessary on data_in variables
  AudioCodec_data(&left_in, &right_in, left_out, right_out);
 
  // create some temporary variables
  // these tend to work faster than using the main data variables
  // as they arent fetched and stored all the time
  int temp1;
  int temp2;
 
  // create a variable frequency and amplitude sinewave
  // fetch a sample from the lookup table
  temp1 = pgm_read_word_near(sinewave + location);
  // step through table at rate determined by mod1
  // use upper byte of mod1 value to set the rate
  // and have an offset of 1 so there is always an increment.
  location += 1 + (mod1_value >> 8);
  // if weve gone over the table boundary -> loop back
  // around to the other side.
  location &= 0x03ff; // fast way of doing rollover for 2^n numbers
                      // otherwise it would look like this:
                      // if (location >= 1024) {
                      // location -= 1024;
                      // }
 
  // set amplitude with mod0
  // multiply our sinewave by the mod0 value
  MultiSU16X16toH16(temp2, temp1, mod0_value);
  // our sinewave is now in temp2
  left_out = temp2; // put sinusoid out on left channel
  right_out = -temp2; // put inverted version out on right chanel

  // get ADC values
  // & is required before adc variables
  AudioCodec_ADC(&mod0_value);

//  reti(); // reti NOT included when NAKED is removed
}


you should be able to open the arduino serial monitor, and send characters to the arduino, and change pitch.

Things to NOTE:

1. NAKED is removed from the ISR setup. [ISR(TIMER1_COMPA_vect)] - this allows all of the data used in the interrupt to get pushed on the stack. its more time consuming, but its imposible to run anything in loop() if you dont do this.

2. reti() is no longer called at the end of the ISR. when you get rid of NAKED, this is automatically done for you.

3. Serial.begin() is called before AudioCodec_init() - this is just precautionary, but AudioCodec_init disables some things inside the arduino that might be used by some functions, and cause them to not initialize properly.

4. delay() and millis() can NOT be used. - AudioCodec_init disables TIMER0 to reduce clock jitter and conflicting interrupts.

5. everything in loop() is nested under the while(1) - this makes it process faster and reduce jitter.
guest
Site Admin
 
Posts: 449
Joined: Thu May 20, 2010 11:58 pm

Return to Audio Codec Shield

Who is online

Users browsing this forum: No registered users and 1 guest


cron