Transmit data via audio over RF or phone

Hi Folks

Has anyone of you ever attempted to send data over PMR radios, babyphones, ham radio or similar devices?
The idea has sprung from the need to create a wireless weather sensor very quickly on a small budget. I'd like to use only what is available to me here and now. I only need one-way communication as I just need to send a few values to a base station connected to the internet to remind me when the plants need watering: I have an Arduino in the garden, reading in soil humidity values. They are supposed to be sent to another Arduino base station connected to the PC or an ethernet shield, whatever I get to work out. :slight_smile:

My idea would be to use two handheld radios as a link between the outdoor arduino and the indoor arduino, as I have two of those around. There doesn't seem to be an arduino library out there which would allow me to encode and decode data in audio signals, is there?

<ARDUINO (lib.)>--wire--<audioIn TRANSM.> - - air - - <audioOut RECEIV.>--wire--<ARDUINO (lib.)

From a first google, there are no obvious picks, but a lot to draw inspiration from:

http://www.ecst.csuchico.edu/~eseifert/radio_modem.html

  • uses a common FM transmitters and FM radios to sends strings of audio-encoded data ('chat') over the FM band. Impressive, but implemented on a PC. I want THIS but as a library for the arduino. It would be OK if this is all the CPU allows, I have some ATMegas lying around so I can dedicate one exclusively for communication.
    Necessities: Sound library (free), DIY FM transmitter (free-5$), DIY FM receiver (free-5$) or other radio pair
    Price: 0-10$

http://w2mh.wordpress.com/2010/06/03/dtmf-shield/

  • There appears to be a shield which can decode DTMF, which could be used to encode my data. But for this, I'd either need the shield or the components as it used a dedicated IC (MT8870) to decode the signal. This probably also means that it tolerated high noise levels which might be really good.
    Necessities: DTMF data encoding library (free), [2] MT8870 (<10$), radio pair (got them: free)
    Price: ~10$

https://web.archive.org/web/20210507090052/https://www.uchobby.com/index.php/2007/09/30/phone-to-microcontroller-interfacing-with-dtmf/

  • This is a really nice writeup of the same chip used above in combination with an ATMega.
    But I don't necessarily want to buy an MT8870. Chips are 3-4 Euros a piece on Ebay but have to be shipped from Thailand or otherwise sourced and shipped to Europe. Also, I'd need to work a bit on how to de- and encode the data I want to send.

http://tronixstuff.wordpress.com/2011/01/19/tutorial-arduino-and-gsm-cellular-part-one/
http://code.google.com/p/sserial2mobile/wiki/MotorolaC168i

  • Another possibility was to use GSM SMS alerts, but I don't have any cellphone working with the sserial2mobile-library however, there would be a 15 Euro one on Ebay as a last resort. The GSM modules are just too expensive for me right now.
    Necessities: Cellphone (~20$ Ebay), GSM module (>50$)
    Price: 20-80 $

Just a thought: What about using and IR-communication library and just putting the audio input where the LED was. Could something along those lines work? The LED light is modulated and it might work reliably even with noise.
Necessities: IR functions(free), IR transmitter/receiver pair (free-5$), radio pair (got them)
Price: free if you can get a IR remote controlled device to take apart

  • Now and then there is this nice little thing: It allows you to hack the 433MHz AM transmitter remotes of available el-cheapo remote controlled outlet devices. It doesn't feature more then a 'sort of' 4 bit communication as it is, but I'm mentioning it since I have one lying around, maybe I missed an obvious solution here.
    Necessities: a good idea for an easy protocol (priceless), Remote controlled outlets (~20$)
    Price: 20$

