UART Problem data sometimes sends

Hi guys, so I am trying to read data through the uart using Serial1 on the arduino due. I'm sending it through as a string which has about 15 characters give or take depending on the data.
Currently I'm using this code to turn it into a string:

String test="";

void setup()  
{
  Serial.begin(19200);
  Serial1.begin(19200);
}

void loop() 
{  
  // Send data from the software serial
  if (Serial1.available()) {
    test="";
     while (Serial1.available()) {
       test=test+(char)Serial1.read();
     }
  }
    Serial.println(test);
}

Which prints fine when I test it, but I then add a few more code by adding dataSetting () to get the string and slice it up into multiple pieces, similar to:

String test="";

void setup()  
{
  Serial.begin(19200);
  Serial1.begin(19200);
}

void loop() 
{  
  // Send data from the software serial
  if (Serial1.available()) {
    test="";
     while (Serial1.available()) {
       test=test+(char)Serial1.read();
     }
  }
    Serial.println(test);
    dataSetting ();
}

void dataSetting () {
int z= 0;
location = "";
weather = "";
temperature = "";

      while(test[z] != '-')
    {
     location += test[z];
     z++;
    }
    Serial.println(location);
}

Where the minus sign is the stopping point for the location string. The problem is if I put the code I wrote at the top, everything works perfect, but when I add a call to dataSetting(); after the Serial.println(test); part then nothing works anymore. Even if I just place a Serial.println("hello"); Within the if (Serial1.available()) {} part nothing prints out through the serial monitor. I'm unsure why having a bit of code works, but adding a little bit more ruins it :(. Ive tried placing the dataSetting part into the loop code but still get the same result.

Any help would be great
cheers

If you are posting code or error messages, use "code" tags

Tips for getting the most out of your post:

Post a complete sketch (program code)! If you don't you waste time while people ask you to do that. However, with coding problems, if possible post a "minimal" sketch that demonstrates the problem - not hundreds of lines of code. If the problem goes away in the minimal sketch, it wasn't where you thought it was.

My bad, its 1:30 am here, and I am very very very tired haha, cheers, will definitely keep that in mind.

trustnoone:
My bad, its 1:30 am here, and I am very very very tired haha, cheers, will definitely keep that in mind.

I'm still not seeing a complete sketch.

Yeah, just quickly went to brush my teeth, updated now.

Once you get to the

dataSetting ();

call in your code, what's in the input buffer better have a '-' or your system will enter an infinite loop here:

 while(test[z] != '-')
    {
     location += test[z];
     z++;
    }

which would cause it to run rampant on your memory, going completely out-of-bounds of the array. Perhaps it would be a good idea to post what you're inputting and what you're expecting to get as an output to give us a better idea of what you're trying to accomplish.

Oh yeah good idea, basically a string is placed through that is in the context of
location-weather-temperature.
for example
Tokyo-Rainy-23C

But so far I only want the location part, the sending gets placed through 1 bit at a time.

So from what I am aware there should be a minus sign, but unfortunately I can't test to see what I am receiving as placing a Serial.println(test); doesn't show any data, unless I comment out dataSetting (); then the println works fine.

I'm unsure what you mean by once I get to dataSetting (); call in my code??

Cheers heaps

I think the problem is that you are assuming when you send it the string

Tokyo-Rainy-23C

That every byte will be instantly available, so the call to Serial.available() will return 15. The reality is that Serial communication is much slower than the Arduino; the loop() function could run hundreds of time between characters reaching the Serial buffer, so you aren’t likely to get more than 1 (the first time, at least, as Serial.prints will slow it down enough). So the first time dataSetting() is called, you’re likely to only have “T” as your string. Because a ‘-’ hasn’t been read yet, you’ll get stuck in an infinite loop.

The band-aide fix would be to use delay(). This will allow all the characters to be received before processing the input. This isn’t recommended because it will block the microcontroller from doing anything else while it wait for the slow Serial input. The delay time will also need to be dependent on the baud rate. The proper way to fix it would be to use a deliminator character (the Arduino Serial Monitor supports automatically appending ‘\n’ and/or ‘\r’) that would signal the end of the input. Data would only be processed once it sees that character. Simple example:

const byte BUFFER_SIZE = 20;  // how many characters we can store in the buffer
const char EOP = '\n'; // when a new line character is received, process the input
char buffer[BUFFER_SIZE + 1]; // plus 1 for the null-terminator
byte index = 0; // keeps track of the next free spot in the buffer

void setup()
{
  Serial.begin(115200);
  Serial.println("begin");
}

void loop()
{
  if (Serial.available() > 0) // if there is an available character
  {
    char inByte = Serial.read(); // read it

    if (inByte == EOP) // if it's our deliminator character
    {
      buffer[index] = '\0'; // null terminator our string
      processInput(buffer); // process the input
      index = 0; // reset the index for the next input
      buffer[0] = '\0'; // clear the buffer string for the next input
    } 
    else if (index < BUFFER_SIZE) // only add to buffer if no overflow occurs
    {
      buffer[index++] = inByte; // add byte to buffer and increment index
    }
  }
}

void processInput(char *input)
{
  // do something with the input string. In this example, print it.
  Serial.print("I received ");
  Serial.println(input);
}

There is also an “in-between” solution that uses time as the deliminator, but doesn’t block. Take a look at my post history if you want that example.

Oh thanks heaps, I've been having a look at things such as block, but I'm really surprised to hear that the data is sent so slowly, I kind of figured it was more like a small time of the loop function, not enough time that the loop can actually go through. I'm debating now whether its easier to use a delay, my code will later update an LCD display, but since weather data changes very slowly, I don't mind too much on having a delay in place. The problem is I also have a servo I want to move for a second part, which I don't mind if the delay is a few seconds, but may be bad if the delay is more then that.

Either way though your example code does sound interesting, and probably the best and safest way to go coding wise, I think I might go to sleep now, but going to try your code tomorrow, and will report how it go's. Thanks heaps for that, kind of an eye opener on the UART as well haha. Cheers

Okay tested what you said and you're right :D, turns out it was getting stuck in a loop, I tried a test just to make sure that the string being passed through is correct or not, and to kick out the loop if it isn't and it works great now, still curious in seeing your code though as it might work even better.

Random question though, I have an int value, that I want to round to the closest 5 so for example
13 rounds to 15
and 12 rounds to 10
Also -3 rounds to -5
Is there a simple way to implement this? I've been looking at the round function but as far as I can tell only rounds to the closes integer, I tried dividing by 10, rounding, then multiplying by 10, but this of course only rounds to the closest 10. Was hoping for something kind of simple, but if thats not possible thats okay as well, and I might look up making my own round function.