Controlling Arduino with audio tones from a headphone jack.

Heya guys! Who here is going to Bay Area Maker Faire? Great. Anyway, I've decided to build a simple robot controlled by an iPhone. I was thinking the easiest way to achieve this is to simply listen for tones from a headphone jack wired to the Arduino. Currently, I have some basic VU code listening for a high tone, but I'm concerned that my code won't be fast enough and that I won't be able to trigger one and not the other. I came here hoping someone would affirm my beliefs of it working (feasibility). I cannot find anything like this, anywhere else.

That might be possible if there was any code to look at.

Also how are you coupling the audio into the arduino? Audio signals are symmetrical about ground but you must not let a negative signal get into an arduino, so you have to AC couple and bias it.

This approach involves a lot of processing power, if I were doing it I would use a tone decoder like the HT9170.

or maybe some older 300 baud FSK modem chips/modules?

Grumpy_Mike:
Also how are you coupling the audio into the arduino? Audio signals are symmetrical about ground but you must not let a negative signal get into an arduino, so you have to AC couple and bias it.

This approach involves a lot of processing power, if I were doing it I would use a tone decoder like the HT9170.

Can you guys wait about thirty minutes for me to post the code? Also, I'm already over budget on this, so I'd prefer not to order anything, and even if I did, I'd need it this week.

By the sound of it your behind schedule too. Are you just starting it now ? Isn't that cutting it kinda close ?

raschemmel:
By the sound of it your behind schedule too. Are you just starting it now ? Isn't that cutting it kinda close ?

Yep, but I can build extremely fast. The wiring is 95% done I'm just waiting for the parts, which should be in ~3 days or so.

Here is the current code:
I'm still gathering app. thresholds.

/*
microphone sketch

SparkFun breakout board for Electret Microphone is connected to analog pin 0
*/

const int ledPin = 13;    
const int ledPin2 = 8;     //the code will flash the LED in pin 13
const int middleValue = 262129
;      //the middle of the range of analog values
const int numberOfSamples = 128;  //how many readings will be taken each time

int sample;                       //the value read from microphone each time
long signal;                      //the reading once you have removed DC offset
long averageReading;              //the average of that loop of readings

long runningAverage=0;          //the running average of calculated values
const int averagedOver= 16;     //how quickly new values affect running average
                                //bigger numbers mean slower

const int threshold=225;

const int threshold2=425;
;        //at what level the light turns on

void setup() {
  pinMode(ledPin, OUTPUT);
    pinMode(ledPin2, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  long sumOfSquares = 0;
  for (int i=0; i<numberOfSamples; i++) { //take many readings and average them
    sample = analogRead(0);               //take a reading
    signal = (sample - middleValue);      //work out its offset from the center
    signal *= signal;                     //square it to make all values positive
    sumOfSquares += signal;               //add to the total
  }
  averageReading = sumOfSquares/numberOfSamples;     //calculate running average
  runningAverage=(((averagedOver-1)*runningAverage)+averageReading)/averagedOver;

  if (runningAverage>threshold & runningAverage<threshold2){         //is average more than the threshold ?
    digitalWrite(ledPin, HIGH);          //if it is turn on the LED
  }else{
    digitalWrite(ledPin, LOW);           //if it isn't turn the LED off
  }
  
    if (runningAverage>threshold2 & runningAverage<threshold){         //is average more than the threshold ?
    digitalWrite(ledPin2, HIGH);          //if it is turn on the LED
  }else{
    digitalWrite(ledPin2, LOW);           //if it isn't turn the LED off
  }
  Serial.println(runningAverage);        //print the value so you can check it
}

How are coupling the audio to the arduino ? (your post didn't mention any experience with electronics)

raschemmel:
How are coupling the audio to the arduino ? (your post didn't mention any experience with electronics)

Oops! Well, I have a 3 prong jack with GND to, well, GND, L to A0 and R isn't being used. Is that what you needed?

Honestly, It is not looking good for this project. I can't create a stark enough difference.

128keaton:

raschemmel:
How are coupling the audio to the arduino ? (your post didn't mention any experience with electronics)

Oops! Well, I have a 3 prong jack with GND to, well, GND, L to A0 and R isn't being used. Is that what you needed?

Honestly, It is not looking good for this project. I can't create a stark enough difference.

Well a audio signal is a AC voltage and you are not allowed to apply the negative portion of the signal without risking pin damage. You will need some external circuitry to 'bias' the audio signal so it is confined to the 0 to +5 vdc that the ADC can process.

You're scaring me. You state that you build very quickly but you don't know that any AC audio signal must be coupled to the arduino with a 1uF capacitor in series and voltage divider consisting of a 10k pullup resistor connected to a 10k pull down resistor (to GND) to bias the signal in the center of the range of the analog input. The signal cannot be connected directly without the cap
and voltage divider.

Honestly, It is not looking good for this project. I can't create a stark enough difference.

Of course not. If you did not provide the circuit described in my last post it would not work. Also , if the tones are standard computer audio level they are 1V pk to pk and may not be high enough. You may need an amplifier.

raschemmel:

Honestly, It is not looking good for this project. I can't create a stark enough difference.

Of course not. If you did not provide the circuit described in my last post it would not work. Also , if the tones are standard computer audio level they are 1V pk to pk and may not be high enough. You may need an amplifier.

Okay. I am gonna throw this out there. At this point, I have no idea how to do this. I've built something like this, but that was years ago (years). Raschemmel, In the past i have used a 220 uF Cap with something like this, would this work again? I have a part of the old circuit with a 220uf, 22k and a 10k resistor, but using that on this circuit has a slow discharge

I was thinking the easiest way to achieve this is to simply listen for tones from a headphone jack wired to the Arduino.

That code will do nothing with the frequency of the tone it will just detect different amplitudes if the numbers were correct which they are not.
Both thresholds are below the mid point of 512.
Is this amplitude modulation what you intend? How are you providing this from the phone?

220uF is awfully large for this application. If you live in the USA go to RadioShack and buy the 1uF cap. And buy two resistors of the same value. You cannot use two different resistor values. The whole point is to bias the circuit in the middle of the range, which can only be done using two equal resistors.

Mike's right. It's not realistic to think you can do FFT on the fly and generate discrete digital output but who knows, maybe someone knows how to do that . I don't.

raschemmel:
220uF is awfully large for this application. If you live in the USA go to RadioShack and buy the 1uF cap. And buy two resistors of the same value. You cannot use two different resistor values. The whole point is to bias the circuit in the middle of the range, which can only be done using two equal resistors.

Figured, I have a 1uf ceramic in my mintronics, but I do not know what code equals what. I think it is a 102. Now that I have a 1uf and multiple 10ks, how should the circuit go? 10k-1uf-10k?

raschemmel:
Mike's right. It's not realistic to think you can do FFT on the fly and generate discrete digital output but who knows, maybe someone knows how to do that . I don't.

Okay. I think I am close, it sorta works.

What good is it going to do if you can detect it if you can't identify the frequency ?
Take a look at this:
http://wiki.openmusiclabs.com/wiki/ArduinoFFT

Now that I have a 1uf and multiple 10ks, how should the circuit go? 10k-1uf-10k?

No.
Look at the front end of this circuit:-
http://interface.khm.de/index.php/labor/experimente/arduino-realtime-audio-processing/