SoftwareSerial buffer size

Is there any way I can increase the buffer size?
The slave (Arduino Uno) is sending the data to the master (Arduino Mega).

Or is there any other library which could send these variables from the Uno to the Mega.

Variables needed to be transmitted:

int sensor_rain = 0;
float sensor_light = 0.00;
float sensor_hum = 0.00;
float sensor_temp = 0.00;
// Data received from the Internet
float API_rain;
float API_temp;
float API_tempFeels;
int API_hum;
char API_wind[55];
char API_weather[30];
char API_text_tomorrow[150];
char API_text_tomorrow_night[150];

Master code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);//rx tx

const byte numCharsSlave = 32;
char receivedSlaveChars[numCharsSlave];
char tempSlaveChars[numCharsSlave];        // temporary array for use when parsing

// variables to hold the parsed data
char messageFromSlave[numCharsSlave] = {0};
// Data received from sensor system
int sensor_rain = 0;
float sensor_light = 0.00;
float sensor_hum = 0.00;
float sensor_temp = 0.00;
// Data received from the Internet
float API_rain;
float API_temp;
float API_tempFeels;
int API_hum;
char API_wind[55];
char API_weather[30];
char API_text_tomorrow[150];
char API_text_tomorrow_night[150];
boolean newData = false; // invert this on Slave arduino

static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;

