Serial Communications and ASCII to Integer Values

The setup:

I have 2 Bluno Beetles connected via bluetooth to each other. One is connected to an LCD, 2 temp sensors, and buttons and is the Master and is sending 4 variables to the other Bluno Beetle. The Slave Bluno Beetle is taking the incoming serial data from the Master and displaying it to the serial monitor.

Problem:
The data only shows up as ASCII characters. I need integer values so that the slave can make changes depending on the values. Changes will be made in future versions and for now I just need integer variables to work with. Essentially the variables are 2 temperature setpoints and 2 temperature readings. So they will all change over time depending on the user preferences.

Slave Code that essentially is just a copy from the Serial Input Basics page found here: Serial Input Basics - updated - Introductory Tutorials - Arduino Forum

// Example 3 - Receive with start- and end-markers

const byte numChars = 32;
char receivedChars[numChars];

boolean newData = false;



void setup() {
  Serial.begin(115200);
  Serial.println("<Arduino is ready>");
}

void loop() {
  recvWithStartEndMarkers();
  showNewData();
  delay(1000);
}

void recvWithStartEndMarkers() {
  static boolean recvInProgress = false;
  static byte ndx = 0;
  char startMarker = '<';
  char endMarker = '>';
  char rc;

  while (Serial.available() > 0 && newData == false) {
    rc = Serial.read();

    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        if (ndx >= numChars) {
          ndx = numChars - 1;
        }
      }
      else {
        receivedChars[ndx] = '\0'; // terminate the string
        recvInProgress = false;
        ndx = 0;
        newData = true;
      }
    }

    else if (rc == startMarker) {
      recvInProgress = true;
    }
  }
}

void showNewData() {
  if (newData == true) {
    Serial.print("This just in ... ");
    Serial.println(receivedChars);
    newData = false;
  }
}

Master Code...this isn't all of the master code. Just the part that is sending the data.

  if (Serial.available())
  {

    Serial.write('<');
    Serial.write(heat_setpointF);
    Serial.write(','); 
    Serial.write(cold_setpointF);
    Serial.write(','); 
    Serial.write(tank_temp22);
    Serial.write(','); 
    Serial.write(cold_combined22);
    Serial.write('>');
    delay(10);

   

  }

What I see on the Slave Bluno Beetle serial Monitor:

10:47:57.854 -> This just in ... ⸮,N,Q,Q

It should be 200,78,81,81 but all I get is ASCII characters.

I tried to modify example 5 from the Serial Input Basics page but it would only display the string value and no integers.

Any help would be greatly appreciated. FYI I am still fairly new to programming and especially working with serial/ASCII data.

So you have both the Bluetooth modules and the serial monitor connected to the same serial port? That does not always work well. I am not at all familiar with the Bluno Beetle boards. When I use Bluetooth with Uno boards I use software serial for the Bluetooth module and hardware serial for the program upload, debugging and monitoring program flow.

Here is example 5 modified to receive your data. Modify the following code to suit.

// Example 5 - Receive with start- and end-markers combined with parsing
#include <SoftwareSerial.h>

SoftwareSerial ss(4, 7);

const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];        // temporary array for use when parsing

// variables to hold the parsed data

int heat_setpointF = 0;
int cold_setpointF = 0;
int tank_temp22 = 0;
int cold_combined22 = 0;


boolean newData = false;

//============

void setup()
{
   Serial.begin(115200);
   Serial.println("This demo receives 4 integer values from a soft serial port\n");
   ss.begin(9600);
}

//============

void loop()
{
   recvWithStartEndMarkers();
   if (newData == true)
   {
      strcpy(tempChars, receivedChars);
      // this temporary copy is necessary to protect the original data
      //   because strtok() used in parseData() replaces the commas with \0
      parseData();
      showParsedData();
      newData = false;
   }
}

//============

