I would like to get the best range possible from my 433MHz modules. After A LOT of searching and reading, I'm convinced I should be able to cover 10m indoors with free line of sight.
[update]
After some tips in the comments I changed a few things. It looks like with an Arduino receiving in stead of a Pi, I get an extra meter, 1,5m now so still terrible. And 'as a bang on the fire arrow' as we say in Dutch, I now use two whip antenna's parallel to each other.
Before moving to fix the reception on my Pi, I now first try to maximize the reception on the receiving Arduino. This makes it much more simple to investigate.
[update 2]
After some more tests I got to about 6 meters range. When the transmitter is behind 1cm of wood, this goes back to 30cm.
My current 433MHz modules are going into the garbage bin, I thank you all for your time. I will look for a more stable alternative and maybe try some other/better433MHz modules like these: http://www.ebay.com/itm/433MHz-Superheterodyne-RF-Link-kits-3400-ARM-MCU-Transmitter-and-Reveiver-/281169560721?hash=item4177030491:g:SUcAAOxyaTxTRKJn
[update 3]
The new modules made an enormous change. I can now send my data from across my house with no problems at all. No ground plane (will try that TwoD!) yet. Still on 5V transmitter voltage!
I've asked a question before about my 433MHz setup so for full disclosure:
433MHz sending not receiving
My current range is about 40/50cm, this is not much since I use a straight antenna ~17cm at the receiver and a coil antenna at the transmitter:
http://www.instructables.com/id/433-MHz-Coil-loaded-antenna/
These are the modules I use:
http://www.ebay.com/itm/-/221524421949?roken=cUgayN&soutkn=xKBBUo
And just FYI, I use these awesome working pumps:
http://www.ebay.com/itm/-/321779742264?roken=cUgayN&soutkn=hk1lrB
I have tried many antenna combinations and also upping the transmitter voltage to 12V but it doesn't help much. My aim is to reach 10m line of sight at the least.
- I notice that my Pi outputs 4.77V to the receiver.
- The 4 penlites now output around 5V so transmitter power is low.
- What I also like to test is adding 10uF caps to the V and GND of the transmitter but I have to wait for them to get delivered.
- I have the 10mw version of the transmitter, they may be just useless.
- The receiver stands in front of a speaker and a subwoofer, I turn those off when I test.
- The 433MHz modules came in pairs. I did not respect this and use any receiver with any transmitter, wonder if this is a problem. My end-goal is 3 transmitters on one receiver.
- Since I have multiple Tx/Rx modules, I swapped them to exclude DOA modules.
- Also tried these Helical antenna's, only made range worse; http://www.ebay.com/itm/-/171271811976?roken=cUgayN&soutkn=TmOnpH
My Arduino usses VirtualWire to send with 1000 baud to my Raspberry Pi, on the Pi side I use PIGPIO and the following code:
if __name__ == "__main__":
import time
import datetime
import pigpio
import vw
import json
import requests
from requests.auth import HTTPDigestAuth
# Setup receiving 433MHz port
RX=27
# Setup Baud rate 433MHz
BPS=1000
# Connect to local Pi.
pi = pigpio.pi()
# Specify Pi, rx gpio, and baud.
rx = vw.rx(pi, RX, BPS)
# Empty message
msg = 0
# Save the time
start = time.time()
# Run for 3 seconds
while (time.time()-start) < 36000:
# Count msg per cycle
msg += 1
# Sleep for .4 second
time.sleep(0.4)
# Run while receiver is ready
while rx.ready():
# String join received characters into message
message = ("".join(chr (c) for c in rx.get()))
# Print the received message to screen
print(message)
# Create data dictionary
data = {}
data['meting'] = message[8:11]
data['bericht'] = message[4:7]
data['plant'] = message[1:3]
data['timestamp'] = str(datetime.datetime.utcnow().isoformat())
# Print the data to the screen
print(data)
# Setup filename for local data backup
filename = str('data/' + data['plant'] + data['bericht'] + data['meting'] + '.json')
# Write JSON data file to disk
with open(filename, 'w') as outfile:
json.dump(data, outfile)
# Sending data
url = 'http://server:8000/v1/documents?database=plantjes&extension=json'
# Setup headers
headers = {
'Content-Type': 'application/json'
}
# Execute request
r = requests.post(url, json = data, auth=HTTPDigestAuth('plantje', 'password'))
# Print request response
print r
# Cancel the receiving of data
rx.cancel()
# Stop PIGPIO listening on pins
pi.stop()
This script sends the measurement of the Hygro sensor to a database in JSON. This works like a charm.
The Arduino uses this code:
#include <VirtualWire.h>
#include <Sleep_n0m1.h>
String pid = "p02";
const int led_pin = 11;
const int transmit_pin = 12;
const int hygroSensor = 0;
int hygroPower = 8;
const int pump_pin = 5;
int watering_level = 900;
int count = 0;
Sleep sleep;
unsigned long sleepTime;
void setup()
{
// serial console setup
Serial.begin(9600);
Serial.println("setting up");
// cycle sleep time in ms
sleepTime = 10000;
// virtualwire setup
vw_set_tx_pin(transmit_pin);
// setting of pin modes
pinMode(hygroPower, OUTPUT);
pinMode(led_pin, OUTPUT);
pinMode(pump_pin, OUTPUT);
// Bits per sec
vw_setup(1000);
}
void loop()
{
// delay to allow serial output to be ready after wake up
delay(100);
// cycle counter
count++;
// turn on hygro sensor module
digitalWrite(hygroPower, HIGH);
// wait a bit for hygro sensor to start
delay(1000);
// read the input on analog pin 0:
int measure = analogRead(hygroSensor);
// Start light to show transmitting
digitalWrite(led_pin, HIGH);
// log moment of sending
Serial.println("Sending: " + String(measure));
// create & send random message id
String mid = "m" + String(random(100, 999));
// Sending data
String hygrodata = "d" + String(measure);
dataSend(pid + mid + hygrodata);
// Stop light to show transmitting
digitalWrite(led_pin, LOW);
// Wait a second
delay(1000);
// sleep code
if(count >= 3)
{
// reset counter
count = 0;
// run pump routine
//waterpump(measure, mid, pid);
// log sleeping to serial console
Serial.print("Going to sleep now..");
// set sleep mode
sleep.pwrDownMode();
// turn off hygro module power
digitalWrite(hygroPower, LOW);
// sleep for: sleepTime
sleep.sleepDelay(sleepTime);
}
}
// Data sending funtion
int dataSend(String data) {
// declare int for length of message
int msglen;
// set length of message +1
msglen = data.length() + 1;
// declare array of characters
char envelope[msglen];
// put string in array
data.toCharArray(envelope, msglen);
// log data to serial monitor
Serial.println(data);
// send data
vw_send((uint8_t *)envelope, sizeof(envelope));
// wait for sending to finish
vw_wait_tx();
// return 1 for succes
return 1;
}
// Pump function
int waterpump(int measure, String mid, String pid) {
// Log measure
Serial.println(measure);
// Water when needed
if (measure > watering_level) {
// Turn on pump 2 seconds
digitalWrite(pump_pin, HIGH);
delay(3000);
digitalWrite(pump_pin, LOW);
// Send pump data
dataSend(pid + mid + "pump");
}
}
This controls the sensing of the messages and also the water pump I use to water my plant automagically when needed. This also works like a charm.