Help with interfacing Arduino Uno with RAK811

The first step is to write code to read the sensor.

Then you can add the result from the sensor to the buffer[].

Hopefully this gets you going, I can knock up something later on this week if you can bare with me.

Sure, I’m looking forward this week.

https://github.com/ztfnky/sensorCode/blob/main/FlowmeterSimplestCode_withsource.ino

This is my sensor code.

I edited the previous answer to add the float conversion for you. This would a way to solve your problem.
Float -> char -> add another char with something you may want, like sensor name -> merge them -> print(buffer, hex)

Please, note the this is was added inside the RAK811.cpp file, you need to create your own function for this.

bool RAK811::rk_sendData(int port, char *datahex)
{
  // String command = "";
  command = "at+send=lora:" + (String)port + ":";// + datahex;
  // _serial1.println(command);

  float resistance = 123.45;
  char res[7];
  dtostrf(resistance, 6, 2, res);

  char hi[3] = {0};
  hi[0] = 'h';
  hi[1] = 'i';
  hi[2] = '\0';

  char buffer[strlen(hi) + strlen(res) + 1];
  sprintf(buffer, "%s:%s", hi, res);

  Serial.println(buffer);

  command = command;// + converter(teste);
  Serial.println(command);

  while (_serial.available())
  {
    _serial.read();
  }
  //_serial1.println(cmd);
  _serial.print(command);

  for(int i=0;i<(strlen(hi) + strlen(res) + 1);i++){
    _serial.print(buffer[i], HEX);
  }
  _serial.println("");


  delay(200);
  return true;
  
  //sendRawCommand(command);

  return true;  
}

Here is the TTN print of the received payload.

And the hex payload converted to ascii.

Whilst this does move things forward, it will have rendered the library specific only to this sensor.

The code should be put in the main ino and the hex string then passed to the rk_sendData.

Additionally, sending payloads as strings is considered wasteful - conversion to an integer (usually by multiplying by 10, 100 or 1000 etc as appropriate) and then byte packing / shifting is strongly encouraged. As far as the TTN forumites think, any other way is wrong, a heinous crime and bad for the network.

I definitely agree with @nmcc regarding floats. The best approach is to multiply it with 10, 100, etc. then do the conversion on the decoder side of the network server. It is just a simple javascript. But @SWoto’s code above can work as well and you can easily add char or string on your payload. However, if you are only going to send just float values, @nmcc advise is really recommended.

Sadly all too easy - I’ve yet to come across a really good reason for sending plain text in a LoRaWAN payload.

Conversely, I have a very messed up set of utilities I use to bit-pack so if, for example I only need 0-15, I only use 4 bits and the other 4 are used for another value - it handles all the fun of crossing byte boundaries. Perhaps I should clean it up and release it.

1 Like

I think with what i’m going to say I might be stepping outside the topic question, though I’m not sure because it is related with the replies. Mods, please correct me if I’m wrong.

@nmcc, @carlrowan, regarding the discussion about sending it as int or float and the usage of plain text, if you have three sensors (assume temperature, humidity and pressure) how would you send it with LoRaWAN? Three frames with the value as int, or try to fit it in a frame separated by some character?

No, no, no, no, never, ever. Never ever think like that again or the LoRaWAN SWAT team will visit.

That implies three transmissions - three times you use you battery.

Try? Do or do not, there is no try!

The LoRaWAN SWAT team won’t come for this, they just send the LoRaWAN police around to fine you 100 batteries - as this will add to battery burn.

OK, I’ll stop encouraging a search using the forum, TTN forum or Mistress Google and go for the direct answer using Arduino code:

#define PAYLOAD_SIZE  6

void setup() {

  Serial.begin(9600);
  Serial.println("LoRaWAN using RAK library payload demo");
  
  int data[PAYLOAD_SIZE]; //  binary data structure with enough bytes for the payload
  
  int temperature = 20;
  int humidity = 35;
  int pressure = 935;

/* This is where you get your readings
  // Get your readings
  temperature = getTheTemperature();
  humidity = getTheHumidity();
  pressure = getThePressure();
*/

  // Transfer to the binary data structure
  data[0] = highByte(temperature);
  data[1] = lowByte(temperature);
  data[2] = highByte(humidity);
  data[3] = lowByte(humidity);
  data[4] = highByte(pressure);
  data[5] = lowByte(pressure);

  // Convert to a HEX string
  String payload = "";
  for(int c = 0; c < PAYLOAD_SIZE; c++) {

    if(data[c] < 0x10) {  // If it is less that 10, we'll need to put the 0 in as the Arduino String function doesn't pad with leading 0's
        payload += '0';
    }
    
    payload += String(data[c], HEX);
    
  }

  payload.toUpperCase(); // Converts in place, just to add to new programmer confusion

  Serial.print("Payload as Hex string: ");
  Serial.println(payload);

  // RAKLoRa.rk_sendData(1, payload) // This is where we send the payload

  // Note, buffer is a reserved word in Arduino, so I don't use buffer, I use payload, but the RAK examples do, your mileage may vary

}

void loop() {
}

Scroll inside the above box to see it all

3 Likes

My understanding is that the Uno and 811 can only be connected by wires due to different voltages / pin mismatch. Correct?

Not sure what the alternatives are to wires but …

The alternative is to use a Pro Mini.

You can also convert Arduino Uno to 3.3v volts operation with some tweaking. Replace the 5V regulator with 3.3v and solder some jumper wires “here and there” on the board.

I did this before. However, the atmega328 will be out of specs at 3.3v when running at 16Mhz. It is somehow overclocked. But for quick testing, it works. In production, I wont recommend it.