Can't change the values in a byte array once they are initialized

I am using a pair of Adafruit Feather M0 boards with an RFM9x LORA radio on each. I have installed the RadioHead rf95_reliable_datagram sketches on my boards and they will communicate back and forth with each other with the stock sketches.

I want to be able to send a different byte array from the client to the server depending upon the state of a switch. The end goal is to turn a device at the server end off or on.

So I have tried to modify the client code to transmit a message depending upon the switch status but I never see the message change when I open or close the switch. I added debug print statements to my if(switch) code and I can see that the switch changes are actually being read but the message being sent does not change. I watch what the server has received to see if the message changes.

In the code below you can see that I declare and initialize the byte array

uint8_t data[11] = "Arduino";

In the main program loop. I then try to change the contents of the array in my if(switch) code.

  if(switch_state == 0) {
    uint8_t data[11] = ("Switch Off");
    Serial.println("Switch Off");
  }
  else {
    uint8_t data[11] = ("Switch On ");
    Serial.println("Switch On");
  }
No mater what I do I always see the "Arduino" text being received at the server.  It seems like the byte is a constant instead of a variable?  Any ideas or help would be greatly appreciated.  Thanks in advance.



// rf95_reliable_datagram_client.ino
// -*- 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 

#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
  // Required for Serial on Zero based boards
  #define Serial SERIAL_PORT_USBVIRTUAL
#endif

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

#define CLIENT_ADDRESS 1
#define SERVER_ADDRESS 2

// Singleton instance of the radio driver
RH_RF95 driver(8,3);                          //AdaFruit Feather M0 with the RFM95W                       

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

unsigned short int switch_state;

void setup() 
{
   
  pinMode(13, OUTPUT);                // Make LED pin an output
  digitalWrite(13, LOW);               // Start with LED OFF

  pinMode(10, INPUT_PULLUP);
  
  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
  driver.setFrequency(915.0);

  // 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(13, false);

  // You can optionally require this module to wait until Channel Activity
  // Detection shows no activity on the channel before transmitting by setting
  // the CAD timeout to non-zero:
//  driver.setCADTimeout(10000);
}

void loop()
{
  digitalWrite(13, HIGH);                                           // LED ON
  delay(1000);

  Serial.println("* Sending to rf95_reliable_datagram_server *");   

  switch_state = digitalRead(10);

  uint8_t data[11] = "Arduino";

  if(switch_state == 0) {
    uint8_t data[11] = ("Switch Off");
    Serial.println("Switch Off");
  }
  else {
    uint8_t data[11] = ("Switch On ");
    Serial.println("Switch On");
  }

  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];                             // Dont put this on the stack: 

  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))       // Send a message to manager_server
  {
    // 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);
      digitalWrite(13, LOW);                                            // LED OFF
    }
    else
    {
      Serial.println("No reply, is rf95_reliable_datagram_server running?");
    }
  }
  else
    Serial.println("sendtoWait failed");
  delay(500);
}

Every time you started calling array from the data type, for example

uint8_t data[]....

you declare the new array rather than change the contains of the previosly defined.
This new arrays are local to switch statements and disappear once you leave the code block. So every time you send the data array - you send the same unmodified data with text "Arduino"
Also note, that in C language assigning array to string is supported only in initialization time. Once array defined, you cant assign a whole string to it, you can only change letter by letter or use strcpy command

Try this
Declare the array as a global but use the data type char

char data[11] = "Arduino";

To change data in the array later do this

strcpy(data, "Switch off");
Serial.println(data);

Be careful with the length of the string that you copy into the array because space is require for the hidden zero that terminates the string

1 Like

Thank you for such a fast reply. Thanks for getting me to think outside the rut that I was stuck in and onto the right path. I have it working now (at last) and I can proceed with my project.

My data from the client as received at the server.

got request from : 0x1: Switch Off
got request from : 0x1: Switch Off
got request from : 0x1: Switch On
got request from : 0x1: Switch On
got request from : 0x1: Switch On
got request from : 0x1: Switch Off

It made no sense to me to do it that way but I didn't get a compiler error so I tried it. What can I say, now I know better. In fact I know of a lot of things that didn't work. :slightly_smiling_face:

Here is the code snippet that does work for me.

 Serial.println("* Sending to rf95_reliable_datagram_server *");   

  byte data[12];                                                    // declare the byte array
  String s0 = "Switch Off";                                         // init string 0 
  String s1 = "Switch On ";                                         // init string s1

  if(switch_state == 0) {
    s0.getBytes(data, 11);
    Serial.println("Switch Off");                                   // debug serial out
  }
  else {
    s1.getBytes(data, 11); 
    Serial.println("Switch On");                                    // debug serial out
  }
  
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];                             // Dont put this on the stack: 

  if (manager.sendtoWait(data, sizeof(data), SERVER_ADDRESS))       // Send a message to manager_server

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