unsigned long currentMillis1 = 0;
unsigned long previousMillis1 = 0;
long interval1 = 150;           // 150 milliseconds
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}
void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempSlaveChars, receivedSlaveChars);// 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() {
  while (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedSlaveChars[ndx] = rc;
        ndx++;
        if (ndx >= numCharsSlave) {
          ndx = numCharsSlave - 1;
        }
      }
      else {
        receivedSlaveChars[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(tempSlaveChars, ",");     // get the first part - the string
  strtokIndx = strtok(NULL, ",");
  sensor_rain = atoi(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  sensor_light = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  sensor_hum = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  sensor_temp = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  API_rain = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  API_temp = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  API_tempFeels = atof(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  API_hum = atoi(strtokIndx);
  strtokIndx = strtok(NULL, ",");
  strcpy(API_wind, strtokIndx);
  strtokIndx = strtok(NULL, ",");
  strcpy(API_weather, strtokIndx);
  strtokIndx = strtok(NULL, ",");
  strcpy(API_text_tomorrow, strtokIndx);
  strtokIndx = strtok(NULL, ",");
  strcpy(API_text_tomorrow_night, strtokIndx);
}
void showParsedData() {
  Serial.print("Rain sensor: ");
  Serial.println(sensor_rain);
  Serial.print("Sensor light: ");
  Serial.println(sensor_light);
  Serial.print("Sensor humidity: ");
  Serial.println(sensor_hum);
  Serial.print("Sensor temperature: ");
  Serial.println(sensor_temp);
  Serial.print("API rain: ");
  Serial.println(API_rain);
  Serial.print("API temperature: ");
  Serial.println(API_temp);
  Serial.print("API temperature feels: ");
  Serial.println(API_tempFeels);
  Serial.print("API humidity: ");
  Serial.println(API_hum);
  Serial.print("API wind: ");
  Serial.println(API_wind);
  Serial.print("API weather: ");
  Serial.println(API_weather);
  Serial.print("API Text tomorrow: ");
  Serial.println(API_text_tomorrow);
  Serial.print("API Text tomorrow night: ");
  Serial.println(API_text_tomorrow_night);
}

Slave code:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);//rx tx
// Data received from sensor system
int sensor_rain = 1;
float sensor_light = 2.22;
float sensor_hum = 3.33;
float sensor_temp = 4.44;
// Data received from the Internet
float API_rain = 5.55;
float API_temp = 6.66;
float API_tempFeels = 7.77;
int API_hum = 8;
char API_wind[55] = "Strong wind";
char API_weather[30] = "The sky is clear";
char API_text_tomorrow[200] = "Good weather tomorrow";
char API_text_tomorrow_night[200] = "Shit weather tomorrow night";
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}
void loop() {
  sendDataToMaster ();
  delay(15000);
}
void sendDataToMaster () {
  mySerial.print('<');
  mySerial.print("Slave text");
  mySerial.print(",");
  mySerial.print(sensor_rain);
  mySerial.print(",");
  mySerial.print(sensor_light);
  mySerial.print(",");
  mySerial.print(sensor_hum);
  mySerial.print(",");
  mySerial.print(sensor_temp);
  mySerial.print(",");
  mySerial.print(API_rain);
  mySerial.print(",");
  mySerial.print(API_temp);
  mySerial.print(",");
  mySerial.print(API_tempFeels);
  mySerial.print(",");
  mySerial.print(API_hum);
  mySerial.print(",");
  mySerial.print(API_wind);
  mySerial.print(",");
  mySerial.print(API_weather);
  mySerial.print(",");
  mySerial.print(API_text_tomorrow);
  mySerial.print(",");
  mySerial.print(API_text_tomorrow_night);
  mySerial.print(">");
}

These are the codes I am using. Apart from not being able transmit the required amount of variables, it works fine.

Why do you need to increase the buffer size ?

char API_text_tomorrow_night[150] takes up 150bytes, right?
The buffer limit is 64bytes.

In case I am wrong please let me know as I am not sure about it.

    strcpy(tempSlaveChars, receivedSlaveChars);// this temporary copy is necessary to protect the original data because strtok() used in parseData() replaces the commas with \0

So what if strtok() destroys the array? You never use its contents again, so the copy is unnecessary.

I know that Robin2 put that in the example, because there was a possibility that someone would need the array intact after parsing, but you are SUPPOSED to think when you steal code.

notfreeusername:
char API_text_tomorrow_night[150] takes up 150bytes, right?
The buffer limit is 64bytes.

In case I am wrong please let me know as I am not sure about it.

Serial data is transmitted slowly. The Arduino can read data orders of magnitude faster than it arrives. So, you are wrong.

notfreeusername:
char API_text_tomorrow_night[150] takes up 150bytes, right?
The buffer limit is 64bytes.

In case I am wrong please let me know as I am not sure about it.

You're not wrong, but so what?

notfreeusername:
char API_text_tomorrow_night[150] takes up 150bytes, right?
The buffer limit is 64bytes.

In case I am wrong please let me know as I am not sure about it.

But you only send one byte at a time, and there is plenty of time for the receiver to save each one before another one arrives.

So why don't I receive the whole data?

notfreeusername:
So why don't I receive the whole data?

You haven't offered any proof that you don't. So, we have to assume that you do.

Sorry. :frowning: You are right.

This is what I receive when I send everything:

Rain sensor: 1
Sensor light: 2.22
Sensor humidity: 3.33
Sensor temperature: 4.44
API rain: 0.00
API temperature: 0.00
API temperature feels: 0.00
API humidity: 0
API wind: ⸮
API weather:
API Text tomorrow:
API Text tomorrow night:

When I send only API_text_tomorrow_night, I receive only this:

API Text tomorrow night: Shit weather tomorr

In the transmitter the variable is declared as:

API Text tomorrow night: Shit weather tomorr

In the transmitter the variable is declared as:

I don't think so.

const byte numCharsSlave = 32;
char receivedSlaveChars[numCharsSlave];
char tempSlaveChars[numCharsSlave];

You don't seem to be able to count. You are sending just a few more characters than THAT.

I used sizeof() which gave me a value of 413.
I put that value instead of 32 but I am still not getting everything.

Should I use something else instead of sizeof() to determine the correct value?

Should I use something else instead of sizeof() to determine the correct value?

What did you measure the size of? The shoes of all the students in your dorm?

If you changed the code, you need to post the revised code AND the new output.

Before you do that, however, ask yourself if you REALLY need to send all that data. You send the same set of values every time. Do you REALLY need to send the same string literals EVERY time?

This line determines how many characters are received

const byte numCharsSlave = 32;

change it to whatever size you need - allow at least one extra byte for the terminating '\0'

...R

I measured the size of the variables.

This is the revised code for the master:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);//rx tx

const byte numCharsSlave = 500;
char receivedSlaveChars[numCharsSlave];
char tempSlaveChars[numCharsSlave];        // temporary array for use when parsing

