Arduino Realtime Processing with Switch and LED

Hi- I have been doing a bunch of experiments with the Arduino Realtime Audio Processing library and I was wondering if someone could tell me if this is possible:

I want to use 4 of the different effects on the same Arduino.

I have it set up so that the output uses digital pins 0-7 to send to a R2R resistor ladder, and it sounds great.

I have also added a 7-segment LED display using digital pins 8-13 and Analog 2 as outputs to show the number of the effect (1-4). To conserve analog pins, I have hooked the rotary switch up to different resistors and powered it with 5V. I connected this switch to Analog 5, and it was very easy to teach the Arduino the input of each setting on the switch.

The problem I am having now is the code.

The real question is, is it possible to run other functions on the same chip while using this code? I know that the registry is manually toggled for this program, and I am wondering if that is making it impossible to do what I want to do.

The source code is here: http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1224777046

Thanks in advance for your wisdom!

The real question is, is it possible to run other functions on the same chip while using this code? I know that the registry is manually toggled for this program, and I am wondering if that is making it impossible to do what I want to do.

Without knowing what else it is you want to do, it would be hard to give definitive answers. You don't have any digital pins left, and can't do serial communications, so that limits, to a degree, what else you can do.

If you are already doing real-time audio processing, I doubt that you have all that much memory or process capability left, either.

But, if all you wanted to do was read a potentiometer to control volume, that should be possible.

To clarify: the program code for the Reverb effect is only 2600 bytes.

I was hoping to put Reverb, Loopback, Phasor, and maybe Pitch Shifter on the same Arduino chip, with the option to switch between them.

Never mind the LED display for now.

It's not so much the function code that is the problem but :- 1) The amount of RAM you need to have for each function. 2) The amount of free time you have for each process. I suspect you will be pushing things to get them all going at once. By sharing buffers you could get one switched in at any time without any problems.

GM! Thanks for weighing in. I hear you saying RAM- stupid question- that is NOT the binary sketch size after compiling, right?

The other thing is, originally I was trying to toggle pins 8-13 and A02 by using pinMode and digitalWrite, however I have realized that I need to do this by assigning values in the Port Registers.

Working only with one effect, I am now able to get the display to show a "one" while the guitar is playing through, but I still can't get the switch to be active. I will work more on PORT C to figure out what the problem is.

Is there a resource for me to learn more about Assembly Language? I don't know if you have checked out the code for this project, but it is far removed from content covered in most Arduino tutorials.

Thanks man!

There are 3 kinds of memory on the Arduino - SRAM, Flash, and EEPROM.

Compiler code goes in Flash. Global variables, stack space (for function calls), etc. goes in SRAM, and user data goes in EEPROM.

So, while your code size is small, you may still run out of SRAM, which is limited to 2K on the Duemilanove.

You can try combining the sketches, with code to switch between the functions. If it works, great. If not, you'll need to determine if you have run out of SRAM, which is not all that easy to do, since the amount of SRAM used is dynamic.

that is NOT the binary sketch size after compiling, right?

Yes that's right, the binary sketch size is the amount of "flash" memory and that is 32K on a 328 processor. However the RAM is only 2K and that has to cope with the buffering, variables and stack.

however I have realized that I need to do this by assigning values in the Port Registers.

You should be able to use the digitalWrite as you shouldn't be changing them all that fast. You do not get much of a speed up by going to assembler as compilers are quite good now. One speed saving tip is don't use ints where bytes will do, that halves the amount of processing required.

Understood. You are saying that I need to identify which FUNCTIONS are different between the different effects programs, and toggle ONLY those functions, while keeping the rest of the program the same. Does having my fancy rotary switch connected to Analog Pin 5 eat up some of that 2K? Is there a less memory-intensive way to read that switch? And is an "if" construct the right way to identify switch settings?

I am immersed in the data sheet, and I have to admit that I find the registry stuff much more exciting than the regular Arduino code.

Thanks for the encouragement guys!

I need to identify which FUNCTIONS are different

Not quite I was saying you need to identify the storage used and keep that common thought all the effects.

Does having my fancy rotary switch connected to Analog Pin 5 eat up some of that 2K?

No not at all.

And is an "if" construct the right way to identify switch settings?

Yes it's fine.

Ok, now I have the numbers 1-6 showing up, but no love on the guitar input. I am thinking that because analog 0 and 1 are allocated to serious input tasks, a simple analog read at A05 turns them off (or something). I don't really know.