void recvWithStartEndMarkers()
{
   static boolean recvInProgress = false;
   static byte ndx = 0;
   char startMarker = '<';
   char endMarker = '>';
   char rc;

   while (ss.available() > 0 && newData == false)
   {
      rc = ss.read();

      if (recvInProgress == true)
      {
         if (rc != endMarker)
         {
            receivedChars[ndx] = rc;
            ndx++;
            if (ndx >= numChars)
            {
               ndx = numChars - 1;
            }
         }
         else
         {
            receivedChars[ndx] = '\0'; // terminate the string
            recvInProgress = false;
            ndx = 0;
            newData = true;
         }
      }

      else if (rc == startMarker)
      {
         recvInProgress = true;
      }
   }
}

//============

void parseData()        // split the data into its parts
{

   char * strtokIndx; // this is used by strtok() as an index

   strtokIndx = strtok(tempChars, ",");     // get the first part - the string
   heat_setpointF = atoi(strtokIndx); // copy it to messageFromPC

   strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
   cold_setpointF = atoi(strtokIndx);     // convert this part to an integer

   strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
   tank_temp22 = atoi(strtokIndx);     // convert this part to an integer

   strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
   cold_combined22 = atoi(strtokIndx);     // convert this part to an integer
}


//============

void showParsedData()
{
   Serial.print("heat setpoint ");
   Serial.println(heat_setpointF);
   Serial.print("cold setpoint ");
   Serial.println(cold_setpointF);
   Serial.print("tank temp ");
   Serial.println(tank_temp22);
   Serial.print("cold cmb temp ");
   Serial.println(cold_combined22);
   Serial.println();
}
Serial.write('<');
    Serial.write(heat_setpointF);
    Serial.write(',');
    Serial.write(cold_setpointF);
    Serial.write(',');
    Serial.write(tank_temp22);
    Serial.write(',');
    Serial.write(cold_combined22);
    Serial.write('>');

Use Serial.print instead of Serial.write in your sender. Of course if I were sending with a Bluetooth module, I would be using a software serial port to send the data.

A short program to send example data:

#include <SoftwareSerial.h>

SoftwareSerial ss(4, 7);

int heat_setpointF = 200;
int cold_setpointF = 78;
int tank_temp22 = 81;
int cold_combined22 = 81;

void setup()
{
   Serial.begin(115200);
   ss.begin(9600);
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;
   if (millis() - timer >= interval)
   {
      timer = millis();
      ss.print('<');
      ss.print(heat_setpointF);
      ss.print(',');
      ss.print(cold_setpointF);
      ss.print(',');
      ss.print(tank_temp22);
      ss.print(',');
      ss.print(cold_combined22);
      ss.print('>');
   }
}

You could send binary data (with serial write) but you must make sure that the start and end markers ('<', '>') are never part of the data. That is why I like to send ASCII and use atoi to convert.

You have copied the codes/sketches blindly without trying to understand a little bit how 'UART Based Serial Communication works'; this is the reason that you can not now debug your program. The post of this link may help you understanding the working principle of UART communication.

Please, post the codes of your Master that acquires data from two temperature sensors and then send them to Slave over UART Port.

After that I shall show using step-by-step strategy how to receive ASCII/Binary formatted data by the Slave and then extract the desired integer formatted results.

Are you using these BlunoBeetle.jpg boards? If so, please, show the UART connections between Master and Slave.

BlunoBeetle.jpg

Thank you groundFungus. I will look into the use of software serial and see if that is even an option. Initially I don't think it is with the Bluno Beetles but will check it out and I greatly appreciate the example codes and modifications to my existing code to try out.

GolamMostafa:
I am learning :). You are correct and I dont know much about UART. The picture is the correct hardware I am using. 2 Bluno Beetles with version 1.8 firmware.

I am not sure what you mean by UART connections as from what I read the Bluno Beetles only have one serial port which is shared with the bluetooth. Perhaps having one Bluno connected via USB is causing problems? I dont think so though since I am getting the expected data, just not in the desired format/type though.

Hardware Setup (I would take pictures but my phone is dead):
(Master) Bluno Beetle wired to proto board with an I2C RGB display and 2 DS18B20 temp sensors. Also, has 3 push buttons to change the setpoints and display the setpoints and temp values on the display. Being powered by 5v power supply. NOTHING plugged into the USB port on the beetle.

