RF433 Tx/Rx Ultrasonic sensor

Hi i would like some advice please and help. I have googled and looked on the forum here for help, and so far I have a semi working code that i have put together and this is far as i could get after weeks. It does not seem much but i have tried.
What i want the code to do is from the Transmitter which has the ultrasonic sensor, is to report the Distance to the Receiver and with the Distance values i get i can use that to turn on LEDs. But most of the projects out there all just do a Serial.print to LCDs
Ok what my code does currently it sends the distance from the Transmitter to the Receiver, and i'm getting unreliable distance readings, Trigger points even from the Serial monitor. I know this is where my fault lays but don't know how to correct. And place a reliable (distance) variable in is place

My idea is to have full control over the Variable received from the transmitter and use it as i like on the receiver.
Thank you in advance.

These are the links i have tried to put this togeather.

https://forum.arduino.cc/t/how-to-send-data-from-one-arduino-to-another/393936/10```

This is my transmitter code.

// Transmitter

#include<RH_ASK.h>
#include<SPI.h>

RH_ASK rf_driver(2000, 11, 12);

//const int Led = 8;
const int trig = 2;
const int echo = 3;
long distance = 0;

void setup(void) {
  
Serial.begin(9600);
rf_driver.init();

pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
pinMode(Led, OUTPUT);

}

void loop(void) {


  rf_driver.send((uint8_t*)distance,(uint8_t)1);
  rf_driver.waitPacketSent();

  long duration;
  digitalWrite(trig, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trig, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = (duration / 2) / 29.1;
}

Receiver code

// Receiver

#include<RH_ASK.h>
#include<SPI.h>
const int Led = 8;
uint8_t Received = 1;
long distance = 0;
RH_ASK rf_driver(2000, 11, 12);

void setup() {
Serial.begin(9600);
rf_driver.init();
pinMode(Led, OUTPUT);
}

void loop() {


    if (rf_driver.recv((uint8_t *) (&distance), &Received))
    if(distance > 10 && distance < 30){

    digitalWrite(Led, 1);
    delay(30);
    digitalWrite(Led, 0);
    delay(30);
  }
  Serial.println(distance);
  }

Then lets start with the fundamentals! What ultrasonic sensor are you using? Did you have test code for just the sensor and did it return correct time values? What are you using to reflect the ultrasonic pulse? Is it a smooth hard surface directly in front of the sensor?

In the transmitter code:
Add a Serial.println(distance); at the end of loop. Use serial monitor to show what the distance reading outputs.

You seem to be trying to use RF to synchronize receiver and transmitter. Have you factored in latency in the RF packetization and transmission? Also how have you modified the ultrasonic RX module so that it doesn't transmit?

There is a lot here that you haven't told us, I suspect. That is not a practical way to ask a question.

AARG i'm not a hot shot coder lol, it is just my hobby so i will try a better way to ask.

This is the Rf433 i'm using. I will add the Serial.print thank you for that.

And i have used, Hello worlds, and push button and LED code i got from sites, And it all works. As test codes. Some have the Onewire library and the RH_ASK.
I used a hard surface and my hand in front of the sensor.

Ok let me try again, If you look at the current code for the Transmitter and, i have all the functions on it for the Ultrasonic sensor to operate it. And initialise it.

Now all what i'm trying to do is to send the "distance value" from the Transmitter to the receiver to convert it to a usable fuction, and i know i'm going about it the wrong way, the "distance" variable needs to be packaged in way so it come out to the receiver in a reliable way. And from there it can be used.
Let me show you were i know i have the issue it. I know the distance cannot just be used as is, i just plugged it in.
And as you can see i have a statement if(distance > 10 && distance < 30) . It blinks the LED just as it is but there is a 10 CM difference in the statement and the LED blinks in about a 2mm range. I hope i'm clear enough.

//Transmittertype
  rf_driver.send((uint8_t*)distance,(uint8_t)1);
  rf_driver.waitPacketSent(); paste code here

//Receiver

    if (rf_driver.recv((uint8_t *) (&distance), &Received))
    if(distance > 10 && distance < 30){

Please re-post the entire current revised sketch, and copy and paste after that, the Serial output along with a description of what the sensor is facing at the time the output is produced. Try to pick a meaningful value for that experiment. For example if you are trying to detect 5cm then put something 5cm away. Or point it at the ceiling, it doesn't matter as long as you tell us what you did.

Do this for both the transmitter and receiver. In other words, add Serial debug statements to both. It won't help to troubleshoot the receiver if the transmitter is not working.

Also, you won't see much progress here if you don't answer questions. There are still some left from reply #2.

One very weird thing, you are using ASK protocol and you posted images of an ASK transmitter, but your transmitter sketch doesn't specify any pins for the transmitter. How is it connected?

I think, now it's important to see a diagram, or images of your hardware connections.

About the second Question, i have factored nothing in as i would not know how to as of yet that is why i'm asking for some assistance and maybe i hoping i will see the light.
Yes i am using the ASK well i'm trying to, the pinout are there on the sketch, and i have only added the Serial.print on the both the sketch's and reposted as asked.
This is the Serial.print and images of the setup and please if the image is not clear i will make up a fritzing diagram and the sketch is the same as above but i will repost if need be.

Basically i want to know how to send only the "distance" variable from the Transmitter to the Receiver and use the "distance" on the receiver end to blink and anything else i need it to do.

As you can see the Serial.print is fine on the Transmitter but not reliable on the Receiver.

This is the snippets of the code i having a problem with in the sketch's, I know i cannot just plug in the distance value here { (rf_driver.send((uint8_t*)distance,(uint8_t)1); } but it was just a test.

type or//Transmittertype
  rf_driver.send((uint8_t*)distance,(uint8_t)1);
  rf_driver.waitPacketSent(); paste code here


//Receiver

    if (rf_driver.recv((uint8_t *) (&distance), &Received))
    if(distance > 10 && distance < 30){paste code here

type or // Transmitter

#include<RH_ASK.h>
#include<SPI.h>

RH_ASK rf_driver(2000, 11, 12);

//const int Led = 8;
const int trig = 2;
const int echo = 3;
long distance = 0;

void setup(void) {
  
Serial.begin(9600);
rf_driver.init();

pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
//pinMode(Led, OUTPUT);

}

void loop(void) {


  rf_driver.send((uint8_t*)distance,(uint8_t)1);
  rf_driver.waitPacketSent();

  long duration;
  digitalWrite(trig, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trig, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = (duration / 2) / 29.1;

  Serial.print(distance);
  Serial.println(" cm Transmitter Distance");
} code here
// Receiver

#include<RH_ASK.h>
#include<SPI.h>
const int Led = 8;
uint8_t Received = 1;
long distance = 0;
RH_ASK rf_driver(2000, 11, 12);

void setup() {
Serial.begin(9600);
rf_driver.init();
pinMode(Led, OUTPUT);
}

void loop() {


    if (rf_driver.recv((uint8_t *) (&distance), &Received))
    if(distance > 10 && distance < 30){

    digitalWrite(Led, 1);
    delay(30);
    digitalWrite(Led, 0);
    delay(30);
  }
  Serial.print(distance);
  Serial.println(" cm Receiver Distance");
  delay(200);
  }


Your receiver circuit looks okay. Not the transmitter circuit. You are attempting to power the breadboard and modules from the Arduino Vin pin. How are you powering the Arduino?

If you are powering via the barrel connector, you are applying overvoltage to the modules and to the Arduino I/O pins via the connecting wires. The transmitter you are using can work safely on a higher voltage like 9V, but not the ultrasonic sensor.

If you are powering the Arduino via the USB port, there is no power on Vin, so both modules will be completely unpowered.

On the software side, here you are sending a 'long' data type, 'distance'. That type takes 4 bytes of storage. So why are you only sending one byte?

Also, why are you sending a 'long'? Do you expect to be detecting anything 2 billion centimeters away? Or any negative distance? :slight_smile:

I looked on the transmitter image now and i see there is an error of parallax so it seems it is powered up from the Vin pin but i do have it on the 5v, apogees for that. Anyway they are both powered up from the laptop using the usb data inputs,

Ok Aarg thanks for coaching me i'm almost seeing the light now, i changed the (uint8_t Received = 4;) from 1 to 4 since you are saying that a long is four bytes.
And now it is working. reliable reading on the both sides of the Serial monitor and the Led is flashing at the correct distance as well. Tell me the variable distance could that be considered as a byte instead of using the long. I will test it anyway.
Railroader thanks for advising me on using the Serial.print.

// Transmitter

#include<RH_ASK.h>
#include<SPI.h>

RH_ASK rf_driver(2000, 11, 12);

//const int Led = 8;
const int trig = 2;
const int echo = 3;
long distance = 0;
int data = 0;

void setup(void) {
  
Serial.begin(9600);
rf_driver.init();

pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
//pinMode(Led, OUTPUT);

}

void loop(void) {

  data = distance;
  rf_driver.send((uint8_t *)&distance, (uint8_t)4);
  rf_driver.waitPacketSent();

  long duration;
  digitalWrite(trig, LOW);  // Added this line
  delayMicroseconds(2); // Added this line
  digitalWrite(trig, HIGH);
  delayMicroseconds(10); // Added this line
  digitalWrite(trig, LOW);
  duration = pulseIn(echo, HIGH);
  distance = (duration / 2) / 29.1;

  Serial.print(distance);
  Serial.println(" cm Transmitter Distance");
}
// Receiver

#include<RH_ASK.h>
#include<SPI.h>
const int Led = 8;
uint8_t Received = 4;
long distance = 0;
int data = 0;

RH_ASK rf_driver(2000, 11, 12);

void setup() {
Serial.begin(9600);
rf_driver.init();
pinMode(Led, OUTPUT);
}

void loop() {


    if (rf_driver.recv((uint8_t *)&distance, &Received))
     
    if(distance > 10 && distance < 30){

    digitalWrite(Led, 1);
    delay(30);
    digitalWrite(Led, 0);
    delay(30);
  }
  Serial.print(distance);
  Serial.println(" cm Receiver Distance");
  delay(200);
  }

It really depends on what the largest number you want to send is. If the number you are sending is in centimeters, 'uint16t' would probably be the best choice, two bytes.

If you need to specify the number of bytes, use the 'sizeof' operator instead of using a hard coded number.

uint16_t distance;
...
  rf_driver.send((uint8_t *)&distance, sizeof (distance));

It doesn't matter what value you set 'Received' to initially, you chose 4, but actually the reason it's passed by address to 'rf_driver.recv()' is that the value is not a constant, it is set to the number of bytes actually received. So if the transmitter sends 4, it will become 4, if it sends 7, it will become 7 and so on...
so this

uint8_t Received = 4;

should really be

uint8_t Received;

and if you want to be really safe from receive errors, you should check the value to confirm that you actually got the number you expect.

If it was my project, I would not send centimeters, I would send the microseconds result 'duration' and then perform the calculations on the receive device, to allow more accurate measurement:

float distance = (duration / 2.0) / 29.1;

If you integer divide by about 60 before you transmit, you are reducing the precision of the value by 60 instantly. You can never recover that information after that.

Another thing, you are spamming the ISM band. There are strict rules about the duty cycle of transmissions in the 433MHz band. Imagine why, if your device is transmitting every 200ms or so, every consumer device nearby on that frequency is blocked. It is a shared band. So it's actually illegal in many countries. You should send only every 30 seconds or so.

Ok thanks for advise i will work on it, I just did a quick test and did what you have recommended on the transmitter, just the basics you laid out for me, but now i don't get the "distance" on the Serial.print. But it is ok, i will work on it, i think there may have to be changes on the recv side now that there are now changes on the transmitter.

You did mention the you are spamming the ISM band . so i suppose the way to remedy that would be by using a Mills function to do the transmitting every 30 seconds.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.