Is there another call to read Analog 5 besides naming the pin something like 'numberPin' and doing an analog read to it?

Right now I would just like to get the switch AND the music going at the same time, never mind about multiple effects yet.

THANKS

If you are trying to perform an analogRead on A5, that WILL fail. A5 is the name of the 5th analog pin, WHEN USED AS A DIGITAL PIN. Not, in my opinion, one of the Arduino team's best moves.

Post the code you are having problems with.

Heavy stuff man. I will try it with a different pin. I don't know how to post code here in a non-annoying way. Thanks so much for your help

I don't know how to post code here in a non-annoying way.

On the top row, there is a button with a # on it. Select that button. It will add tags to the message area. Paste your code between the tags.

Or, paste the code first, then select it all, then press the # button.

//Arduino Realtime Audio-  Delay Effect-
//R2R digital to analog converter on digital pins 0-7
//LED 7 segment display on digital pins 8-13 and analog 5
//Guitar input from a preamp that delivers 0-5V on analog pin 1
//Potentiometer middle lug to analog 0 with pins to Arduino 5V and ground
//Six position rotary switch that sends DISCRETE voltages to analog pin 2

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit)) //clearing registry bits
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))  //setting registry bits

boolean div32;
boolean div16;
// interrupt variables accessed globally
volatile boolean f_sample;
volatile byte badc0;
volatile byte badc1;
volatile byte ibb;

int cnta;
int icnt;
int cnt2;
int iw1;
int iw;
byte bb; //OUTPUT???
byte dd[1024]; // Audio Memory Array 8-Bit

int numberPin = 2; // analog pin to read the buttons
int numberVal;  //BUTTON VALUE

void setup()
{
 //R2R: Initialize output ports  MAKES PINS 0-7 OUTPUT TO DAC
// PORTD = B11111111;
 for(int i=0; i < 8; i++){
  pinMode(i, OUTPUT);
 }

 fill_sinewave();    // reload wave after 1 second


 // set adc prescaler to 64 for 19kHz sampling frequency
 //DETERMINES DIVISION FACTOR BETWEEN SYSTEM CLOCK FREQUENCY AND
 //INPUT CLOCK OF ADC
 
 cbi(ADCSRA, ADPS2);
 sbi(ADCSRA, ADPS1);
 sbi(ADCSRA, ADPS0);

//ADMUX SELECTS ANALOG INPUT CHANNEL

 sbi(ADMUX,ADLAR); // 8-Bit ADC in ADCH Register PRESENTED LEFT-ADJUSTED
 sbi(ADMUX,REFS0); // VCC Reference
 cbi(ADMUX,REFS1);
 cbi(ADMUX,MUX0);  // Set Input Multiplexer to Channel 0
 cbi(ADMUX,MUX1);
 cbi(ADMUX,MUX2);
 cbi(ADMUX,MUX3);

 // Timer2 Clock Prescaler to : 1
 sbi (TCCR2B, CS20);
 cbi (TCCR2B, CS21);
 cbi (TCCR2B, CS22);

 //cli(); // disable interrupts to avoid distortion

 //TIMER/COUNTER INTERRUPT MASK REGISTER
 cbi (TIMSK0,TOIE0); // disable Timer0 !!! delay is off now  OVERFLOW INTERRUPT ENABLE
 sbi (TIMSK2,TOIE2); // enable Timer2 Interrupt

 iw1=badc1; //NO IDEA
 
  DDRB=B00111111;//SETS DIGITAL LED PINS AS OUTPUTS
  DDRC=B00100000;//SETS ANALOG 5 AS OUTPUT
}

