String or char array Problems

I am not sure what question to ask. Should I work with perhaps with strings?

I am sending a string from one node to another and am doing this on the send side:

MY procedure call:

sendMessage ("BlinkLED");

My procedure:

void sendMessage (char message[])
{
radio.sendWithRetry(TONODEID, message, sizeof(message))
}

The receive side is not getting the message correctly unless I enter the number "8" in place of
"sizeof(message))".

Once I have the message on receive side, I need to see if the string or char array contains "BlinkLED"
and then it blinks it.

You have also neglected to post the warning message your compiler is giving you because because "BlinkLED" is not a char array.

"BlinkLED" is 8, why are you substituting 5?

Try changing sendMessage("BlinkLED"); to sendMessage((char *)"BlinkLED");

You are missing a semicolon at the end of "radio.send...". If that is not the problem, try this:

void sendMessage (char *message)
{
    radio.sendWithRetry(TONODEID, message, strlen(message));
}

sendMessage("The Message");

"sizeof" will (at least) return 9 for "BlinkLED", "strlen" will return 8.

adwsystems:
You have also neglected to post the warning message your compiler is giving you because because "BlinkLED" is not a char array.

"BlinkLED" is 8, why are you substituting 5?

Try changing sendMessage("BlinkLED"); to sendMessage((char *)"BlinkLED");

I typed "5" instead of "8" by mistake. Sorry.

I tried your suggested change.

This is the result on the serial monitor of both nodes:

sending to node 1, message [144-2-SOA]
ACK received!

received from node 2, message [], RSSI -26
ACK sent

"BlinkLED" is 8, why are you substituting 5?

sizeof("BlinkLED");

Returns 9 not 8 because of the terminating zero so anything depending on the length is likely to have problems.

You need to post ALL of the code for each end. The problem may not be on the sending end, like you assume.

Thanks so much everyone for the replies.

I seems I was doing things wrong on both the send and receive ends.

The following is send code that is working:

void sendMessage(char message[])
{ 
  // Send the packet!

      Serial.print("sending to node ");
      Serial.print(TONODEID, DEC);
      Serial.print(", message [");
      Serial.print (message);
      Serial.println("]");      

        if (radio.sendWithRetry(TONODEID, message, strlen(message)))        
        {
          Serial.println("ACK received!");          
        }
        else
        {
          Serial.println("no ACK received");
        }
      
      
}

This is working receive code:

if (radio.receiveDone()) // Got one!
  {
    // Print out the information:

    Serial.print("received from node ");
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");

    // The actual message is contained in the DATA array,
    // and is DATALEN bytes in size:
    String recMessage = "";
    for (byte i = 0; i < radio.DATALEN; i++)
    {
      //Serial.print((char)radio.DATA[i]);
      //recMessage[i] = (char)radio.DATA[i];
      recMessage += (char)radio.DATA[i];
    }
    
    Serial.print (recMessage);
    
    // RSSI is the "Receive Signal Strength Indicator",
    // smaller numbers mean higher power.    
    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);

    if (radio.ACKRequested())
    {
      radio.sendACK();
      Serial.println("ACK sent");
    }
    
    // turn on and indicator LED
    if(recMessage.indexOf("SOA") > 0)
    {
      digitalWrite (7, HIGH);
    }        
  } // End if (radio.receiveDone()) // Got one!

Can you make any additional suggestions?
Should I try to use just Strings or char arrays for example?

What sort of wireless are you using?

If you had posted the complete program we would know.

...R

Robin2:
What sort of wireless are you using?

If you had posted the complete program we would know.

...R

RFM69HCW

So, you're really not going to post the complete code? Guess you don't need help THAT much.

gfvalvo:
So, you're really not going to post the complete code? Guess you don't need help THAT much.

LOL. This is what I have so far. Parts are incomplete.

For the sender:

// RFM69HCW Example Sketch
//
//Node 1 using:
//// Set Tools/Board menu to Arduino Uno
//
// NODE 2 using:
// Set Tools/Board menu to Arduino Pro or Pro Mini
// Set Tools/Processor to ATmega328 (3.3V, 8MHz)
//

