Send String via Bluetooth

Hi, I am trying to send a string with a mixture of text and numbers from 1 Arduino to another and wondering how I can go about doing this...

I currently have a Nextion Screen where i use buttons and sliders to get my values, this is connected to Serial1 on my Arduino Mega.

  if(Serial1.available()) {
    char character = "";
    String data_from_display = "";
    delay(30);

    while(Serial1.available()) {
      character = char(Serial1.read());
      data_from_display += character;
    }

The string format arrives fine from here in the format of 2 letters and 5 numbers.

I then use the second letter to determine if it needs to be sent via Bluetooth using substring

if(data_from_display.substring(1,2) == "S") {      //Check if 2nd Letter is "S"

The next part is what i am having troubles with, passing on the string via Bluetooth...

If i use this my Arduino Nano just receives a letter Y:

Serial2.write(data_from_display);

if I try .print it sends nothing across.

I'm not sure we can see your code

which code cant you see?

    // *** Check What to do with data ***
    if(data_from_display.substring(1,2) == "S") { 
      Serial2.write(data_from_display);               //Send to Bluetooth
    } 

Nextion Editor Debug:

For Receiving Arduino Nano code i have:

  if(Serial1.available()) {
    String data_from_master = "";
    data_from_master = Serial1.read();
    Serial.print(data_from_master);    //See data on PC
  }   

If you persist in posting snippets of code, snippets of help are what you are likely to receive.

Read the forum guidelines.

Post the whole code

Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

All of it.
But, by all means, keep bumping your post count

@Ralphyboy
If you are using a Nextion start here:

There are examples that do pretty much what I think you are trying to do (although I'm not entirely clear what you are doing).

I Have 2 LED Strips attached to An Arduino Nano on the other end, the data i am sending over is what will change the settings, Colour, Cycle Speed and if just on, cycling or pulsing.

Here is the code i have for My Receiving Arduino:

// *** Libraries ***
#include <FastLED.h>
#include <Wire.h>

// *** Setup LEDs ***
#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 24
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];

// *** Startup Speed / Colour / Program ***
int CRedValue = 255;
int CGreenValue = 255;
int CBlueValue = 255;
int SRedValue = 0;
int SGreenValue = 255;
int SBlueValue = 0;
int cycleSpeed = 100;
String cabinetProg = "On";
String shelfProg = "Cycle";
String shelfState = "On";
String cabinetState = "On";


void setup() {

  //*** Setup Serial ***
  Serial.begin(9600);  //PC
  Serial1.begin(9600); //Bluetooth


  // *** Setup LEDs ***
  FastLED.addLeds<NEOPIXEL, 2>(leds[0], NUM_LEDS_PER_STRIP); // No. LEDs on pin 2
  FastLED.addLeds<NEOPIXEL, 4>(leds[1], 18); // No. LEDs on pin 4

  // *** Set Cabinet lights to on and white ***
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[1][i] = CRGB::White;
    FastLED.show();
  }

}

void loop() {

  // *** Get Bluetooth Data ***
  HMI_read();

  // *** Cabinet Program ***
  if (cabinetProg == "Pulse" && cabinetState == "On") { //Pulse Loop

    // *** Set Cabinet lights to Pulse and white ***
    for (int i = 255; i > 0; i--) {
      setWhite(i);
      delay(10);
    }

    for (int i = 0; i < 256; i++) {
      setWhite(i);
    } delay(10);

  } else if (cabinetProg == "On" && cabinetState == "On") { //On

    // *** Set Cabinet lights to on and white ***
    for (int i = 0; i < 18; i++) {        // This loop will go over each led one at a time
      leds[1][i] = CRGB(CRedValue, CBlueValue, CGreenValue);
      FastLED.show();
    }

  } else {

    // *** Set Cabinet lights to off ***
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
      leds[1][i] = CRGB::Black;
      FastLED.show();
    }

  }


  // *** Unit/Display Program ***
  if (shelfProg == "Cycle" && shelfState == "On") { //Cycle Loop

    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {        // This loop will go over each led one at a time

      // *** Get Bluetooth Data ***
      HMI_read();

      // *** Display LED ***
      leds[0][i] = CRGB(SRedValue, SBlueValue, SGreenValue); //Set Selected Colour
      FastLED.show();
      leds[0][i] = CRGB::Black;
      delay(cycleSpeed); // Selected Delay

    }

  } else if (shelfProg == "On" && shelfState == "On") { //On

    // *** Set Unit lights to on***
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {        // This loop will go over each led one at a time
      leds[0][i] = CRGB(SRedValue, SBlueValue, SGreenValue); //Set Selected Colour
      FastLED.show();
    }

  } else {

    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
      leds[0][i] = CRGB::Black;
      FastLED.show();
    }

  }

}

