Interrupts

I have been reading on interrupts to generate different frequency sine waves from arduino. But the problem i am facing is that i want to generate sound for a few seconds and then stop and the sound generation should be inside a loop.

so basically i want the arduino to control servos and go to a certain position, generate a 4KHz sound, record sound and repeat the whole process for a new servo position.

This seems like a dumb question but do i even have to use interrupts to perform sound generation or alternative code can be used given that i want to generate frequencies between 4KHz and 12KHz.

EDIT: Since i would be using delay() in the loop for other funtions, how can i prevent the interrupt timer settings messing with the delay function.

EDIT: Since i would be using delay() in the loop for other funtions, how can i prevent the interrupt timer settings messing with the delay function.

The simplest way is to put that crutch away. Do not use delay() for any purpose. It is not needed. The blink without delay example shows how to get along without it.

so basically i want the arduino to control servos and go to a certain position

Piece of cake.

generate a 4KHz sound

What kind of sound? Why not use the tone() function?

record sound

The same one you just generated? Why? Can't you remember what you did?

The Arduino make a lousy audio processor. How are you going to measure the sound you want to record? How often? For how long? Record the data where?

This seems like a dumb question but do i even have to use interrupts to perform sound generation

You, or some other function, yes.

basically i want to generate sound wave, point it towards the wall and get the wave reflection record it via a microphone (biased and amplified) and save these readings in arduino or display them on the serial monitor and save it as a log file or something. Also getting the servo position into record would be great.

since i have to do sound analysis, i asked around and was suggested to use sine waves since using tone() would generate square wave which is not suitable for my purposes.

if it helps here is the link to my earlier post URGENT: Project Sound Camera (Need Guidance) - Project Guidance - Arduino Forum

So the project wasn't really "URGENT" after all ...

Have you already got working code that generates the sine wave that you want? Let's imagine it is in a function called makeSound()

Now all you need is code in loop() like this

void loop() {
   moveServo();
   makeSound();
   recordSound();
}

Or maybe like this

void loop() {
   moveServo();
   startRecord();
   makeSound();
   stopRecord();
}

...R

Robin2:
So the project wasn't really "URGENT" after all ...

Have you already got working code that generates the sine wave that you want? Let's imagine it is in a function called makeSound()

Now all you need is code in loop() like this

void loop() {

moveServo();
   makeSound();
   recordSound();
}




Or maybe like this



void loop() {
   moveServo();
   startRecord();
   makeSound();
   stopRecord();
}




...R

the first thread i made was a few months ago and updated it last week to say URGENT....the problem with your suggestion is that the servos move a pan and tilt mount and i require one reading per angle.

AbdulW87:
the problem with your suggestion is that the servos move a pan and tilt mount and i require one reading per angle.

I don't understand ( a) what you mean about 1 reading per angle or ( b) how my code excludes anything you want.

My code was only intended as a very generalized suggestion.

...R

Robin2:

AbdulW87:
the problem with your suggestion is that the servos move a pan and tilt mount and i require one reading per angle.

I don't understand ( a) what you mean about 1 reading per angle or ( b) how my code excludes anything you want.

My code was only intended as a very generalized suggestion.

...R

sorry i should have been clear and maybe i didnt get what you were trying to say.

By 1 reading per angle i mean, the pan and tilt mount will move in a similar fashion as scan lines in a TV go, from left to right (or right to left) from the top to the bottom of the screen. Now break the horizontal line into say 9 angles of 10 degree each, so for the first line i get 9 reading then move to next line vertically and repeat the process. around 5 lines vertically that makes a total of 45 readings. I think it would be appropriate to say like a grid.

with the tone() command i was able to produce a sound frequency for all the 45 combination of angles but was limited to low frequencies. The mic responds better ot frequencies between the range of 4kHz and 12kHz, which i am not sure can be produced by the tone function in a sinusoidal waveform thus the decision to choose interrupts.

Which brings me to my recent problem, i copied a piece of code and ran it on arduino. the code was supposed to produce sample rate of 40kHz but the oscilloscope read 400Hz (100 times less), i tried tinkering with the prescalar, and the timer modes but nothing works. the code was taken from this instructable http://www.instructables.com/id/Arduino-Audio-Output/?ALLSTEPS

//Sine out w/ 40kHz sampling rate
//by Amanda Ghassaei
//http://www.instructables.com/id/Arduino-Audio-Output/
//Sept 2012

/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
*/

byte sine[] = {127, 134, 142, 150, 158, 166, 173, 181, 188, 195, 201, 207, 213, 219, 224, 229, 234, 238, 241, 245, 247, 250, 251, 252, 253, 254, 253, 252, 251, 250, 247, 245, 241, 238, 234, 229, 224, 219, 213, 207, 201, 195, 188, 181, 173, 166, 158, 150, 142, 134, 127, 119, 111, 103, 95, 87, 80, 72, 65, 58, 52, 46, 40, 34, 29, 24, 19, 15, 12, 8, 6, 3, 2, 1, 0, 0, 0, 1, 2, 3, 6, 8, 12, 15, 19, 24, 29, 34, 40, 46, 52, 58, 65, 72, 80, 87, 95, 103, 111, 119,};
int t = 0;//time

void setup(){
  //set digital pins 0-7 as outputs
  for (int i=0;i<8;i++){
    pinMode(i,OUTPUT);
  }
  
  cli();//disable interrupts
  //set timer0 interrupt at 40kHz
  TCCR0A = 0;// set entire TCCR0A register to 0
  TCCR0B = 0;// same for TCCR0B
  TCNT0  = 0;//initialize counter value to 0
  // set compare match register for 40khz increments
  OCR0A = 49;// = (16*10^6) / (40000*8) - 1 (must be <256)
  // turn on CTC mode
  TCCR0A |= (1 << WGM01);
  // Set CS11 bit for 8 prescaler
  TCCR0B |= (1 << CS11); 
  // enable timer compare interrupt
  TIMSK0 |= (1 << OCIE0A);
  sei();//enable interrupts
  
}


ISR(TIMER0_COMPA_vect){ //40kHz interrupt routine
  PORTD = sine[t];//send sine wave to DAC, centered around (127/255)*5 = 2.5V
  t++;//increment t
  if (t > 99){//reset t to zero
    t = 0;
  }
}

void loop(){
  //do other stuff here
}

That seems to be a problem for what goes inside the mythical makeSound() function in my pseudo code. I'm afraid I know little or nothing about making sine waves.

I think the general approach that I suggested remains relevant.

...R

Robin2:
That seems to be a problem for what goes inside the mythical makeSound() function in my pseudo code. I'm afraid I know little or nothing about making sine waves.

I think the general approach that I suggested remains relevant.

...R

another problem i am having is i tried 1-Bit DAC but it works on pin 9 (or i think can work on pin 10) since both these pins are controlled by timer1 where the conflict arises as the servo library also uses these pins to control the servos. so i can either use the servos or generate sound not both.

Configuring timer2 for high freq PWM? Drive it from a sinetable on timer2 interrupt
using DDS?

But where are you going to record the incoming waveform, there's precious little RAM.