I'm trying to receive a current temperature and humidity from remote weather station sensor using 433mhz receiver (EMAX EM-RX433-01). This receiver has 3 pins: GND, POWER and DATA. I connected power to 5v, GND to the ground and I'm receiving DATA in a following format:
Actual signal from the weather station is n the middle of this log. When transmitter transmits nothing, I receive a data looking like this: "11111111111111000011111111111111111110000111111111".
I have spent a lot of time reading forums and trying to understand what kind of a protocol it is and how to read it in my arduino. Maybe anyone knows how to decode this in a readable format?
-This repeating pattern is always changing a bit, there are random 1/0 sometimes. Do you mean strip it when no signal is received or strip from incoming stream?
-The whole stream is received immediately. Each bit is received in: 1/16mhz = 62,5 nanoseconds
-You are right, but curently I have no ideas how to receive not oversampled data without noise.
Looks like you're using a mega, rather than trying to read the data bit by bit on a digital input, where getting the timing right will be tricky, how about trying one of the other serial ports?
Each bit is received in: 1/16mhz = 62,5 nanoseconds
Very unlikely as the code (e.g. serial.print(val, DEC)) takes far more time to execute. 57600 baud means 5760 chars per second can be send, so the time between the above samples is at best in the order of 1/5760 sec ~~ 174 microseconds. Further the digitalRead also takes some time ....
based upon my assumption that the three -sometimes 4- zeros form one logical LOW => one real bit is in the order of 3.25 x 1/5760 == 0.00053 second. So the signal could be a 2Khz signal (which is quite a reasonable number). Below code to sample at this frequency (not compiled or tested)
void setup()
{
Serial.begin(115200); // as fast as possible
pinMode(40, INPUT);
}
unsigned long last = 0;
void loop()
{
unsigned long t = micros();
if (t - last >= 500)
{
last = t + t - last - 500; // the t- last - 500 is to prevent drifting ...
int sensorValue = digitalRead(40);
Serial.print(sensorValue, DEC);
}
}
Can you test this code and look if the pulses make more sense?
now there becomes a repeating pattern of 0111111 = 0x7F = 127 visible. This is a typical value.
And it looks like almost every 8-th bit is a zero.
The most used parts of the ascii table for tekst are in hex:
0x41 - 0x5A (uppercase)
0x61 - 0x7A (lowercase) // I see a lot of 0110xxxx0110xxxx in the stream that could mean lower case ascii
Now you have to write a program that read the bitstream at every position and convert the bits to char's and try to print them
you need to try to sync with 0x7F's
But first you have to get the sample speed right, you need to write a sketch that gets the timing better. Connect the signal to IRQ line ( don't know the MEGA iRQ PIN's) and trigger on CHANGING in the "idle" mode.
(code not tested)
void setup()
{
Serial.begin(115200);
attachInterrupt(0, IRQ, CHANGE);
}
void loop()
{}
volatile unsigned long t = 0;
void IRQ()
{
unsigned long interval = micros() - t;
t = micros();
Serial.println(interval, DEC); // ok print statements in IRQ is not advised but as the IRQ's are expected approx every 500 microseconds it might work.
}
During the idle time this code should give a short interval (one LOW ) and a long interval (7 HIGH's). If you have those two values you should be able to calculate the bitrate of the device pretty precise.
I was playing a bit with serial connection but without success: I'm receiving a lot of 255 and 253 bytes in the idle mode and random numbers while receiving... can't guess a correct baud rate.
EM-RX433-01 board is using CHMC S23 S358F chip, but I can't find data sheet for it.
There are only a few numbers under 500, so I consider that noise
There are a few very large values, => ignored too.
It looks like the basic bit width is around 512 micros()
I interpret the values between 512-700 as the times between 2 bytes. When the weather station has clocked out one byte they wait a little longer than one bit before sending the next byte.
Now the step is to write a sketch that accepts 8 bits clocked out to be samples every 512 micros() and that sketch needs to synchronize on the first LOW.
I would search the net for whatever brand/model of sensor you are using and "radio protocol" to see if some of the work has been done for you already. For example if you have a Oregon Scientific sensor theses articles describe the various protocols:
If you are on Windows you might also find the entire Weather Station Data Logger project of Interest. The have written quite a bit of code for receiving signals from various sensors, which might be helpful to you to look at. http://wmrx00.sourceforge.net/
I spent some time working on the eavesdropping on the 433Mhz sensors, but the range never amounted to what I needed in my environment, so I went with a wired solution instead.
It's the best way to start. I wrote a decoder several months ago and used the wave like the one displayed in figure 1 to interpret 1's and 0's.
Then I made a small change in temperature and looked at the wave again to guess where in the stream the data is stored. The protocol I decoded was totaly different from the one Oregon Scientific uses.
Until I saw that page, I wasted a lot of time trying to read the radio receiver and writing the state to serial.
There are lots of problems with decoding an unknown RF packet format if you want to recreate it over the air:
The things that you need to identify are:
carrier frequency
modulation type
deviation (if FM)
baud rate
manchester coding, whitening, bit-stuffing or other clock-recovery feature present.
preamble and header, CRC algorithm
I'm wondering how you know your rx433 unit is actually picking up the correct signal and not some other 433MHz device?
That radio receiver has a variable gain feature which causes it to turn up the gain as the transmitter gets further and further away. If the transmitter gets "infinitely" far away, as in, is OFF, the gain goes to max and it interprets just about anything as a 0 or 1, hence it starts to generate random data, literally hallucinating.
There is virtually nothing you can about that. The transmitter program is probably sending an inital prefix code over and over a number of times, knowing that the first few times will get trashed, but eventually, the radio receiver will lower its gain (now that a real signal is coming in) and eventually it get the code. In other words, the transmitting program sends about 10 bytes of some known code, say "37" hex, doesn't much matter what, and the receiving program looks for a 37, ignores all incoming data until it gets a few 37's, then the next non-37 is the true first byte of the data. Other ways to do it, but that is the gist.
So, in your case, find some valid data and then look back at what proceeds it always, that is the radio "wakeup code".
The best way to try and figure out what the data protocol is , is to look at the data stream in the Transmitter,
ie before its transmitted.
That way, all the noise and garbage data is removed and all you see is what the Sensor is sending.
You can then look for data which is common, ie never changes, and data which changes when the Sensor is heated or cooled.