# Limits of my Arduino <-> Smartphone communication

I want to transfer signals from my smartphone to my Arduino Uno by using the audio jack. I have directly connected one channel of the audio to the analog in on the board. The smartphone is sending ~ +-0.5V. This will be interpreted as either 1 or 0 bit signals.

I got the Arduino to read the voltage within ~10 microseconds (100kHz). My problem is that I can't send data with this rate, but I want to speed up the transmission as far as possible.

Below you can see the voltage which is read with 100kHz. On the top right side you can see the bit value. The bits were send with 10kHz. With higher sending frequency the bit "blocks" are not blocklike anymore and blur into each other.

Is this a problem of the smartphone? Can't it produce good signals with this high frequencies?

Or is it a problem of the circuit?

What can I do to get a better signal?

Edit: Here is the Arduino Uno code:

byte data[500];
int i;

void setup() {
Serial.begin(9600);
}

void loop() {
while(analogRead(A0)<50) (true); //wait for start of transmission
for(i = 0; i<500;i++){
}
for(int i = 0;i<500;i++){
Serial.println(data[i]);
}
delay(1000);//just prevent starting again to soon
}

• Just a wild guess, but it looks like you're getting near the limit of your Arduino at 10us. You'll probably need to optimize your code. In any case, it would be helpful to see the code your running on the Uno. – Ricardo Jan 23 '15 at 12:50
• I added the code above. I don't think the limit is the Arduino. When I change the sending frequency, the block shape changes, but when I change the reading frequency the shape does not change. – Butterkekskrumel Jan 23 '15 at 13:01
• why are you reading at 100kHz while the audio output is filtered at some 20kHz or less? sample at 50kHz (nyquist is happy) and use a multi level modulation if your SNR allows it. – Vladimir Cravero Jan 23 '15 at 13:05
• Without thinking about it too much, I'd say it has something to do with the output driver - it's supposed to be audio, 20Hz-20kHz... If you're trying to send non-audio data from the audio jack as I understand it. – Mister Mystère Jan 23 '15 at 13:06
• Have you looked at sine waves at 10kHz vs. 20kHz from the phone? That may be telling in terms of any filtering being done. – Scott Winder Jan 23 '15 at 13:23

The audio output of your smartphone is fitted with a bandpass filter: high pass to protect the membrane of your earbuds/speakers against DC which would cause useless mechanical stress, and low pass to make sure as little noise is heard. Since audio is roughly 20Hz-20kHz, signals with a higher frequency will get attenuated at a rate depending on the order of the filter - at least -3dB/decade.

In fact, that output can't even accurately output digital signals up to 20kHz. Why? Because the sharp edges of the digital signals are made up by an infinite number of elementary sinusoids. The lower the cutoff frequency, the more harmonics you'll attenuate, distorting the signal like this:

You may filter what you measure to try and reconstruct the square wave but still, it's not very appealing.

Now, you can increase the datarate for a reasonable carrier frequency (say, 4kHz), by changing the modulation and/or encoding. Modulation is the process that transforms the data to send into a signal to apply to the transmission medium (through power amp. + antenna for example) - the transport layer if you will. Encoding is higher level, it deals with anomalies detection and correction. Yours is by default certainly in its simplest form (parity bits, compared to more advanced state machines etc.), but the first step to take to increase the datarate for non-critical communication is modulation.

There is a range of possible modulation techniques out there. Each one of them will have a different signal to noise ratio - error rate relationship and also a different symbol rate out for a given datarate in.

Among all of those, I recommend the simplest digital amplitude modulation. As you increase the number of possible output levels, the signal to noise ratio will decrease so you'll have to find the sweet spot. To increase your datarate by N, you'll need to be able to read 2^N different levels.

Note: Forget about the carrier (the medium is not air, so no need for RF), and in this example 0 is coded with some amplitude but it doesn't need to be.

Should you need more, you could improve your encoding to decrease the required signal to noise ratio and therefore increase the number of levels a bit further. If it's not enough, take a look at a more complex technique, e.g. QAM. ADSL used that modulation to boost the datarate on the same lines; I don't remember the symbol rate, but the carrier was around 1MHz to avoid interfering with the telephone < 4kHz, and they achieved at least 512kb/s at the time, impossible to achieve without a very dense modulation. I'm not sure if the Arduino is powerful enough for this plus your application though.

I would use a transistor to amplify the signal and then use digital input pin instead of analog. Reading digital is faster and you can use on change interrupts instead of constantly checking the value. In the schematics below the input will be negated.

simulate this circuit – Schematic created using CircuitLab

• The speed of the Arduino is no problem anymore. But the interrupt might be interesting. I have a BC547 here, can I use it? And why is there a resistor? Thanks in advance. – Butterkekskrumel Jan 25 '15 at 16:24
• Yes BC547 will work, the resistor on 5V is there so it won't short 5V to the ground. I would also put a small (100 ohm) resistor between audio jack and the base. – Cano64 Jan 26 '15 at 15:55