(Slave) Bluno Beetle connected through its USB port to the computer. Data being monitored via Arduino IDE Serial Monitor on port 9. Powered through USB. Nothing else connected to it.

Slave and Master link via bluetooth after a few seconds being powered on. Link lights stay solid green.

Full Master Code in following post.

Do these boards have built-in BT Modules? I have no idea as I don't own these boards. Are you transferring data to Slave via these BTs? Anyway once I receive your sketches, I will show you the use of software UART Ports for data communication and then you switch back to BT communication.

//Master Code

#include <Wire.h>                  //Library for I2C communications to LCD display
#include <OneWire.h>               //Library needed for onewire sensors
#include <DallasTemperature.h>     //Library needed for onewire sensors
#include <LiquidCrystal_PCF8574.h> //
#include "rgb_lcd.h"               //Library to control LCD display

// Data One Wire Temperature Sensors
#define ONE_WIRE_BUS 5   //Pin 3 for reading temperature sensors
#define precision 12      

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

//Set up the LCD
rgb_lcd lcd;
int colorR = 255;
int colorG = 255;
int colorB = 255;

float tank_temp;           //Temperature sensor on the heating tank
int heat_setpointF = 120;  //Setpoint in degrees F
float heat_setpoint = heat_setpointF; //

float cold_combined;      //Temperature sensor on the cold out
int cold_setpointF = 80;  //Setpoint in degrees F
float cold_setpoint = cold_setpointF; //

//Variables for button and menu controls
boolean dotprint = LOW; 
const int RightSW = 2;
const int MidSW = 3;
const int LeftSW = 4 ;
boolean RightSWState = LOW;
boolean MidSWState = LOW;
boolean LeftSWState = LOW;

boolean waitHere = HIGH;       // used in the menu loop to wait for input

int debouncecounter = 0;       // how many times we have seen new value
int debouncereading;           // the current value read from the input pin
long debouncetime = 0;         // the last time the output pin was sampled
int debounce_count = 10;       // number of millis/samples to consider before declaring a debounced input

const int LoopSpeed = 1000;    // Controls speed of main loop

unsigned long time;            // used for button repeat
const unsigned long repeatdelay = 500; // 500ms for repeat

//Needed for buttonInput function to work properly.
int buttonInput = 0;

DeviceAddress t1, t2, t3, t4, t5, t6, t7, t8; // arrays to hold device addresses