//Pulse Program
void setWhite(int val) {
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[1][i] = CRGB(val, val, val);
  }

  FastLED.show();

}

// *** Read Data From Master ***
void HMI_read() {

  if (Serial1.available()) {
    String data_from_master = "";
    data_from_master = Serial1.read();

    //Debug
    Serial.print("Code: ");
    Serial.print(data_from_master);
    Serial.print("  |  Location: ");
    Serial.print(data_from_master.substring(1, 2)); // U or S
    Serial.print("  |  Format: ");
    Serial.print(data_from_master.substring(0, 3)); // SU0, RU0, etc.
    Serial.print("  |  Value: ");
    Serial.println(data_from_master.substring(4, 7)); // 0-255

    //Format of Incoming String "AA00000" - 1st Letter for Object, 2nd For Area,1st Number for On/Off or switch & Last 3 Numbers for value.

    // *** Shelf Speed ***
    if (data_from_master.substring(0, 2) == "SS") {
      cycleSpeed = data_from_master.substring(5, 7).toInt();  //Check Start of string for Delay Slider Data ("SS")
    }


    // *** Shelf Colour ***
    if (data_from_master.substring(0, 3) == "RS0") {
      SRedValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Red Slider Data ("RS0")
    }
    if (data_from_master.substring(0, 3) == "GS0") {
      SGreenValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Green Slider Data ("GS0")
    }
    if (data_from_master.substring(0, 3) == "BS0") {
      SBlueValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Blue Slider Data ("BS0")
    }


    // *** Cabinet Colour ***
    if (data_from_master.substring(0, 3) == "RS1") {
      CRedValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Red Slider Data ("RS1")
    }
    if (data_from_master.substring(0, 3) == "GS1") {
      CGreenValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Green Slider Data ("GS1")
    }
    if (data_from_master.substring(0, 3) == "BS1") {
      CBlueValue = data_from_master.substring(4, 7).toInt();  //Check Start of string for Blue Slider Data ("BS1")
    }



    // *** Cabinet Program ***
    if (data_from_master == "PS00002") {                              //Check string for Off Pulse Radio Data ("Pulse")
      cabinetProg = "Pulse";
      cabinetState = "Off";
    }

    if (data_from_master == "PS00001") {                              //Check string for Off Pulse Radio Data ("On")
      cabinetProg = "On";
      cabinetState = "Off";
    }

    if (data_from_master == "PS10002") {                              //Check string for On Pulse Radio Data ("Pulse")
      cabinetProg = "Pulse";
      cabinetState = "On";
    }

    if (data_from_master == "PS10001") {                              //Check string for On Pulse Radio Data ("On")
      cabinetProg = "On";
      cabinetState = "On";
    }


    // *** Shelves Program ***
    if (data_from_master == "CS00002") {                              //Check string for Off Cycle Radio Data ("Cycle")
      shelfProg = "Cycle";
      shelfState = "Off";
    }

    if (data_from_master == "CS00001") {                              //Check string for Off Cycle Radio Data ("On")
      shelfProg = "On";
      shelfState = "Off";
    }

    if (data_from_master == "CS10002") {                              //Check string for On Cycle Radio Data ("Cycle")
      shelfProg = "Cycle";
      shelfState = "On";
    }

    if (data_from_master == "CS10001") {                              //Check string for On Cycle Radio Data ("On")
      shelfProg = "On";
      shelfState = "On";
    }

  }

}

And this is the code i have for the Arduino Mega (also with 2 LED strips), that receives the data from the screen, I have tested the data from screen and that works fine, ist just passing on via bluetooth

// *** Libraries ***
#include <FastLED.h>
#include <Wire.h>

// *** Setup LEDs ***
#define NUM_STRIPS 2
#define NUM_LEDS_PER_STRIP 32
CRGB leds[NUM_STRIPS][NUM_LEDS_PER_STRIP];

// *** Startup Speed / Colour / Program ***
int URedValue = 0;
int UGreenValue = 255;
int UBlueValue = 0;
int CRedValue = 255;
int CGreenValue = 255;
int CBlueValue = 255;
int cycleSpeed = 100;
String cabinetProg = "On";
String unitProg = "Cycle";
String cabinetState = "On";
String unitState = "On";


void setup() {

  //*** Setup Monitor ***
  Serial.begin(9600);   //PC
  Serial1.begin(9600);  //Monitor
  Serial2.begin(9600);  //Bluetooth


  // *** Setup LEDs ***
  FastLED.addLeds<NEOPIXEL, 2>(leds[0], 32); // No. LEDs on pin 2 (TV Display = 32, Sofa Shelf = 24)
  FastLED.addLeds<NEOPIXEL, 4>(leds[1], 18); // No. LEDs on pin 4 (TV Cabinet & Sofa Cabinet = 18)

  // *** Set Cabinet lights to on and white ***
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[1][i] = CRGB::White;
    FastLED.show();
  }

}