void loop()
{
 while (!f_sample) {  // wait for Sample Value from ADC  WHAT DOES THIS DO?
 }  // Cycle 15625 KHz = 64uSec
 
 //hi!!!!!  I ADDED THE COUNTING/ROTARY KNOB FUNCTION HERE, JUST TO TRY TO GET THE TWO
 //PROGRAMS RUNNING AT THE SAME TIME- NO DICE
 //OF COURSE, THE NEXT STEP IS TO PUT A SECOND OR THIRD (6?)EFFECT IN TIED TO THE SWITCH
 //THANKS FOR LOOKING!!!
 
{ numberVal = analogRead(numberPin);
      
    if(numberVal == 465)//number one
    {
    PORTB=B00010000;
    PORTC=B00100000;
   }
   if(numberVal == 204)//number two
    {
    PORTB=B00111011;
    PORTC=B00000000;
  }
  if(numberVal == 129)//number three
    {
    PORTB=B00101111;
    PORTC=B00000000;
  }
}
 f_sample=false;  //VALUE OF BOOLEAN "f_sample"
 
 bb=dd[icnt] ; // read the delay buffer
 iw = 127-bb ; // substract offset
 iw = iw * badc0 / 255;  // scale delayed sample with potentiometer
 iw1 = 127 - badc1; // substract offset from new sample
 iw1=iw1+iw;  // add delayed sample and new sample

 if (iw1 < -127) iw1=-127; // Audio limiter

 if (iw1 > 127) iw1=127;  // Audio limiter

 bb= 127+iw1; // add offset
 dd[icnt]=bb; // store sample in audio buffer
 icnt++;
 icnt = icnt & 1023;  // limit bufferindex 0..511

 PORTD=bb;  //Sends the output to the R2R digital to analog converter on digital pins 0-7

} // loop
//******************************************************************

void fill_sinewave(){
 float pi = 3.141592;
 float dx ;
 float fd ;
 float fcnt;
 dx=2 * pi / 512; // fill the 512 byte bufferarry
 for (iw = 0; iw <= 511; iw++){ // with 50 periods sinewawe
 fd= 127*sin(fcnt); // fundamental tone
 fcnt=fcnt+dx;  // in the range of 0 to 2xpi  and 1/512 increments
 bb=127+fd; // add dc offset to sinewawe
 dd[iw]=bb; // write value into array

 }
}

//******************************************************************
// Timer2 Interrupt Service at 62.5 KHz
// here the audio and pot signal is sampled in a rate of: 16Mhz / 256 / 2 / 2 = 15625 Hz
// runtime : xxxx microseconds

//TIMER/COUNTER 2 OVERFLOW INTERRUPT

ISR(TIMER2_OVF_vect) {

  div32=!div32; // divide timer2 frequency / 2 to 31.25kHz
 if (div32){
 div16=!div16; //
 if (div16) {  // sample channel 0 and 1 alternately so each channel is sampled with 15.6kHz
 badc0=ADCH; // get ADC channel 0
 sbi(ADMUX,MUX0);  // set multiplexer to channel 1
 }
else
 {
badc1=ADCH; // get ADC channel 1
cbi(ADMUX,MUX0);  // set multiplexer to channel 0
f_sample=true;
}
ibb++;
ibb--;
ibb++;
ibb--; // short delay before start conversion
sbi(ADCSRA,ADSC); // start next conversion
}

}

Thanks so much for being willing to look at this!
The question for right now is, can we get the LED display and switch working together while the guitar program is running?

The symptom is that the switch with LED works, but no sound is coming out.
Thanks again

And to clarify, A5 was my shorthand for the 5th analog pin. Lesson learned about being careful with terminology here- thanks!

But, since you mentioned it, I put the rotary switch on analog 2 and made analog 5 connect to the 7 segment LED.

Thanks again

I am pretty sure that I am putting the function for the switch and the numbers in the wrong place. Does anybody know where I should put it?

The code is in the right place. I’m still trying to figure out what it does, though.

The value read from the resistor ladder may not be exactly the same every time. You should have a range test, not an equality test.

if(numberVal > 460 && numberVal < 470)

What is the direct port manipulation stuff doing?

To clarify, the code that I added is not from/for a resistor ladder. It's a 6-position rotary switch. Each position on the switch is connected to 5V, and to a resistor, so that each switch position inputs different voltage to the analog pin, which is number 2 now.

I toggled the port registers directly A) because I just learned how to do this and it makes me feel like superman, and B) this is how the pins are set in the rest of the program and I was worried about something conflicting.

I am really new to arduino and to coding, and I am POSITIVE I am doing this wrong.

But, to rehash, the purpose of this experiment is to get the switch to light an LED display of 7 segments with different numbers 1-6.

Eventually, I would like to tie each switch position to both an LED number AND a guitar effect in the software.

Thanks man Pete

I keep getting weird errors having to do with the fill sinewave part when I try to tie in other effects.

Good Morning-

I am trying to decode Mike's advice about common buffers.

Can anyone tell me if there is something unique about the names of the variables in this program, or if they are simply chosen by the writer of the original code?

I believe that the part of the code that engages the buffering is the fill_sinewave part. Is this semi-correct?

Thanks for your help!