http://code.google.com/p/arduino/issues/detail?id=441
This also looks interesting, it is an arduino based device that creates CTCSS signals (I'm not entirely sure how it works though as details are sparse.) It also uses a dedicated chip for the generation of the signal, which rules out this particular implementation for me. (for now...) But CTCSS tones are quite low, maybe that makes it more robust?
Necessities: library for encoding CTCSS tones (priceless), radio pair, maybe needs dedicated ATMegas
Price: possibly free

This is an application note for an ATMega used as a DTMF tone generator. This helps me only so far, as it covers only one side of the whole operation but it's nice to see that tone generation obviously works.
Necessities: Dedicated ATMega (free-5$), a way to decode the data (priceless)
Price: free-5$

//edit: just for completeness, I'll add those two possibilities which are wandering my mind:
http://www.geocities.co.jp/arduino_diecimila/wifi/a2p_ddwrt_en.html

  • now this would be a nice idea: use a DD-WRT flashed router with a serial port to send data to Processing I could just build a nice enclosure and put myself a router in the garden. Awesome, but quite expensive if you don't have the router. I'd have one but I might need it inside.
    Necessities: DD-WRT router (ie. Linksys WRT54GL) (free-60$), waterproof housing (have one!), antenna wiring adapters (have them)
    Price: free-65$

http://jeelabs.com/collections/all

  • Here is an excellent all-around solution, I could just use a JeeLink with a JeeNode. It's so excellent because the arduino compatible software takes care that my data is transmitted easily and securely. Also, a lot can be learned from the author, who puts a lot of effort into documenting the development of his products. (Thanks!)
    Necessities: JeeLink (30 Euro), JeeNode SMS v2 (24 Euro)
    Price: 54 Euro (with shipping)

As a sidenote: I'm aware that transmitting data over PMR is not necessarily legal, but I also don't suppose that a few tones transmitted a few times an hour will bother anyone. Also, I can opt for citizens band, which seems to allow for data transmission. (You can leave worrying about this issue to me, I'll check local regulations before building the device, promise.) The interesting thing is encoding/decoding of data to audio with medium to high reliability.

Also, I already have the following components I in intend to use:
Indoor station:
[1] small laptop running XP and/or Ethernet shield,
[1]Arduino/AtMegas,
[1] 868 MHz receiver module,
seperately: [1] Chumby to display the Pachube data
yet to determine: [1] outdoor sensor receiver

Outdoor station
[1] Arduino
[3] DIY gypsum soil sensors
[1] DIY DS1820 soil temp sensor
seperately: [1] weather station 868 MHz (Alecto WS-4000 3000)
yet to determine: [1] sensor data transmitter

Do you have any other ideas how I get my indoor arduino to receive data from the outdoor unit cheap and fast?
Also, I have not yet completely resolved the issue on how to get the weather station data to the arduino with the receiver module, but that's another topic. Of course, I could get a 868 MHz transmitter so both, the weather station and the outdoor arduino would be able to transmit to the indoor arduino. But reading the weather station data seems rather complicated and I haven't found a good tutorial: apparently you have to do some modifications on the module to make it work, if it works at all. Thus I'll make it my first priority to get the soil sensors working with the indoor station whatever way works fastest.

Any ideas? If you have done something similar, feel free to dump some code, links or pics.

  • have you considered buying just a standard outdoor-weather sensor and simply receive/decode this signal with an Arduino?

Weather station sensors come usually with a 433MHz or 868 MHz transmitters and are ready to run. A complete 433MHz-sensor with a combined temperature and humidity sensor I recently bought was slightly cheaper than an Arduino. There's no way to beat this with a home-grown solution....

All you have to do to use such a sensor is to get a matching receiver module (a few $$ - search Sparkfun for example) and search for some information on the code your sensor is using.

The later will probably be the major part of work for you to do.

The best approach here is to try to get a ready-made sensor of which some guys already have written down some knowledge about the transmission codes. Google and some weather forums are certainly your friends here. Stay away from sensors where the protocol is not available on the internet - you might succeed in figuring out the protocol on your own, but it's some work and requires some good guessing (I actually did this for my weather sensor, just for fun. Took me a weekend however ;)).

With such a system, all you need (in addition to the weather sensor) is a basestation: an appropriate RF-receiver + an Arduino + an ethernet-shied + appropriate software to get your weather data to the internet. Guess that's the cheapest option you can come up with.

If you really want to cook your own dish, you might try to use cheap RF-receivers/transmitters with the Virtualwire-library. Some people had success with this kind of setup. Just search this forum.

Yet another option would be to try using some nRF24L01+-based network. These chips work in the 2.4GHz band and will have different propagating properties. For starters, 2.4GHz waves do not penetrate walls that easily than the lower frequencies. Also, some surveillance cameras transmit a constant carrier in this band; furthermore, most WLAN and BlueTooth-traffic is happening there. But these chips are rather cheap and you get even autoacknowledged bi-directional transmission for free. Furthermore, you can easily select a channel with is free of interference.

A final note: as you have already mentioned in your post, using RF-bands which are reserved for specific other things is generally not a good idea. For starters, it is illegal in most parts of the world and it might be costly as well, if someone is bothered by your transmissions. Secondly, the bands you might misuse can have heavy traffic going on, even constant carrier transmissions. This will reduce the reliability of your own transmission link substantially.

In contrast, transmissions in the ISM bands (where most weather station sensors are working) are usually very short (that is even required in some jurisdictions), so interference between two transmitters will happen only occasionally.

So, usually it is a good practice to stick to standards...

cpixip:

  • have you considered buying just a standard outdoor-weather sensor and simply receive/decode this signal with an Arduino?

Weather station sensors come usually with a 433MHz or 868 MHz transmitters and are ready to run. A complete 433MHz-sensor with a combined temperature and humidity sensor I recently bought was slightly cheaper than an Arduino. There's no way to beat this with a home-grown solution....

I did buy an Alecto WS-3000. The problem is that most weather stations use an OOK protocol that can't be decoded by off-the-shelf receivers:
http://jeelabs.net/projects/11/wiki/Receiving_OOKASK_with_a_modified_RFM12B
Also, the main part of the project concerns the soil humidity sensors, which are, unlike the weather station, part of the Outdoor Arduino Unit.

cpixip:
The best approach here is to try to get a ready-made sensor of which some guys already have written down some knowledge about the transmission codes. Google and some weather forums are certainly your friends here. Stay away from sensors where the protocol is not available on the internet - you might succeed in figuring out the protocol on your own, but it's some work and requires some good guessing (I actually did this for my weather sensor, just for fun. Took me a weekend however ;)).

Would you mind sharing some infos/link/pics? Sounds really cool!

cpixip:
If you really want to cook your own dish, you might try to use cheap RF-receivers/transmitters with the Virtualwire-library. Some people had success with this kind of setup. Just search this forum.

This is probably what I'll end up doing: Buying some cheap RF radios and use the JeeLabs code. But still, cost and time for sourcing the stuff bothers me.

cpixip:
Yet another option would be to try using some nRF24L01+-based network. These chips work in the 2.4GHz band and will have different propagating properties. For starters, 2.4GHz waves do not penetrate walls that easily than the lower frequencies. Also, some surveillance cameras transmit a constant carrier in this band; furthermore, most WLAN and BlueTooth-traffic is happening there. But these chips are rather cheap and you get even autoacknowledged bi-directional transmission for free. Furthermore, you can easily select a channel with is free of interference.

Yeah, I've seen those modules around. They're not too expensive and seem quite reliable. I'll add them to the list later.

cpixip:
A final note: as you have already mentioned in your post, using RF-bands which are reserved for specific other things is generally not a good idea. For starters, it is illegal in most parts of the world and it might be costly as well, if someone is bothered by your transmissions. Secondly, the bands you might misuse can have heavy traffic going on, even constant carrier transmissions. This will reduce the reliability of your own transmission link substantially.
[...]
So, usually it is a good practice to stick to standards...

You're absolutely right. However you can still use a phoneline or those Iphone radio transmitters.
Thanks a lot for your input! Especially the point about interfering traffic is one I'll certainly keep in mind.

... The problem is that most weather stations use an OOK protocol that can't be decoded by off-the-shelf receivers:
http://jeelabs.net/projects/11/wiki/Receiving_OOKASK_with_a_modified_RFM12B

:slight_smile: - true. That is why in this case, it is probably better to use a simpler one than the RFM12B, for example this here: http://www.watterott.com/de/RF-Link-2400bps-Empfaenger-434MHz.

This is very simple receiver giving out just the schmitt-triggered RF-amplitude on its data pin. Such a receiver has a autogain, so if there is no transmission, you will see a lot of noise in the data stream. Your Arduino needs to be able to handle this (see below).

cpixip:
The best approach here is to try to get a ready-made sensor of which some guys already have written down some knowledge about the transmission codes. Google and some weather forums are certainly your friends here. Stay away from sensors where the protocol is not available on the internet - you might succeed in figuring out the protocol on your own, but it's some work and requires some good guessing (I actually did this for my weather sensor, just for fun. Took me a weekend however ;)).

Would you mind sharing some infos/link/pics? Sounds really cool!

Sure. I started my little project weather receiving project when I received a 433MHz sensor (temperature & humidity) for my 868MHz weather station. Instead of sending the wrong unit back, I started to investigate this.

First step was to hook up the data output pin of this simple 433MHz receiver I happen to have in my box (link above) to the audio-in of my PC. I started to record the data stream with Audacity, and sure enough, after about one minute, I could hear a characteristic chirp, and see some meaningful patterns in the data stream.

The next thing to do was to get some hints on the codes used; google gave me for example the following page (Mein Sensorprotokoll) which was very helpful. As mentioned before: weather forums are also a good place to hunt for information.

Once the code the sensor was using was clear, it was programming time. The specific sensor I have transmits the same information three times in a row (see attached picture, the top yellow curve). The start of the first transmission is usually corrupted with noise, as the autogain function has not yet reacted to the sensor signal. That can be seen at the very left of the attached screen dump. However, the second transmission was always very clear, even at larger distances, as the audiogain had already adjusted to the transmission level at this point in time. So, I opted to simply write a code which would lock onto this second transmission.

I had two choices - one was to use a timer interrupt (as done in some IR-decoding libraries), the other was to use simply the pulseIn()-function of the Arduino. For simplicity, I opted for the later.

The program is rather simple. The first thing which happens in "loop()" is to wait for the long pause between the first and the second transmission of the sensor reading:

do
  {
    time = pulseIn(7,0);
  }
  while( time<17000 || time>30000 ) ;
  • as this was a weekend project, I simply read off the times required for the while-condition from my oscilloscope trace... :wink:

Once I had the start of the code block, I recorded the on/off-times of the following pulsetrain into an array, as long as the measured pulse lengths were short enough. Any pulse longer than a certain threshold triggered the decoding of the pulse train, pretty much the same way as this is done in common IR-receiving libraries. Parallel to recording the pulse times, I wrote the decoded pulses out on an Arduino pin - this is the second (cyan/bottom) trace on the the attached picture. Sure enough, only the second pulse train is being decoded, as designed.

One remark: for recording the timings of the actual pulses, I shamelessly modied the original pulseIn()-function by deleting a few lines:

unsigned long my_pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
	// cache the port and bit of the pin in order to speed up the
	// pulse width measuring loop and achieve finer resolution.  calling
	// digitalRead() instead yields much coarser resolution.
	uint8_t bit = digitalPinToBitMask(pin);
	uint8_t port = digitalPinToPort(pin);
	uint8_t stateMask = (state ? bit : 0);
	unsigned long width = 0; // keep initialization out of time critical area
	
	// convert the timeout from microseconds to a number of times through
	// the initial loop; it takes 16 clock cycles per iteration.
	unsigned long numloops = 0;
	unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
	
	// wait for the pulse to stop
	while ((*portInputRegister(port) & bit) == stateMask) {
		if (numloops++ == maxloops)
			return 0;
		width++;
	}

	// convert the reading to microseconds. The loop has been determined
	// to be 20 clock cycles long and have about 16 clocks between the edge
	// and the start of the loop. There will be some error introduced by
	// the interrupt handlers.
	return clockCyclesToMicroseconds(width * 21 + 16); 
}

The reason was that the original pulseIn()-function (which I still used for triggering the signal recording, as described above) is actually waiting for a transition of the signal whereas I just wanted to measure times a signal was high or low.

Actually, the decoding of these weather station receivers is very similar to the decoding of IR-signals, with the added challenge that the RF-signal is - due to the autogain function of these receivers - much nosier than the signal which comes from a IR-sensor. If that wouldn't have been a weekend project, I would have probably started with an IR-library which typically are using more precise timer-interrupts. But the quick hack above did the trick :).

I guess one could cook up a own weather sensor with the appropriate protocol choice, an Arduino and the corresponding transmitter module (see here: http://www.watterott.com/de/RF-Link-Sender-434MHz). But I haven't done that so far....

did you get any luck with the original walkie talkie idea?