// variables to hold the parsed data
char messageFromSlave[numCharsSlave] = {0};
// Data received from sensor system
int sensor_rain = 0;
float sensor_light = 0.00;
float sensor_hum = 0.00;
float sensor_temp = 0.00;
// Data received from the Internet
float API_rain = 0.00;
float API_temp = 0.00;
float API_tempFeels = 0.00;
int API_hum = 0;
char API_wind[55] = "";
char API_weather[30] = "";
char API_text_tomorrow[150] = "";
char API_text_tomorrow_night[150] = "";
boolean newData = false; // invert this on Slave arduino

static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;

unsigned long currentMillis1 = 0;
unsigned long previousMillis1 = 0;
long interval1 = 150;           // 150 milliseconds
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}
void loop() {
  recvWithStartEndMarkers();
  if (newData == true) {
    strcpy(tempSlaveChars, receivedSlaveChars);// 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() {
  while (mySerial.available() > 0 && newData == false) {
    rc = mySerial.read();
    if (recvInProgress == true) {
      if (rc != endMarker) {
        receivedSlaveChars[ndx] = rc;
        ndx++;
        if (ndx >= numCharsSlave) {
          ndx = numCharsSlave - 1;
        }
      }
      else {
        receivedSlaveChars[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(tempSlaveChars, "*");     // get the first part - the string
  strtokIndx = strtok(NULL, "*");
  sensor_rain = atoi(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  sensor_light = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  sensor_hum = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  sensor_temp = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  API_rain = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  API_temp = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  API_tempFeels = atof(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  API_hum = atoi(strtokIndx);
  strtokIndx = strtok(NULL, "*");
  strcpy(API_wind, strtokIndx);
  strtokIndx = strtok(NULL, "*");
  strcpy(API_weather, strtokIndx);
  strtokIndx = strtok(NULL, "*");
  strcpy(API_text_tomorrow, strtokIndx);
  strtokIndx = strtok(NULL, "*");
  strcpy(API_text_tomorrow_night, strtokIndx);
}
void showParsedData() {
  Serial.print("Rain sensor: ");
  Serial.println(sensor_rain);
  Serial.print("Sensor light: ");
  Serial.println(sensor_light);
  Serial.print("Sensor humidity: ");
  Serial.println(sensor_hum);
  Serial.print("Sensor temperature: ");
  Serial.println(sensor_temp);
  Serial.print("API rain: ");
  Serial.println(API_rain);
  Serial.print("API temperature: ");
  Serial.println(API_temp);
  Serial.print("API temperature feels: ");
  Serial.println(API_tempFeels);
  Serial.print("API humidity: ");
  Serial.println(API_hum);
  Serial.print("API wind: ");
  Serial.println(API_wind);
  Serial.print("API weather: ");
  Serial.println(API_weather);
  Serial.print("API Text tomorrow: ");
  Serial.println(API_text_tomorrow);
  Serial.print("API Text tomorrow night: ");
  Serial.println(API_text_tomorrow_night);
}

Code for the slave:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11);//rx tx
// Data received from sensor system
int sensor_rain = 1;
float sensor_light = 2.22;
float sensor_hum = 3.33;
float sensor_temp = 4.44;
// Data received from the Internet
float API_rain = 5.55;
float API_temp = 6.66;
float API_tempFeels = 7.77;
int API_hum = 8;
char API_wind[55] = "123456789012345678901234567890123456789012345678901234";
char API_weather[30] = "12345678901234567890123456789";
char API_text_tomorrow[150] = "1234567890123456789012345678901234567890123456789012341234567890123456789012345678901234567890123456789012341234567890123456789012345678901234567890";
char API_text_tomorrow_night[150] = "1234567890123456789012345678901234567890123456789012341234567890123456789012345678901234567890123456789012341234567890123456789012345678901234567890";
void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  int sum;
  sum = sizeof(sensor_rain) + sizeof(sensor_light) + sizeof(sensor_hum) + sizeof(sensor_temp) + sizeof(API_rain) + sizeof(API_temp) + sizeof(API_tempFeels) + sizeof(API_hum) + sizeof(API_wind) + sizeof(API_weather) + sizeof(API_text_tomorrow) + sizeof(API_text_tomorrow_night);
  Serial.println(sum);
  Serial.println(sizeof(API_text_tomorrow) + sizeof(API_text_tomorrow_night));
}
void loop() {
  sendDataToMaster ();
  delay(15000);
}
void sendDataToMaster () {
  mySerial.print('<');
  mySerial.print("Slave text");
  mySerial.print("*");
  mySerial.print(sensor_rain);
  mySerial.print("*");
  mySerial.print(sensor_light);
  mySerial.print("*");
  mySerial.print(sensor_hum);
  mySerial.print("*");
  mySerial.print(sensor_temp);
  mySerial.print("*");
  mySerial.print(API_rain);
  mySerial.print("*");
  mySerial.print(API_temp);
  mySerial.print("*");
  mySerial.print(API_tempFeels);
  mySerial.print("*");
  mySerial.print(API_hum);
  mySerial.print("*");
  mySerial.print(API_wind);
  mySerial.print("*");
  mySerial.print(API_weather);
  mySerial.print("*");
  mySerial.print(API_text_tomorrow);
  mySerial.print("*");
  mySerial.print(API_text_tomorrow_night);
  mySerial.print(">");
}

This is the output for the revised codes:

Rain sensor: 1
Sensor light: 2.22
Sensor humidity: 3.33
Sensor temperature: 4.44
API rain: 5.55
API temperature: 6.66
API temperature feels: 7.77
API humidity: 8
API wind: 123456789012345678901234567890123456789012345678901234
API weather: 12345678901234567890123456789
API Text tomorrow: 12345678901234567890123456789012345678901234567890123412345678901234567890123456789012345678901234567890123412345
API Text tomorrow night:

I need all these data to be transmitted.
They all will be changing by time. The rest of the code is not included because it would only make the code longer.

Any idea why I am not getting all of the data when using 500 for numCharsSlave?

On the master, you have 3 500 byte arrays, to hold the received data, to hold a useless copy of it, and one that is not used.

You also have 385 bytes used in 4 other arrays. Those 7 arrays are using 1,885 bytes of the 2,048 bytes of SRAM that you have, leaving 163 bytes for all the rest of the variables (including the software serial buffer(s)) and the stack.

Do things improve if you STOP COPYING THE DATA? If you delete the unused array?

I deleted:

char tempSlaveChars[numCharsSlave];        // temporary array for use when parsing
char messageFromSlave[numCharsSlave] = {0};

And changed this:

strtokIndx = strtok(tempSlaveChars, "*");     // get the first part - the string

to this:

 strtokIndx = strtok(receivedSlaveChars, "*");     // get the first part - the string

I believe this is what you suggested me.

This is what goes through now:

Rain sensor: 1
Sensor light: 2.22
Sensor humidity: 3.33
Sensor temperature: 4.44
API rain: 5.55
API temperature: 6.66
API temperature feels: 7.77
API humidity: 8
API wind: 123456789012345678901234567890123456789012345678901234
API weather: 12345678901234567890123456789
API Text tomorrow: 12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
API Text tomorrow night:

I am using Arduino Mega for the master. Woulnd't that have more SRAM than the Uno?

Also, when changing numCharsSlave to 600, I receive this:

Rain sensor: 1
Sensor light: 2.22
Sensor humidity: 3.33
Sensor temperature: 4.44
API rain: 5.55
API temperature: 6.66
API temperature feels: 7.77
API humidity: 8
API wind: 123456789012345678901234567890123456789012
API weather:
API Text tomorrow:
API Text tomorrow night:

Wouldn't it make a whole lot more sense to send the data in two or three or four separate messages so that you don't need to receive it all at once and don't need to create the huge buffer?

...R

I am using Arduino Mega for the master.

So why are you f**king around with SoftwareSerial on the Mega? Connect the other Arduino to TX1/RX1, TX2/RX2, or TX3/RX3 and use the correspond hardware serial instance!

I connected to Tx3 and Rx3. It still doesn't receive the whole data.

I will modify the code and send them seperately limiting the buffer to 150. If I manage to do it, I will post the code here.