void loop() {

  //*** Read LED Program ***
  HMI_read();                                         // Call Read_LED_Data to check for a change between Loops

  // *** Update Time ***
  //clock_run();


  // *** Cabinet Program ***
  if (cabinetProg == "Pulse" && cabinetState == "On") { //Pulse Loop

    // *** Set Cabinet lights to Pulse and white ***
    for (int i = 255; i > 0; i--) {
      setWhite(i);
      delay(10);
    }

    for (int i = 0; i < 256; i++) {
      setWhite(i);
    } delay(10);

  } else if (cabinetProg == "On" && cabinetState == "On") { //On

    // *** Set Cabinet lights to on and white ***
    for (int i = 0; i < 18; i++) {        // This loop will go over each led one at a time
      leds[1][i] = CRGB(CRedValue, CBlueValue, CGreenValue);
      FastLED.show();
    }

  } else {

    // *** Set Cabinet lights to off ***
    for (int i = 0; i < 18; i++) {        // This loop will go over each led one at a time
      leds[1][i] = CRGB::Black;
      FastLED.show();

    }

  }


  // *** Unit/Display Program ***
  if (unitProg == "Cycle" && unitState == "On") { //Cycle Loop

    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {        // This loop will go over each led one at a time

      //*** Read Display Data ***
      HMI_read();                                         // Call Read_LED_Data to check for a change between LEDs

      // *** Update Time ***
      //clock_run();

      // *** Display LED ***
      leds[0][i] = CRGB(URedValue, UBlueValue, UGreenValue); //Set Selected Colour
      FastLED.show();
      leds[0][i] = CRGB::Black;
      delay(cycleSpeed); // Selected Delay

    }

  } else if (unitProg == "On" && unitState == "On") { //On

    // *** Set Unit lights to on***
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {        // This loop will go over each led one at a time
      leds[0][i] = CRGB(URedValue, UBlueValue, UGreenValue); //Set Selected Colour
      FastLED.show();
    }

  } else {

    // *** Set Unit lights to off***
    for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {        // This loop will go over each led one at a time
      leds[0][i] = CRGB::Black;
      FastLED.show();
    }

  }

}


// *** Read Data From Screen ***
void HMI_read() {

  if (Serial1.available()) {
    char character = "";
    String data_from_display = "";
    delay(30);

    while (Serial1.available()) {
      character = char(Serial1.read());
      data_from_display += character;
    }

    //Debug
    Serial.print("Code: ");
    Serial.print(data_from_display);
    Serial.print("  |  Location: ");
    Serial.print(data_from_display.substring(1, 2)); // U or S
    Serial.print("  |  Format: ");
    Serial.print(data_from_display.substring(0, 3)); // SU0, RU0, etc.
    Serial.print("  |  Value: ");
    Serial.println(data_from_display.substring(4, 7)); // 0-255


    //Format of Incoming String "AA00000" - 1st Letter for Object, 2nd For Area,1st Number for On/Off or switch & Last 3 Numbers for value.

    // *** Check What to do with data ***
    if (data_from_display.substring(1, 2) == "S") {
      Serial2.write('data_from_display');                                  //Send to Bluetooth

    } else {

      // *** Shelf Speed ***
      if (data_from_display.substring(0, 3) == "SU0") {                   //Check Start of string for Delay Slider Data ("SU")
        cycleSpeed = data_from_display.substring(4, 7).toInt();          //Convert Rest of string to Numerical Value
      }


      // *** Shelf Colour ***
      if (data_from_display.substring(0, 3) == "RU0") {                  //Check Start of string for Red Slider Data ("RU0")
        URedValue = data_from_display.substring(4, 7).toInt();           //Convert Rest of string to Numerical Value
      }

      if (data_from_display.substring(0, 3) == "GU0") {                  //Check Start of string for Green Slider Data ("GU0")
        UGreenValue = data_from_display.substring(4, 7).toInt();         //Convert Rest of string to Numerical Value
      }

      if (data_from_display.substring(0, 3) == "BU0") {                  //Check Start of string for Blue Slider Data ("BU0")
        UBlueValue = data_from_display.substring(4, 7).toInt();          //Convert Rest of string to Numerical Value
      }

      // *** Cabinet Colour ***
      if (data_from_display.substring(0, 3) == "RU1") {                  //Check Start of string for Red Slider Data ("RU1")
        CRedValue = data_from_display.substring(4, 7).toInt();           //Convert Rest of string to Numerical Value
      }

      if (data_from_display.substring(0, 3) == "GU1") {                  //Check Start of string for Green Slider Data ("GU1")
        CGreenValue = data_from_display.substring(4, 7).toInt();         //Convert Rest of string to Numerical Value
      }

      if (data_from_display.substring(0, 3) == "BU1") {                  //Check Start of string for Blue Slider Data ("BU1")
        CBlueValue = data_from_display.substring(4, 7).toInt();          //Convert Rest of string to Numerical Value
      }


      // *** Cabinet Program ***
      if (data_from_display == "PU00002") {                              //Check string for Off Pulse Radio Data ("Pulse")
        cabinetProg = "Pulse";
        cabinetState = "Off";
      }

      if (data_from_display == "PU00001") {                              //Check string for Off Pulse Radio Data ("On")
        cabinetProg = "On";
        cabinetState = "Off";
      }

      if (data_from_display == "PU10002") {                              //Check string for On Pulse Radio Data ("Pulse")
        cabinetProg = "Pulse";
        cabinetState = "On";
      }

      if (data_from_display == "PU10001") {                              //Check string for On Pulse Radio Data ("On")
        cabinetProg = "On";
        cabinetState = "On";
      }


      // *** Unit Program ***
      if (data_from_display == "CU00002") {                              //Check string for Off Cycle Radio Data ("Cycle")
        unitProg = "Cycle";
        unitState = "Off";
      }

      if (data_from_display == "CU00001") {                              //Check string for Off Cycle Radio Data ("On")
        unitProg = "On";
        unitState = "Off";
      }

      if (data_from_display == "CU10002") {                              //Check string for On Cycle Radio Data ("Cycle")
        unitProg = "Cycle";
        unitState = "On";
      }

      if (data_from_display == "CU10001") {                              //Check string for On Cycle Radio Data ("On")
        unitProg = "On";
        unitState = "On";
      }

    }

  }

}