void setup()
{
  time = millis(); // setup time variable for button pushes

  lcd.begin(16, 2);    //Tell the LCD that it is a Columns x Rows LCD
  lcd.setRGB(colorR, colorG, colorB);
  lcd.home();
  lcd.clear();
  lcd.print("Loading");
  delay(2000);
  lcd.noCursor();              //Disable cursor on LCD
  lcd.clear();                 //Clear Screen on LCD
  delay(500);

  Serial.begin(115200);  // start serial port

  // Start up the OneWire library
  sensors.begin();
  // locate devices on the bus
  Serial.print("Found: ");
  Serial.print(sensors.getDeviceCount(), DEC);
  Serial.println(" Devices.");

  // report parasite power requirements
  Serial.print("Parasite power is: ");
  if (sensors.isParasitePowerMode()) Serial.println("ON");
  else Serial.println("OFF");

  // Search for devices on the bus and assign based on an index. Ideally,
  // you would do this to initially discover addresses on the bus and then
  // use those addresses and manually assign them (see above) once you know
  // the devices on your bus (and assuming they don't change).
  //
  if (!sensors.getAddress(t1, 0)) Serial.println("No Found Sensor 1");
  if (!sensors.getAddress(t2, 1)) Serial.println("No Found Sensor 2");
  if (!sensors.getAddress(t3, 2)) Serial.println("No Found Sensor 3");
  if (!sensors.getAddress(t4, 3)) Serial.println("No Found Sensor 4");
  if (!sensors.getAddress(t5, 4)) Serial.println("No Found Sensor 5");
  if (!sensors.getAddress(t6, 5)) Serial.println("No Found Sensor 6");
  if (!sensors.getAddress(t7, 6)) Serial.println("No Found Sensor 7");
  if (!sensors.getAddress(t8, 7)) Serial.println("No Found Sensor 8");



  for (int ilosc = 0; ilosc < sensors.getDeviceCount(); ilosc++) {
    Serial.print("Sensor "); Serial.print(ilosc + 1);
    Serial.print(" Resolution: ");

    if (ilosc == 0) {
      Serial.print(sensors.getResolution(t1), DEC); Serial.println();
    } else if (ilosc == 1) {
      Serial.print(sensors.getResolution(t2), DEC); Serial.println();
    } else if (ilosc == 2) {
      Serial.print(sensors.getResolution(t3), DEC); Serial.println();
    } else if (ilosc == 3) {
      Serial.print(sensors.getResolution(t4), DEC); Serial.println();
    } else if (ilosc == 4) {
      Serial.print(sensors.getResolution(t5), DEC); Serial.println();
    } else if (ilosc == 5) {
      Serial.print(sensors.getResolution(t6), DEC); Serial.println();
    } else if (ilosc == 6) {
      Serial.print(sensors.getResolution(t7), DEC); Serial.println();
    } else if (ilosc == 7) {
      Serial.print(sensors.getResolution(t8), DEC); Serial.println();
    }
  }
  sensors.setResolution(precision);


}


void loop(void)
{
  
  float f1;
  float f2;
  int tank_temp22;
  int cold_combined22;

  f1 = tank_temp;
  tank_temp22 = (int) f1; // now i is 3

  f2 = cold_combined;
  cold_combined22 = (int) f2; // now i is 3
 

  if (Serial.available())
  {

    Serial.write('<');
    Serial.write(heat_setpointF);
    Serial.write(','); 
    Serial.write(cold_setpointF);
    Serial.write(','); 
    Serial.write(tank_temp22);
    Serial.write(','); 
    Serial.write(cold_combined22);
    Serial.write('>');
    delay(10);

  }

  //to issue a global temperature request to all devices on the bus
  sensors.requestTemperatures();
  // Using "byIndex" because you can have more than one DS18B20 on the same bus. // 0 refers to the first sensor on the wire
  cold_combined = sensors.getTempCByIndex(0);
  // Using "byIndex" because you can have more than one DS18B20 on the same bus. // 1 refers to the second sensor on the wire
  tank_temp = sensors.getTempCByIndex(1);


  tank_temp = tank_temp * 1.8 + 32;              //Converts the tank_temp from C to F degrees
  cold_combined = cold_combined * 1.8 + 32;

  heat_setpoint = heat_setpointF;
  cold_setpoint = cold_setpointF;


  lcd.setCursor(0, 0);
  lcd.print("HS:");
  lcd.print(heat_setpoint, 0);
  lcd.print(" CS:");
  lcd.print(cold_setpoint, 0);
  lcd.print("     ");


  if (isnan(tank_temp) || isnan(cold_combined))
  {
    lcd.setCursor(0, 1);
    lcd.print("Read Fail");
    delay (50);
    return;
  } else
  {
    lcd.setCursor(0, 1);
    lcd.print("T:");
    lcd.print(tank_temp, 1);
    lcd.print(" C:");
    lcd.print(cold_combined, 1);
  }

  //Process to read when a button is pressed and if nothing then blink flashing arrow to show program running
  buttonInput = readButtons();
  if (buttonInput == 1)
  {
    //Button 1 currently does nothing on main screen
  }
  else if (buttonInput == 2) 
  {
  }
  else if (buttonInput == 3) {
    Control_Menu();  // enter the Control menu
    waitHere = 1;
  }
  else {
    if (dotprint) {
      lcd.setCursor(15, 1);
      lcd.print((char)126);
      dotprint = !dotprint;
    } else {
      lcd.setCursor(15, 1);
      lcd.print(" ");
      dotprint = !dotprint;
    }
    delay(LoopSpeed);
  }
}