#include <RFM69.h>
#include <SPI.h>


// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     144   // Must be the same for all nodes
#define MYNODEID      2   // My node ID
#define TONODEID      1   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:
//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// AES encryption (or not):
#define ENCRYPT       true // Set to "true" to use encryption
//#define ENCRYPT       false // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):
#define USEACK        true // Request ACKs or not

// Packet sent/received indicator LED (optional):
#define LED           9 // LED positive pin
#define GND           8 // LED ground pin

// Create a library object for our RFM69HCW module:
RFM69 radio;

bool presentAlarmSwitchState = false;
bool previousAlarmSwitchState = false;
bool presentResetSwitchState = false;
bool previousResetSwitchState = false;


void setup()
{
  // Open a serial port so we can send keystrokes to the module:
  Serial.begin(9600);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");  

  // Set up the transmit indicator LED (optional):
  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);
  
  // ******************
  // activated when it goes high
  pinMode (7,INPUT_PULLUP);
  pinMode (6, INPUT_PULLUP);
  
  // set up the state LED optional:
  pinMode (5,OUTPUT); // LED plus
  digitalWrite (5,LOW);
  pinMode (4,OUTPUT);
  digitalWrite (4,LOW);
  // **************

  // Initialize the RFM69HCW:
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW

  // Turn on encryption if desired:
  if (ENCRYPT)
    radio.encrypt(ENCRYPTKEY);
}

void loop()
{  
  // detect present Alarm Switch State
  if (digitalRead(7) == HIGH)
  {
    delay (50);
    if (digitalRead(7) == HIGH)
    {      
        presentAlarmSwitchState = true;
    }
      else
      {
        presentAlarmSwitchState = false;
      }
  }
  else
  {
    presentAlarmSwitchState = false;
  }
      
  // detect a change in Alarm Switch state 
    if (presentAlarmSwitchState != previousAlarmSwitchState)
    {
      if (presentAlarmSwitchState == true)
      {
      //we have an alarm
      Serial.println ("ALARM OPEN");
      digitalWrite (5,HIGH);
      sendMessage("144-2-SOA");
      
      previousAlarmSwitchState = true;
      }    
      else
      {
      //we have no alarm
      Serial.println ("ALARM CLOSED");
      digitalWrite (5,LOW);
      previousAlarmSwitchState = false;
      }
    }
    
  // detect present Reset Switch State
  if (digitalRead(6) == LOW)
  {
    delay (50);
    if (digitalRead(6) == LOW)
    {      
        presentResetSwitchState = true;
    }
      else
      {
        presentResetSwitchState = false;
      }
  }      
    
  // detect a change in Reset Switch state 
    if (presentResetSwitchState != previousResetSwitchState)
    {
      if (presentResetSwitchState == true)
      {
      //we have a reset
      reset();
      }
      else
      {
        previousResetSwitchState = false;
      }      
    }
  

  // RECEIVING
  // In this section, we'll check with the RFM69HCW to see
  // if it has received any packets:

  if (radio.receiveDone()) // Got one!
  {
    // Print out the information:

    Serial.print("received from node ");
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");

    // The actual message is contained in the DATA array,
    // and is DATALEN bytes in size:

    for (byte i = 0; i < radio.DATALEN; i++)
      Serial.print((char)radio.DATA[i]);
      
      String recMessage = "";
      for (byte i = 0; i < radio.DATALEN; i++)
      recMessage[i] = (char)radio.DATA[i];
      

    // RSSI is the "Receive Signal Strength Indicator",
    // smaller numbers mean higher power.

    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);

    // Send an ACK if requested.
    // (You don't need this code if you're not using ACKs.)

    if (radio.ACKRequested())
    {
      radio.sendACK();
      Serial.println("ACK sent");
    }
    
    Blink(LED,10);    
    
    if(recMessage.indexOf("SI") > 0)
    {
      if (presentAlarmSwitchState == true)
      {
        sendMessage ("144-2-SO");
      }
      else
      {
        sendMessage ("144-2-SC");
      }
    } // End if(recMessage.indexOf("SI") > 0)
    
    if(recMessage.indexOf("SR") > 0)
    {
      reset();
    }
    
  } // End if (radio.receiveDone()) // Got one!
  
}  // End void loop()

