Issue with array

Hello, I am trying to convert a variable string of data into an hexstring to send it over LoRa. When I make my array too long it gets filled with 0's and weird characters. How can I make my conversion variable or cut off my conversion when my data ends? My code is

#include <TheThingsNetwork.h>
#include <SoftwareSerial.h>
SoftwareSerial BTserial(8, 9); // RX | TX

char c = ' ';

void delayAndRead()
{
  delay(220);
  while (BTserial.available())
  {
    c = BTserial.read();
  }
  delay(800);
}

void initHC05ToInq()
{
  BTserial.println("AT+INIT");// Init.
  delayAndRead();
  Serial.println("test0");
  BTserial.println("AT+CMODE=1");// Enable connect to any device
  delayAndRead();
  Serial.println("test1");
  BTserial.println("AT+ROLE=1");// Set to master in order to enable scanning
  delayAndRead();
  Serial.println("test2");
  BTserial.println("AT+INQM=1,7,5");//RSSI, Max 10 devices, ~30s
  delayAndRead();
  Serial.println("test3");
  BTserial.println("AT+CLASS=0");// Disable COD filter
  delayAndRead();
  Serial.println("test4");
}

//-----------------------------------------------
// Set your DevAddr, NwkSKey, AppSKey and the frequency plan
const char *devAddr = "nonono";
const char *nwkSKey = "no private keys";
const char *appSKey = "for you :)";

#define loraSerial Serial1
#define debugSerial Serial

// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
#define freqPlan TTN_FP_EU868

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);
//-----------------------------------------------


void setup()
{
  loraSerial.begin(57600);
  debugSerial.begin(9600);
  BTserial.begin(38400);

  // Wait a maximum of 10s for Serial Monitor
  while (!debugSerial && millis() < 10000)
    ;

  debugSerial.println("-- PERSONALIZE");
  ttn.personalize(devAddr, nwkSKey, appSKey);

  debugSerial.println("-- STATUS");
  ttn.showStatus();

  delay(1000);
  BTserial.println("AR+ORGL");
  delay(1000);
  BTserial.println("AT+RESET");
  delay(1000);
  initHC05ToInq();
  initMessage();
  BTserial.println("AT+INQ");
}

char lineBuffer[100];
char subBuffer[220];
int index = 0;
int index2 = 0;
int total = 0;
bool capture = false;
String send = "";

void initMessage()
{
  send = "B1:";
}

void string2ByteArray(char* input, byte* output)
{
  int loop;
  int i;
  loop = 0;
  i = 0;
  while (input[loop] != '\0')
  {
    output[i++] = input[loop++];
  }
}

void loop()
{
  // Keep reading from HC-05 and send to Arduino Serial Monitor
  if (BTserial.available())
  {
    // Read character and append into buffer
    c = BTserial.read();
    lineBuffer[index] = c;
    index++;

    // When line ends
    if (c == '\n')
    {
      // Remove line end characters from buffer
      lineBuffer[index - 1] = 0; // \r\n

      // Reset buffer index for next line
      index = 0;

      if (lineBuffer[0] == 'O' && lineBuffer[1] == 'K')
      {
        // Finish message
        send += "]}}}";
        
        //---------------------------------------------------------------- 
        // B1;["FCDE:90:5E7952,5A020C,FFD4"]} = 34 (ex. haakjes is het 31)

        send.toCharArray(subBuffer, sizeof(subBuffer));
        ttn.sendBytes(subBuffer, sizeof(subBuffer));
        //---------------------------------------------------------------- 

        // DEBUG / TODO actually send this message
        if (total > 0)
        {
          Serial.println(send);

        }
        // Restart INQ
        delay(2000);
        BTserial.println("AT+INQ");
        total = 0;
        initMessage();
      }
      else
      {
        capture = false;
        index2 = 0;
        for (index = 0; index < 220; index++)
        {
          if (!capture)
          {
            if (lineBuffer[index] == ':')
            {
              capture = true;
            }
          }
          else
          {
            subBuffer[index2] = lineBuffer[index];
            if (lineBuffer[index] == '\n')
            {
              subBuffer[index2] = 0;
              break;
            }
            index2++;
          }
        }
        index = 0;

        // Add this line buffer
        String str((char*)subBuffer);

        if (send.indexOf(str) <= 0)
        {
          // If not first then add comma
          if (total > 0)
          {
            send += ",";
          }

          send += "\"";
          send += str;
          send += "\"";
          // Keep count
          total++;
        }
      }
    }
  }
}

around this part:

        send.toCharArray(subBuffer, sizeof(subBuffer));
        ttn.sendBytes(subBuffer, sizeof(subBuffer));
        //---------------------------------------------------------------- 

        // DEBUG / TODO actually send this message
        if (total > 0)
        {
          Serial.println(send);

        }

is where my problems begin. For example I get returned this :
42313A22423441393A46433A3131363334442C3241303130432C464642300D222C22423441393A46433A3131363334442C3241303130432C464641380D222C22423441393A46433A3131363334442C3241303130432C464641450D222C22423441393A46433A3131363334442C3241303130432C464641460D225D7D7D7D00000000000000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D01000010270000E9060000CD00CC00C800C9

this translates into:

B1:"B4A9:FC:11634D,2A010C,FFB0
","B4A9:FC:11634D,2A010C,FFA8
","B4A9:FC:11634D,2A010C,FFAE
","B4A9:FC:11634D,2A010C,FFAF
"]}}}ÿÿ'éÍÌÈÉ

