Sending an array over the RFM69HCW between Arduinos

My son and I are working on a project where we need to send two variables wirelessly over two Adafruit RFM69HCW radios connecting one Arduino to another. We have used the Radio Head example code and library for RF69 client and the RF69 server and we have it working well for sending a string of characters between the two Arduinos. However, we want to be able to send a 1 or a 0 and a 1 or a 0 depending sensors status on one Arduino to the receiving one.

Our initial thought is to send an array from one to the other like this (0,1) or (1,0) or (0,0, or (1,1) depending on the status of the sensors on the other Arduino. However, we are new to programming and have not been able to send anything other than the characters. What do we need to change to be able to send the High or Low status of two sensors from one arduino to the other over the wireless radios?

I will attach the two codes we are using so far successfully for sending text from one to the other.

This is only our second time posting anything so please let me know if you need more information to help us.

Thanks

rf69_client.ino (1.42 KB)

rf69_server.ino (2.61 KB)

Unless the sketch is too large, it's better if you post your code, rather than attach it. When it's attached, we have to download it, create a folder then open your code in our IDE. And afterwards, the folder remains unless we navigate to the "Temp" folder and manually remove it. It's much easier to just view the code in your post.

Use code tags. The code tags make the code look

like this

when posting source code files. It makes it easier to read, and can be copied with a single mouse click. Also, if you don't do it, some of the character sequences in the code can be misinterpred by the forum code as italics or funny emoticons. The "Code: [Select]" feature allows someone to select the entire sketch so it can be easily copied and pasted into the IDE for testing. Code tags can also be inserted manually in the forum text using the code and /code metatags.

Why can't your variable be 0,1,2, or 3? This is binary equivalent to 0b00000000, 0b00000001, 0b00000010, 0b00000011 so there's your 4 combinations.

Thanks for the reply CrossRoads. This is a good idea. However, I can't get any variable to show up on the other side. I can only get the regular string text to show up. If I put a variable in the place of DATA[] on the client side, I either gets lots of random characters or I get blank space on the server side. I'm sure it is something simple I am missing in converting between data types, but I can't seem to locate it.

OPs code
rf69_client

#include <SPI.h>
#include <RH_RF69.h>

uint8_t dryerStatus = "0";
uint8_t washerStatus = "1";

uint8_t sendArray[2];

// Singleton instance of the radio driver
RH_RF69 rf69;
void setup()
{
  // Reset for wireless module
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  delay(100);
  digitalWrite(9, LOW);
  delay(100);

  Serial.begin(9600);

  rf69.init();

  rf69.setFrequency(915.0);

  rf69.setTxPower(20, true);

  // The encryption key has to be the same as the one in the server
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
                  };
  rf69.setEncryptionKey(key);

}

void loop()
{


  sendArray[0] = dryerStatus;
  sendArray[1] = washerStatus;


  Serial.println("Sending to rf69_server");
  // Send a message to rf69_server
  uint8_t data[] = "test";
  rf69.send(data, sizeof(data));

  Serial.print(data[0]);
  Serial.print(",");
  Serial.println(data[1]);




  rf69.waitPacketSent();
  // Now wait for a reply
  uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (rf69.waitAvailableTimeout(500))
  {
    // Should be a reply message for us now
    if (rf69.recv(buf, &len))
    {
      Serial.print("got reply: ");
      Serial.println((char*)buf);
    }
    else
    {
      Serial.println("recv failed");
    }
  }
  else
  {
    Serial.println("No reply, is rf69_server running?");
  }
  delay(400);

  delay(400);
}

rf69_server

// rf69_server.pde
// -*- mode: C++ -*-
// Example sketch showing how to create a simple messageing server
// with the RH_RF69 class. RH_RF69 class does not provide for addressing or
// reliability, so you should only use RH_RF69  if you do not need the higher
// level messaging abilities.
// It is designed to work with the other example rf69_client
// Demonstrates the use of AES encryption, setting the frequency and modem
// configuration.
// Tested on Moteino with RFM69 http://lowpowerlab.com/moteino/
// Tested on miniWireless with RFM69 www.anarduino.com/miniwireless
// Tested on Teensy 3.1 with RF69 on PJRC breakout board

#include <SPI.h>
#include <RH_RF69.h>

// Singleton instance of the radio driver
RH_RF69 rf69;
//RH_RF69 rf69(15, 16); // For RF69 on PJRC breakout board with Teensy 3.1
//RH_RF69 rf69(4, 2); // For MoteinoMEGA https://lowpowerlab.com/shop/moteinomega
//RH_RF69 rf69(8, 7); // Adafruit Feather 32u4