// Methods **************************************

void reset()
{
  Serial.println ("RESET");
  previousResetSwitchState = true; 
  presentResetSwitchState = false;  
  presentAlarmSwitchState = false;  
  previousAlarmSwitchState = false;  
}

void sendMessage(char message[])
{ 
  // Send the packet!

      Serial.print("sending to node ");
      Serial.print(TONODEID, DEC);
      Serial.print(", message [");
      Serial.print (message);
      Serial.println("]");      

        if (radio.sendWithRetry(TONODEID, message, strlen(message)))        
        {
          Serial.println("ACK received!");          
        }
        else
        {
          Serial.println("no ACK received");
        }
      
      Blink(LED,10);      
}

void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

Receiver code in next post.

recMessage[i] = (char)radio.DATA[i];

This statement has no effect.

For the receiver:

// RFM69HCW Example Sketch
//
//Node 1 using:
//// Set Tools/Board menu to Arduino Uno
//
// NODE 2 using:
// Set Tools/Board menu to Arduino Pro or Pro Mini
// Set Tools/Processor to ATmega328 (3.3V, 8MHz)
//


#include <RFM69.h>
#include <SPI.h>

// Addresses for this node. CHANGE THESE FOR EACH NODE!
#define NETWORKID     144   // Must be the same for all nodes
#define MYNODEID      1   // My node ID
#define TONODEID      2   // Destination node ID

// RFM69 frequency, uncomment the frequency of your module:
//#define FREQUENCY   RF69_433MHZ
#define FREQUENCY     RF69_915MHZ

// AES encryption (or not):
#define ENCRYPT       true // Set to "true" to use encryption
#define ENCRYPTKEY    "TOPSECRETPASSWRD" // Use the same 16-byte key on all nodes

// Use ACKnowledge when sending messages (or not):
#define USEACK        true // Request ACKs or not

// Packet sent/received indicator LED (optional):
#define LED           9 // LED positive pin
#define GND           8 // LED ground pin

// Create a library object for our RFM69HCW module:
RFM69 radio;

void setup()
{
  // Open a serial port so we can send keystrokes to the module:
  Serial.begin(9600);
  Serial.print("Node ");
  Serial.print(MYNODEID,DEC);
  Serial.println(" ready");  

  // Set up the indicator LED (optional):

  pinMode(LED,OUTPUT);
  digitalWrite(LED,LOW);
  pinMode(GND,OUTPUT);
  digitalWrite(GND,LOW);
  
  pinMode (7,OUTPUT);
  digitalWrite (7,LOW);

  // Initialize the RFM69HCW:
  radio.initialize(FREQUENCY, MYNODEID, NETWORKID);
  radio.setHighPower(); // Always use this for RFM69HCW

  // Turn on encryption if desired:
  if (ENCRYPT)
    radio.encrypt(ENCRYPTKEY);
}

void loop()
{
  // RECEIVING
  // In this section, we'll check with the RFM69HCW to see
  // if it has received any packets:

  if (radio.receiveDone()) // Got one!
  {
    // Print out the information:

    Serial.print("received from node ");
    Serial.print(radio.SENDERID, DEC);
    Serial.print(", message [");

    // The actual message is contained in the DATA array,
    // and is DATALEN bytes in size:
    String recMessage = "";
    
    for (byte i = 0; i < radio.DATALEN; i++)
    {
      recMessage += (char)radio.DATA[i];
    }
    
    Serial.print (recMessage);
    
    // RSSI is the "Receive Signal Strength Indicator",
    // smaller numbers mean higher power.    
    Serial.print("], RSSI ");
    Serial.println(radio.RSSI);

    if (radio.ACKRequested())
    {
      radio.sendACK();
      Serial.println("ACK sent");
    }
    Blink(LED,10);
    
    // turn on indicator LED on pin 7
    if(recMessage.indexOf("SOA") > 0)
    {
      digitalWrite (7, HIGH);
    }  
       
  } // End if (radio.receiveDone()) // Got one!
  
} // End void loop()