but I want it to translate it into this:
42313A22423441393A46433A3131363334442C3241303130432C464642300D222C22423441393A46433A3131363334442C3241303130432C464641380D222C22423441393A46433A3131363334442C3241303130432C464641450D222C22423441393A46433A3131363334442C3241303130432C464641460D225D7D7D7D

B1:"B4A9:FC:11634D,2A010C,FFB0
","B4A9:FC:11634D,2A010C,FFA8
","B4A9:FC:11634D,2A010C,FFAE
","B4A9:FC:11634D,2A010C,FFAF
"]}}}

So how can I edit my program to cut off or to remove the unnecessary piece of the string. This whole piece is not needed:
00000000000000FFFF0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001D01000010270000E9060000CD00CC00C800C
I cannot make my array smaller because my data is variable between 1 and 9 devices.
Thank you in advance!

this does not allocate any memory for your buffer

        char ttnBuffer[];

so the size of what you copy and try to send

        send.toCharArray(ttnBuffer, sizeof(ttnBuffer));
        ttn.sendBytes(subBuffer, sizeof(subBuffer));

won't be much...

I would suggest to study Serial Input Basics to handle reading correctly from your BT Serial line

Hey sorry for the mistake, I uploaded the wrong code.

The edits should have been :

char subBuffer[220];

        send.toCharArray(subBuffer, sizeof(subBuffer));
        ttn.sendBytes(subBuffer, sizeof(subBuffer));

for (index = 0; index < 220; index++)

I have edited the main post to correct for these mistakes. Do you know any solution in this case?

What happens if you don't send the full buffer but only the actual data based on strlen?
Try to change

ttn.sendBytes(subBuffer, sizeof(subBuffer));

to

ttn.sendBytes(subBuffer, strlen(subBuffer));

You have two buffers:

char lineBuffer[100];
char subBuffer[220];

when you do

 if (BTserial.available())
  {
    // Read character and append into buffer
    c = BTserial.read();
    lineBuffer[index] = c;
    index++;

you don't test for overflow. at the very least check if index is < 99 before writing into the array.

When you've got the '\n' you do

       index2 = 0;
        for (index = 0; index < 220; index++)
        {
          if (!capture)
          {
            if (lineBuffer[index] == ':') // <<==== ????
            {
              capture = true;
            }
          }

why would you try to read 220 bytes from lineBuffer when you only allocated 100 bytes there?

when you do this

           subBuffer[index2] = lineBuffer[index];

Didn't you get your index mixed up?


You probably need to rethink the whole thing. Capture the incoming bytes in the right way. I would suggest to study Serial Input Basics to handle this

When you have that done, handle the message. make sure you don't go beyond the boundaries.

sterretje:
What happens if you don't send the full buffer but only the actual data based on strlen?
Try to change

ttn.sendBytes(subBuffer, sizeof(subBuffer));

to

ttn.sendBytes(subBuffer, strlen(subBuffer));

Sterretje, thank you for your reply. I managed to fix it with strlen. Nevert thought of that one. You really helped me out! Big shout out to you. :slight_smile: :slight_smile: :slight_smile:

double check your indexes though... something lurking there

J-M-L:
double check your indexes though... something lurking there

Hey J-M-L, thanks for your reply. I made some changes with my indexes. It shouldn't be a problem now.

good

You could replace all that buffer and index stuff with my SafeString library available from the library manager

SafeString can print an error message when your idx is out of range or the buffer overflows.
The detailed tutorial is here

The companion SafeStringReader (included in the library) simplifies your code, it replaces your linebuffer and handles the line read. SafeStringReader.read() is non-blocking, unlike the standard Serial.readUntil(), so it won't halt your loop code.

The String send should be replaced with a SafeString (see below). Using Strings in Arduino is advised against see the SafeString tutorial for references and the details
The SafeString provides similar functionality to the String it replaces, but with more error checking and no memory problems.

#include <SafeStringReader.h> 
// install SafeString library from the library manager
// see the tutorial https://www.forward.com.au/pfod/ArduinoProgramming/SafeString/index.html
... 

void setup()
{
  loraSerial.begin(57600);
  debugSerial.begin(9600); //<< make this as fast as possible to prevent serial.print() blocking the rest of your code
  // see Text I/O for the Real World https://www.forward.com.au/pfod/ArduinoProgramming/Serial_IO/index.html
  SafeString::setOutput(debugSerial); // turn on SafeString error msgs
  BTserial.begin(38400);
  sfReader.connect(BTserial); // read from here
 ...
}

createSafeString(send,500); 
void initMessage() {
  send = "B1:";
}

void loop()
{
  // Keep reading from HC-05 and send to Arduino Serial Monitor
  // read a line
  if (sfReader.read()) {
    // got a \n terminated line
    sfReader.trim(); // remove \r
    if (sfReader.beginsWith("OK")) {
    // Finish message
        send += "]}}}";   // can += to a SafeString
         //----------------------------------------------------------------
        // B1;["FCDE:90:5E7952,5A020C,FFD4"]} = 34 (ex. haakjes is het 31)
        ttn.sendBytes(sfReader.c_str().sfReader.length());
        if (total > 0) {
          debugSerial.println(send);
        }
        // Restart INQ
        delay(2000);   // <<<<<<<<<<<< delays are evil but... one thing at a time
        BTserial.println("AT+INQ");
        total = 0;
        initMessage();
    }
    else  // not ends with OK
    {
      // other stuff here
    }
    sfReader.clear(); // for next read
  }
}

The
for (index = 0; index < 220; index++)
stuff can be more reliably replaced with SafeString methods
but I was not sure exactly what you were trying to achieve.
Post here or drop me a line if you want to use SafeStrings for this.

SafeStrings was designed to simplify char[] processing and to catch the errors. Check out the tutorial for the details.

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