void setup()
{
  pinMode(9, OUTPUT);
  digitalWrite(9, HIGH);
  delay(100);
  digitalWrite(9, LOW);
  delay(100);

  Serial.begin(9600);
  if (!rf69.init())
    Serial.println("init failed");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(915.0))
    Serial.println("setFrequency failed");

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  rf69.setTxPower(14, true);

  // The encryption key has to be the same as the one in the client
  uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
                  };
  rf69.setEncryptionKey(key);

#if 0
  // For compat with RFM69 Struct_send
  rf69.setModemConfig(RH_RF69::GFSK_Rb250Fd250);
  rf69.setPreambleLength(3);
  uint8_t syncwords[] = { 0x2d, 0x64 };
  rf69.setSyncWords(syncwords, sizeof(syncwords));
  rf69.setEncryptionKey((uint8_t*)"thisIsEncryptKey");
#endif
}

void loop()
{
  if (rf69.available())
  {
    // Should be a message for us now
    uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf69.recv(buf, &len))
    {
      //      RH_RF69::printBuffer("request: ", buf, len);
      Serial.print("got request: ");
      Serial.println((char*)buf);
      //      Serial.print("RSSI: ");
      //      Serial.println(rf69.lastRssi(), DEC);

      // Send a reply
      uint8_t data[] = "And hello back to you";
      rf69.send(data, sizeof(data));
      rf69.waitPacketSent();
      Serial.println("Sent a reply");
    }
    else
    {
      Serial.println("recv failed");
    }
  }
}

You can add a function to process the reply from the server:

// Should be a reply message for us now
if (rf69.recv(buf, &len))
{
    Serial.print("got reply: ");
    Serial.println((char*)buf);
    // now do something with it here. For example call a function
    process_response(buf, len);
}
else
{
    Serial.println("recv failed");
}

And then inside the 'process_response' function

void process_response(const char* buf, uint8_t len)
{
    if(strncmp(buf, "00", 2) == 0) {
       Serial.println("Hey, the server sent me '00'");
    }
}

Or something like this...

Thanks for the reply CrossRoads. This is a good idea. However, I can't get any variable to show up on the other side. I can only get the regular string text to show up.

Are you saying that you can send and receive the word "test"

Serial.println("Sending to rf69_server");
  // Send a message to rf69_server
  uint8_t data[] = "test";
  rf69.send(data, sizeof(data));

But that you can't send and received the character "1" with this?

Serial.println("Sending to rf69_server");
  // Send a message to rf69_server
  uint8_t data[] = "1";
  rf69.send(data, sizeof(data));

Thanks all!

Cattledog, I am pretty new to Arduino programming. Yes, I can get a "1" to come through, but I want to be able to monitor two variables from the client arduino. Specifically we want to send a HIGH or LOW if a dryer is on and a HIGH or LOW if a washer is on and have a receiver Arduino three floors up turn on or off an LED respectively if they are running.

Is there a way to do this with what is already working?

Cattledog, I am pretty new to Arduino programming. Yes, I can get a "1" to come through, but I want to be able to monitor two variables from the client arduino. Specifically we want to send a HIGH or LOW if a dryer is on and a HIGH or LOW if a washer is on and have a receiver Arduino three floors up turn on or off an LED respectively if they are running.

Crossroads told you how to do this by sending "0" or "1" or "2" or "3" as you can interpret them at the receiving end as 0,0 or 0,1 or 1,0 or 1,1.

If you actually want to send the data as characters you can send(for example) "1,0" or "1,1" and parse the character string at the receiving end.

Sending a numerical byte array, or any type data in an array or struct, is slightly more complex and can certainly be done but is harder to debug. Let me know if you really want to go there.

Thanks for all the fast help, all! We are making progress by using your suggestions for sending different strings depending on the status. Here's what we are doing so far. The other end is reading it just fine. Next we will set up if statements on the receiving end to light different LEDs and trigger a sound alarm.

  char data[20] = "Status: ";
  if (dryerStatus == LOW && washerStatus == LOW) data[8] = '1';
  if (dryerStatus == LOW && washerStatus == HIGH) data[8] = '2';
  if (dryerStatus == HIGH && washerStatus == LOW) data[8] = '3';
  if (dryerStatus == HIGH && washerStatus == HIGH) data[8] = '4';

  Serial.println(data[8]);

  Serial.println("Sending to rf69_server");
  // Send a message to rf69_server
  rf69.send(data, sizeof(data));