// Methods *****************************************


void Blink(byte PIN, int DELAY_MS)
// Blink an LED for a given number of ms
{
  digitalWrite(PIN,HIGH);
  delay(DELAY_MS);
  digitalWrite(PIN,LOW);
}

//******************************************************************
//***************************************************************
/*

// Set up a "buffer" for characters that we'll send:

  static char sendbuffer[62];
  static int sendlength = 0;

  // SENDING

  // In this section, we'll gather serial characters and
  // send them to the other node if we (1) get a carriage return,
  // or (2) the buffer is full (61 characters).

  // If there is any serial input, add it to the buffer:

if (Serial.available() > 0)
  {
    char input = Serial.read();

    if (input != '\r') // not a carriage return
    {
      sendbuffer[sendlength] = input;
      sendlength++;
    }

    // If the input is a carriage return, or the buffer is full:
    if ((input == '\r') || (sendlength == 61)) // CR or buffer full
    {
      // Send the packet!

      Serial.print("sending to node ");
      Serial.print(TONODEID, DEC);
      Serial.print(", message [");
      for (byte i = 0; i < sendlength; i++)
        Serial.print(sendbuffer[i]);
      Serial.println("]");

      // There are two ways to send packets. If you want
      // acknowledgements, use sendWithRetry():

      if (USEACK)
      {
        if (radio.sendWithRetry(TONODEID, sendbuffer, sendlength))
        //if (radio.sendWithRetry(TONODEID, sendbuffer, sendlength,5,10))  //me test
          Serial.println("ACK received!");
        else
          Serial.println("no ACK received");
      }

      // If you don't need acknowledgements, just use send():
      else // don't use ACK
      {
        radio.send(TONODEID, sendbuffer, sendlength);
      }

      sendlength = 0; // reset the packet
      Blink(LED,10);
    }
  }
*/

arduino_new:

recMessage[i] = (char)radio.DATA[i];

This statement has no effect.

It may be in a part of the code I have not addressed yet. Thanks. I will check.

For the receiver (node 1), if I use this code the serial output appears to be correct.

String recMessage = "";    
    for (byte i = 0; i < radio.DATALEN; i++)
    {
      recMessage += (char)radio.DATA[i];
    }

Output:

received from node 2, message [144-2-SOA], RSSI -36
ACK sent

With this code, it is not correct.

char recMessage[radio.DATALEN];    
    for (byte i = 0; i < radio.DATALEN; i++)
    {
      recMessage[i] = (char)radio.DATA[i];
    }

Output:

received from node 2, message [144-2-SOA ž], RSSI -36
ACK sent

Please comment.

When you send the message does it include the '\0' terminator?

gfvalvo:
When you send the message does it include the '\0' terminator?

It does not. The NULL terminator says when the stop reading the array. It is NOT sent.

OP, you MUST add the NULL terminator to the array. Best practices call for keeping the array NULL terminated at all times:

char recMessage[radio.DATALEN];   
    for (byte i = 0; i < radio.DATALEN; i++)
    {
      recMessage[i] = (char)radio.DATA[i];
      recMessage[i+1] = '\0'; // Add the NULL
    }

PaulS:
It does not. The NULL terminator says when the stop reading the array. It is NOT sent.

OP, you MUST add the NULL terminator to the array. Best practices call for keeping the array NULL terminated at all times:

char recMessage[radio.DATALEN];   

for (byte i = 0; i < radio.DATALEN; i++)
    {
      recMessage[i] = (char)radio.DATA[i];
      recMessage[i+1] = '\0'; // Add the NULL
    }

Got it. Thanks.

One thing I am wondering is if I should use Strings instead of char arrays throughout the program?

You should not.

gfvalvo:
You should not.

Thanks. I tend to agree thinking I will constantly converting back and forth.

Also, I will try sending the char array with the null terminator as part of the packet.
This will help save processing time on the receiver end of things.

Thinking this might work:

radio.sendWithRetry(TONODEID, message, strlen(message)+1)