int Control_Menu() {

  // Menu starts here
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Control Menu");
  lcd.setCursor(0, 1);
  lcd.print("RETURN     SETUP");
  delay(500);
  while (waitHere) {
    buttonInput = readButtons();
    switch (buttonInput) {
      case 0: break;
      case 1: waitHere = 0;
        lcd.setCursor(0, 0); lcd.print("Exiting...      ");
        lcd.setCursor(0, 1); lcd.print("                ");
        delay(25);
        return 0;
      case 2: break;
      case 3: waitHere = 0;
    }
    delay(10);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Heat Set: ");
  lcd.setCursor(0, 1);
  lcd.print("-     +     Next");
  buttonInput = 0;  // Reset button input routing
  while (buttonInput != 3) {
    lcd.setCursor(12, 0); lcd.print(heat_setpointF); lcd.print("  ");
    buttonInput = readButtons();
    switch (buttonInput) {
      case 1:
        heat_setpointF--;
        break;
      case 2:
        heat_setpointF++;
        break;
    }

  }


  lcd.clear();
  lcd.setCursor(0, 0);
  //  lcd.print("                ");
  lcd.print("Cold Set: ");
  lcd.setCursor(0, 1);
  lcd.print("-     +     Next");
  buttonInput = 0;  // Reset button input routing
  while (buttonInput != 3) {
    lcd.setCursor(12, 0); lcd.print(cold_setpointF); lcd.print("  ");
    buttonInput = readButtons();
    switch (buttonInput) {
      case 1:
        cold_setpointF--;
        break;
      case 2:
        cold_setpointF++;
        break;
    }
  }

Yes they have built in bluetooth and the goal is to transfer data from master to slave via bluetooth. In the final version everything will be battery powered and nothing plugged into the onboard usb ports. All communication will be over bluetooth wireless.

Rest of the master code below. I can only post every 5 minutes since I am new and there is a 9000 character limit.

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Save settings? ");
  lcd.setCursor(0, 1);
  lcd.print("SAVE     DISCARD");
  buttonInput = 0;  // Reset button input routing
  delay(1000); // testing
  while (buttonInput != 1 && buttonInput != 3) {
    lcd.setCursor(12, 0);
    buttonInput = readButtons();
    switch (buttonInput) {
      case 1:
        delay (500);
        return (0);
      case 3:
        delay (500);
        return (0);
        break;
    }
  }
}


//Function to read the 3 buttons and make display changes when button pressed
int readButtons() {

  // Right Button
  if (digitalRead(RightSW) && (millis() - time >= repeatdelay)) {
    for (int i = 0; i < 10; i++)
    {
      debouncereading = digitalRead(RightSW);

      if (!debouncereading && debouncecounter > 0)
      {
        debouncecounter--;
      }
      if (debouncereading)
      {
        debouncecounter++;
      }
      // If the Input has shown the same value for long enough let's switch it
      if (debouncecounter >= debounce_count)
      {
        time = millis();
        debouncecounter = 0;
        RightSWState = 1;

      }
      delay (20); // wait 10ms
    }
  } else {
    RightSWState = 0;

  }


  if (digitalRead(MidSW) && (millis() - time >= repeatdelay)) {
    for (int i = 0; i < 10; i++)
    {
      debouncereading = digitalRead(MidSW);

      if (!debouncereading && debouncecounter > 0)
      {
        debouncecounter--;
      }
      if (debouncereading)
      {
        debouncecounter++;
      }
      // If the Input has shown the same value for long enough let's switch it
      if (debouncecounter >= debounce_count)
      {
        time = millis();
        debouncecounter = 0;
        MidSWState = 1;

      }
      delay (20); // wait 10ms
    }
  } else {
    MidSWState = 0;

  }

  if (digitalRead(LeftSW) && (millis() - time >= repeatdelay)) {
    for (int i = 0; i < 10; i++)
    {
      debouncereading = digitalRead(LeftSW);

      if (!debouncereading && debouncecounter > 0)
      {
        debouncecounter--;
      }
      if (debouncereading)
      {
        debouncecounter++;
      }
      // If the Input has shown the same value for long enough let's switch it
      if (debouncecounter >= debounce_count)
      {
        time = millis();
        debouncecounter = 0;
        LeftSWState = 1;

      }
      delay (20); // wait 10ms
    }
  } else {
    LeftSWState = 0;

  }

  if (RightSWState) {
    return 1;
  }
  else if (MidSWState) {
    return 2;
  }
  else if (LeftSWState) {
    return 3;
  }
  else {
    return 0;
  }
}

1. Carry out the functional check of the BT channels.
(1) Connect only one DS18B20 sensor at DPin-5 of Transmit Arduino/Buldinuo,
(2) Upload the following sketch in Transmit Arduino.

//#include<SoftwareSerial.h>
//SoftwareSerial SUART(2, 3); //SRX = DPin-2, STX = DPin-3

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(9600);
  //SUART.begin(9600);  
  sensors.begin();
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  float tempC = sensors.getTempCByIndex(0);
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(tempC, 2);  //2-digit after decimal
  //SUART.println(tempC, 2);
  delay(1000);
}

(3) Upload the following sketch in Receive Arduino/Buldinuo.

//#include<SoftwareSerial.h>
//SoftwareSerial SUART(2, 3); //SRX = DPin-2, STX = DPin-3

void setup()
{
  Serial.begin(9600);
  //SUART.begin(9600);
}

void loop()
{
  byte n = Serial.available();//SUART.available();
  if (n != 0)
  {
    char x = Serial.read();//SUART.read();
    Serial.print(x);
  }
}

(4) Check that the temperature reading appears on the Serial Monitors of both Transmiiter and Receiver.

2. If Step-1 does not work, connect Transmitter and Receiver using Software UART Ports as per following connections.
DPin-2 of Transmitter -----> DPn-3 of Receiver
DPin-3 of Transmitter -----> DPin-2 of Receiver
GND of Transmitter --------> GND of Receiver

(1) Upload the following sketch in Transmitter (tested in UNO).

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX = DPin-2, STX = DPin-3

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 5
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);  
  sensors.begin();
}

void loop()
{
  sensors.requestTemperatures(); // Send the command to get temperatures
  float tempC = sensors.getTempCByIndex(0);
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(tempC, 2);  //2-digit after decimal
  SUART.println(tempC, 2);
  delay(1000);
}

(2) Upload the following sketch in Receiver (tested in NANO).

#include<SoftwareSerial.h>
SoftwareSerial SUART(2, 3); //SRX = DPin-2, STX = DPin-3

void setup()
{
  Serial.begin(9600);
  SUART.begin(9600);
}

void loop()
{
  byte n = SUART.available();
  if (n != 0)
  {
    char x = SUART.read();
    Serial.print(x);
  }
}

(3) Check that the temperature value of sensor appears on both Serial Monitors of TX and RX.

Please, report your outcome.

You can use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without having to convert ASCII values. The library is installable through the Arduino IDE and includes many examples.

Here are the library's features:

This library:

  • can be downloaded via the Arduino IDE's Libraries Manager (search "SerialTransfer.h")
  • works with "software-serial" libraries
  • is non blocking
  • uses packet delimiters
  • uses consistent overhead byte stuffing
  • uses CRC-8 (Polynomial 0x9B with lookup table)
  • allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 254 bytes)
  • can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  char buff[] = "hi";

  myTransfer.txObj(buff, sizeof(buff));
  myTransfer.sendData(sizeof(buff));
  delay(100);
}

Example RX Arduino Sketch:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    char buff[40];
    
    myTransfer.rxObj(buff, sizeof(buff));
    
    Serial.println("New Data: ");
    Serial.write(buff, sizeof(buff));
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

For theory behind robust serial communication, check out the tutorials Serial Input Basics and Serial Input Advanced.