//*** Runtime ***
struct CLOCK {
  int8_t hour;
  int8_t minute;
  int8_t second;
};

struct CLOCK clock;

void HMI_display_clock() {
  char timestring[9];
  sprintf(timestring, "%02d:%02d:%02d ", clock.hour, clock.minute, clock.second);
  Serial1.print(F("t1.txt=\""));
  Serial1.print(timestring);
  Serial1.print("\"");
  Serial1.write(0xff);
  Serial1.write(0xff);
  Serial1.write(0xff);
}

void clock_run() {
  static unsigned long previousMillis;
  unsigned long currentMillis = millis();
  const unsigned long interval = 1000;
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    ++clock.second;
    if (clock.second > 59) {
      clock.second = 0;
      ++clock.minute;
      if (clock.minute > 59) {
        clock.minute = 0;
        ++clock.hour;
        if (clock.hour > 23) {
          clock.hour = 0;
        }
      }
    }
    HMI_display_clock();
  }
}

void setWhite(int val) {
  for (int i = 0; i < NUM_LEDS_PER_STRIP; i++) {
    leds[1][i] = CRGB(val, val, val);
  }

  FastLED.show();

}

Try adding a \n terminator to the sending side and then replacing that section with this from my Arduino Software Solutions
There are other Serial read functions there also with their pros and cons

// read Serial until until_c char found, returns true when found else false
// non-blocking, until_c is returned as last char in String, updates input String with chars read
bool readStringUntil(String& input, char until_c) {
  while (Serial1.available()) {
    char c = Serial1.read();
    input += c;
    if (c == until_c) {
      return true;
    }
  }
  return false;
}
void loop() {
  if (readStringUntil(data_from_display, '\n')) { // read until find newline  non-blocking
    Serial.print(F(" got a line of input '")); Serial.print(input); Serial.println("'");
// add your parsing code here
    data_from_display = ""; // clear after processing for next line
  }
// other loop stuff here
}

Notice the reading and String assembly code you use successfully on the Mega.

if (Serial1.available()) {
    char character = "";
    String data_from_display = "";
    delay(30);

    while (Serial1.available()) {
      character = char(Serial1.read());
      data_from_display += character;
    }

The code on the Nano is not going to assemble a String.

if (Serial1.available()) {
    String data_from_master = "";
    data_from_master = Serial1.read();

Do you see and understand the difference?

@cattledog When i tried the same code on the Nano that worked with the Mega i just got a Y value:

is that something to do with the way its sent between the two?

Why are you using this code on the mega to send the message?

Serial2.write('data_from_display');

First, I don't understand the single quote marks.

What happens if you use
Serial2.print(data_from_display)

data_from_display is a String object, and .write() does not take a String object as a parameter.

If you must use the .write() for some reason, try
Serial2.write(data_from_display.c_str(), data_from_display.length());

@cattledog I was obviously getting the wrong combinations when doing print and write, as thought originally tried that.
But its all working now:

Thanks for the help :partying_face: