Splitting an array into specific blocks.

Hello,
I’m having so issues getting a LoRa project to work.
I am able to transmit and receive the data as expected using the serial.print() function.
however, I want to receive the data into an array and then split the array and store the results into floats and integers to then be displayed on an LCD.

I have the code storing the incoming data into the array fine I’m completely stuck when it comes to sorting the data and storing it for later use.

My code RX code looks like this:

#include <SPI.h>
#include <LoRa.h>
char myArray[13];
int i = 0;
int rssi;

void setup() {
  Serial.begin(9600);
  while (!Serial);

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
        Serial.println("Received packet");

    // read packet
    while (LoRa.available()) {     
      for (i=0; i < 13; i++){
         myArray[i] = LoRa.read();        
      }
    }
    Serial.print(myArray);
    rssi = LoRa.packetRssi();

    // print RSSI of packet
    Serial.print("with RSSI ");    
    Serial.println(rssi);
  }
}

The output from the array would look like this:
‘30.0025.005’
I want to store the first 5 char into a float variable x the next 5 into variable y and the final digit in z.
ie.
variable x would have 30.00
Variable y would have 25.00 and
variable z would have 5

Can anyone point me in the right direction?

atof - cppreference.com Interprets a null-terminated string as a float.

Also look into strncpy() on that site to copy the number of characters you want into a string that atof() and atoi() can work with.

Thanks very much mate, I will check it out.

Unordung:
Can anyone point me in the right direction?

1. Your array named char myArray[13]; presently contains 30.0025.005.

2. Remember that each character/symbol of 30.0025.005 has been coded as an ASCII Code in the myArray. It means that 3 is as 33 (0x33), and so on.

3. You have three diffrent numbers/items in the array, and these are: 30.00, 25.00, and 5.

4. You want to extract the items of Step-3 from the composite value of Step-1 and store them into variables float x, float y, and int z.

5. The process of extraction would be much easier if you could receive the data in this format:<30.00,25.00,5>. But you have this format: 30.0025.005, let us see what we can do.

(1) Re-declare your char myArray[13]; as char myArray[13] = ‘’"; to put 0x00 in all locations of the array.

(2) Temporarily, remove the content of myArray[5] into variable p and store 0x00 at that position. Now, execute the following codes:

float x = atof(myArray, 2);
Serial.print(x, 2); //shows: 30.00
myArray[5] = p;  //put back the original values

(3) Upload the following sketch and check the validity of the above propositions:

char myArray[13] = "30.0025.005";  //test value
void setup() 
{
  Serial.begin(9600);
  byte p = myArray[5];
  myArray[5] = 0x00;
  float x = atof(myArray);
  myArray[5] = p;   //restoring original value
  Serial.print(x, 2); //shows: 30.00
}

void loop() 
{
  
}

(4) Similarly, extract the remaining items.

Thanking you very kindly for the detailed reply.

GolamMostafa:
5. The process of extraction would be much easier if you could receive the data in this format:<30.00,25.00,5>. But you have this format: 30.0025.005, let us see what we can do.

The very good news is I certainly can add a separator between the data if this is significantly easier.

Unordung:
Can anyone point me in the right direction?

Have a look at the parse example in Serial Input Basics

...R

    while (LoRa.available()) {     
      for (i=0; i < 13; i++){
         myArray[i] = LoRa.read();       
      }
    }

Whenever there is one or more bytes to read, read all 13 of them, and then check again. That makes not a lick of sense.

Pack your data into a struct and send it as binary. At the RX end, memcpy the data into an identical struct. It will "magically" be split apart for you.

Unordung:
Thanking you very kindly for the deta
The very good news is I certainly can add a separator between the data if this is significantly easier.

  1. First finish the pending excises of Post#3.

  2. Next the exercise as quoted above.

  3. And then the exercise of Post#7.

gfvalvo:
Pack your data into a struct and send it as binary. At the RX end, memcpy the data into an identical struct. It will "magically" be split apart for you.

I do that, but I send the data as text - which makes debugging easier.

...R

Converting from a binary representation of a float to ASCII, sending it, and then converting back to binary strikes me as inelegant. Plus, I’d suspect that you may not end up with exactly the same binary representation at the other end (round off, etc).

Debugging with binary data is simple: print the bytes that you send at the TX end (I prefer HEX), print the bytes that you get at the RX end. Compare.

Debugging with printable characters is much easier if what you are grabbing is a random terminal program.

Also done correctly as no doubt R2 can there will be no loss of precision, the bits end up being exactly the same.

I switched to readable data transfer long ago when I can choose to do. The overhead in code and transmissions time is totally outweighed by the benefit of being able to read (AND easily simulate either side) the data as it flows.

As always YMMV.

a7

gfvalvo:
Converting from a binary representation of a float to ASCII, sending it, and then converting back to binary strikes me as inelegant.

I agree.

But it works very well because I can print the actual data that I am going to send and print the data that is received and understand both of them without any need to "interpret" anything.

And to be honest I don't care if the conversions mean extra work for Python and the Arduino unless the extra work impairs the functioning of the program.

I do have some programs that send binary data - but only where the extra performance is essential.

...R

1 Like