Idiot needs help Lora sketch

I have tried for answers in the "programming" section and several respondants have done thier very best to help me but i must be an idiot because I still dont understand so I was hoping this might be the area to seek paid help.

I am looking for someone to modify the Radiohead rs95 lora code so that I can transmit 5 integers from sender and convert back to integers at the receiving end.

I cant pay in bitcoin but Paypal is OK for me.

Can anyone help?

Why modify RadioHead? It's easy to do with the eisting message functions. 1, 2 or 4 bytes per integer depending on the actual type, some memcpy magic to get it into your message, that's it. RadioHead handles this really nicely. Then the receiving end can just memcpy it back out of the message.

Thanks for your reply wvmarle but as I said "I am a coding idiot" and nothing you said made any sense to me.

Thats why I am happy to pay someone to modify the code for me.

I've been there done that just before :slight_smile: A number of values, pack it in a message, send it to another node, have it unpack it.

It's a bit tricky to get right, especially when you change anything in the data structure you're sending over. Maybe I should just rewrite it for a general case: pass in a data structure, send it over, receive it on the other side and decode it. Makes maintenance a lot simpler.

I just modified the RFH95 Radiohead examples a little; this should work by putting the data into a struct, then transmitting the struct in one go. Just make sure the total size of your struct is not larger than RH_RF95_MAX_MESSAGE_LEN (= 251 bytes).

It compiles; not tested. It should be straightforward to add this to your program. Please let me know whether it works.

RH95_reliable_datagram_server (modified):

// rf95_reliable_datagram_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging server
// with the RHReliableDatagram class, using the RH_RF95 driver to control a RF95 radio.
// It is designed to work with the other example rf95_reliable_datagram_client
// Tested with Anarduino MiniWirelessLoRa, Rocket Scream Mini Ultra Pro with the RFM95W 

#include <RHReliableDatagram.h>
#include <RH_RF95.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_RF95 driver;
//RH_RF95 driver(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, SERVER_ADDRESS);

// Need this on Arduino Zero with SerialUSB port (eg RocketScream Mini Ultra Pro)
//#define Serial SerialUSB

void setup() 
{
  // Rocket Scream Mini Ultra Pro with the RFM95W only:
  // Ensure serial flash is not interfering with radio communication on SPI bus
//  pinMode(4, OUTPUT);
//  digitalWrite(4, HIGH);

  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
  // you can set transmitter powers from 5 to 23 dBm:
//  driver.setTxPower(23, false);
  // If you are using Modtronix inAir4 or inAir9,or any other module which uses the
  // transmitter RFO pins and not the PA_BOOST pins
  // then you can configure the power transmitter power for -1 to 14 dBm and with useRFO true. 
  // Failure to do that will result in extremely low transmit powers.
//  driver.setTxPower(14, true);
}

uint8_t data[] = "And hello back to you";
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];

struct message_t {
  int value1;
  int value2;
  int value3;
} message;

void loop()
{
  if (manager.available())
  {
    // Wait for a message addressed to us from the client
    uint8_t len = RH_RF95_MAX_MESSAGE_LEN;
    uint8_t from;
    if (manager.recvfromAck((uint8_t *)&message, &len, &from))
    {
      Serial.print("got request from : 0x");
      Serial.println(from, HEX);
//      Serial.print(": ");
//      Serial.println((char*)&message);

      // Send a reply back to the originator client
      if (!manager.sendtoWait(data, sizeof(data), from))
        Serial.println("sendtoWait failed");

      // Recover the values transmitted!
      Serial.print(F("Message len (expect: 6): "));
      Serial.println(len);
      Serial.print(F("value1 (expect 42): "));
      Serial.println(message.value1);
      Serial.print(F("value1 (expect 13): "));
      Serial.println(message.value2);
      Serial.print(F("value1 (expect 666): "));
      Serial.println(message.value3);
    }
  }
}

rf95_reliable_datagram_client (modified):

// rf95_reliable_datagram_client.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple addressed, reliable messaging client
// with the RHReliableDatagram class, using the RH_RF95 driver to control a RF95 radio.
// It is designed to work with the other example rf95_reliable_datagram_server
// Tested with Anarduino MiniWirelessLoRa, Rocket Scream Mini Ultra Pro with the RFM95W 

#include <RHReliableDatagram.h>
#include <RH_RF95.h>
#include <SPI.h>

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_RF95 driver;
//RH_RF95 rf95(5, 2); // Rocket Scream Mini Ultra Pro with the RFM95W

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram manager(driver, CLIENT_ADDRESS);

