Chat freely about anything...
User avatar
By Sturgizz
#68941 Hello guys,
I'm trying to build my own code for my 433MHz RF modules. The transmit side works fine, but the receiver side is more complicated. The signal I emit is as we can see on the image attached. The '0' is 80ms high and 40ms low. The '1' is coded by 40ms high and 80ms low. The code I send to test is 111000. The code below (tries to) measures bit times to find if it's a 0 or a 1.

I use a NodeMCU board, the module RF is connect: Vcc to Vin, GND to GND and DATA to D2 and below the code I wrote for the receiver side:
Code: Select allint receivePin=4;

String reception(int pinReceive){
  bool transmissionTermine=0;
  int ret=0;
  int i=0;
  unsigned long tDebutTransmission=0;
  char data[50];
  Serial.println("-------- Reception ----------");
  if (digitalRead(pinReceive)==1){
    Serial.println("-------- Debut de transmission ----------");
      ret = bitReceive(pinReceive);
      //ret = recBit(pinReceive);
      Serial.print("ret = ");
      if (ret!=-1){
        //strcat(data, *char(ret));
        Serial.print("data = ");
    return data;
  return "A";

int bitReceive(int receivePin){
    unsigned long tIndex1=0;
    unsigned long tIndex2=0;
    unsigned long tIndex3=0;
    int sortir=0;
    Serial.print("tIndex1= ");
    while (digitalRead(receivePin)==1){
    Serial.print("tIndex2= ");
    while ( sortir!=1 ){
      if ( ((micros() - tIndex2) > 85000) || (digitalRead(receivePin)==1) ){
        sortir=1;   //Get-out of the while loop
        Serial.print("val= ");
        Serial.print("(micros() - tIndex2) = ");
        Serial.println((micros() - tIndex2));
    Serial.print("tIndex3= ");
    if (((tIndex2 - tIndex1)>30000) && ((tIndex2 - tIndex1)<50000) && ((tIndex3 - tIndex2)>70000) && ((tIndex3 - tIndex2)<90000)){
      return 1;
      if (((tIndex2 - tIndex1)>70000) && ((tIndex2 - tIndex1)<90000) && ((tIndex3 - tIndex2)>30000) && ((tIndex3 - tIndex2)<50000)){
        return 0;
        Serial.print("tIndex2 - tIndex1 = ");
        Serial.println(tIndex2 - tIndex1);
        Serial.print("tIndex3 - tIndex2 = ");
        Serial.println(tIndex3 - tIndex2);
        return -1;

void setup() {
  // put your setup code here, to run once:
  pinMode(receivePin, INPUT_PULLUP);

void loop() {
  // put your main code here, to run repeatedly:
  String donnees = reception(receivePin);
  if (donnees!="A"){
    Serial.print("Données reçues: ");


And the result in the serial monitor is:
Code: Select all------ Receiving ----------
-------- Receiving ----------
-------- Transmission begins ----------
tIndex1= 256958229
tIndex2= 256979139
val= 1
(micros() - tIndex2) = 53045
tIndex3= 257039475
tIndex2 - tIndex1 = 20910
tIndex3 - tIndex2 = 60336
ret = -1
data = 
Données reçues: 
-------- Receiving ----------
-------- Transmission begins ----------
tIndex1= 257238426
tIndex2= 257259259
val= 0
(micros() - tIndex2) = 53122
tIndex3= 257319672
tIndex2 - tIndex1 = 20833
tIndex3 - tIndex2 = 60413
ret = -1
data = 
Données reçues: 
-------- Receiving ----------
-------- Receiving ----------

Is that due to interferences? I've tried to minimize it the input_pullup. Is that due to the serial monitor limit? I don't really know.
Thanks a lot for your help
signal.png (1.39 KiB) Viewed 1169 times
User avatar
By daniel_ezsbc
#68964 You have several issues with the code:

There is nothing in your code to detect the first bit of the transmission so you can start the receive code in the middle of an incoming word and get lost in the process.

The receiver will always produce an output signal, even in the absence of a transmission from the transmitter. When there's no rf it will increase the gain up to the maximum gain of the receiver and that is normally enough to cause the output to toggle due to noise. You may end up trying to decode this.

Once the RF signal appears the gain is still very high and the receiver needs some time for the gain control circuits to reduce the gain to a reasonable value. Normally RF transmissions include some form of preamble to allow the gain control to stabilize, the start of the data to be detected and to achieve synchronization. I don't see any of that in your code.
User avatar
By btidey
#68976 As described the receivers will produce random pulses even with no signal received. Typically these will be 50 to 300uSec in duration.

It is good to have some form of pre-amble so that agc settles. This can actually be as simple as turning the TX on for say 20mSec and then following that with the code sequence.

The receiving software can then start by rejecting all narrow width pulses until it sees a longer one indicating that a real signal is being received. The trailing edge of this then gives a timing reference for decoding the rest of the pulses.

You are using quite long pulses for the code bits (40 / 80mSec). If that is to match some external device then that is what is needed but if you are using your own protocol and controlling both ends then you should be able to use much shorter pulses and achieve a much quicker transmission time. This is good as it minimises the chances for other interference clashes and means the gain control keeps working well. Typical pulse widths used with 433MHz are in the 500uSec to 2000uSec range.

It is also good with one way transmission to do multiple packet transmits and only recognise receives when 2 or more identical packets are received.