// Need this on Arduino Zero with SerialUSB port (eg RocketScream Mini Ultra Pro)
//#define Serial SerialUSB

void setup() 
{
  // Rocket Scream Mini Ultra Pro with the RFM95W only:
  // Ensure serial flash is not interfering with radio communication on SPI bus
//  pinMode(4, OUTPUT);
//  digitalWrite(4, HIGH);

  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  if (!manager.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, 13dBm, Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on

  // The default transmitter power is 13dBm, using PA_BOOST.
  // If you are using RFM95/96/97/98 modules which uses the PA_BOOST transmitter pin, then 
  // you can set transmitter powers from 5 to 23 dBm:
//  driver.setTxPower(23, false);
  // If you are using Modtronix inAir4 or inAir9,or any other module which uses the
  // transmitter RFO pins and not the PA_BOOST pins
  // then you can configure the power transmitter power for -1 to 14 dBm and with useRFO true. 
  // Failure to do that will result in extremely low transmit powers.
//  driver.setTxPower(14, true);
}

uint8_t data[] = "Hello World!";
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];

struct message_t {
  int value1;
  int value2;
  int value3;
} message;

// Some random values to transmit.
int value1 = 42;
int value2 = 13;
int value3 = 666;

void loop()
{
  Serial.println("Sending to rf95_reliable_datagram_server");
  message.value1 = value1;
  message.value2 = value2;
  message.value3 = value3;
    
  // Send a message to manager_server
  if (manager.sendtoWait((uint8_t *)&message, sizeof(message), SERVER_ADDRESS))
  {
    // Now wait for a reply from the server
    uint8_t len = sizeof(buf);
    uint8_t from;   
    if (manager.recvfromAckTimeout(buf, &len, 2000, &from))
    {
      Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("No reply, is rf95_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

wvmarle. Thanks for your response.

Your sketch seems to work just fine on the "Sender" but I still get no printout of the integers on

the "receiver ". Instead of printing out the Integer received it just prints out just one HEX number

Sorry wvmarle , my problem is with the sender side.

It sends the correct integers , the receiver receivers the correct integers but

on the sender side

Serial.print("got reply from : 0x");
      Serial.print(from, HEX);
      Serial.print(": ");
      Serial.println((char*)buf);

This code just prints out the HEX 0x2 but not the Integers acknowledged.

Client sends data to the server, which prints it out.

Server just sends a generic reply to client.

Sounds like it works as intended, but hard to say as you didn't post actual Serial monitor outputs and making it clear which output is from "client" and which from "server".

Sorry, I was unclear.

What I actually is two way, so that either Sender to Receiver actually transmits and also

Receiver to Sender also can transmit.

As in your modified sketch I would like to send to receiver and have the receiver send back to the

transmitter " Yes I got (Integer,Integer,Integer) and thge original sender could check that what was sent,

was what was received.

Does that make sense.

Same way. Create a struct for the data to be returned in the server sketch (or if it's the same data - just use the existing one, send it back), and use that as message.

You'll quite certainly want to change the code later so do make sure you know what's going on.

Basically all data is stored in a newly defined type, that struct message_t. That's just a piece of memory.

The manager.sendtoWait() function expects to receive an array of bytes (aka uint8_t) so when the message is passed on to that function it gets cast to an array of byte, upon which the sendtoWait() function can read the bytes from memory and send it over.

Remember: all data in the end gets stored as bytes in memory. Be it an integer, a float, a string - doesn't matter, in the end it's just a piece of memory, and those bytes have to be sent over. The radio doesn't care the least what the data represents, it takes the packet and sends it as is, and on the other side it's received and placed back in memory. It's up to you, the programmer, to make sure the data gets copied to the correct place (that's the message variable), and that there's enough memory available to do so.

So there's actually a major issue with this code: the receive buffer (the 6 bytes reserved for message) will overrun the moment you get more bytes than that... to prevent that change the value of len that you pass in, or make sure message can store 251 bytes. That way no matter what message you receive, you're safe.

wvmarle Thanks for your help.

Sender to Receiver is working fine but still cannot get the coding right to send

a transmission back from the Receiver to Transmitter.

I will keep working on it. ( at "arduino idiot pace").

Your reply helped me out greatly and if you would care to EMail me your Paypal Account number

and the amount you think is fair I will compensate you for your help.

Thanks again :slight_smile: :slight_smile: