Help: how to break this while loop in my Arduino Leonardo code

Hello folks:

I can not figure out how to break out this while loop in my arduino project. Basically, I am sending out an array of data from my Matlab code to Arduino program through serial communication. My matlab code is sending out an array data to the COM, based on what I type in the command widow of matlab. For example, if I type 1, the data [-100, 1] will be sent to the COM. My arduino takes the input. When t = 1, the while loop starts running. The way I try to break out the loop, is simply to set the if statement with break. So when I type a number other than 1 ( e.x. 2 or 3 ) in my matlab console, the arduino code takes [-101;2] or [-102;3] and should break the while loop. But it doesnt work the way I want when I use the serial monitor to track the update. Basically once the while loop has started, I am not able to break it by typing a number 2 (or any other number) in my matlab code. I am running of ideas. Hope someone here can help spot the problem. Thanks a lot.

Note: both my matlab and arduino code can run.

Matlab code ( generate the number and send into the serial communication)

function serialOutput

delete(instrfindall);
clear all
clc 

% the serial port number corresponding to the port the leonardo cable
% connects
 arduinoCom = serial('COM21','BaudRate',115200 );  % insert your serial
 fopen(arduinoCom);
 answer = input('what setting do you like 1, 2, 3');
 switch answer
     case 1
         data = [-100;1];
         fwrite(arduinoCom,data,'int16');
         data
     case 2
         data = [-101;2];
         fwrite(arduinoCom,data,'int16');
         data
     case 3
         data = [-102;3];
         fwrite(arduinoCom,data,'int16');
         data
 end
 end

My arduino code ( the leonardo has Serial1 (not Serial) to have the serial communication with external serial device)

byte data1[2];
byte data2[2];
int f;
int t;


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

void loop()
{
  
    if(Serial1.available()>0) {
      data1[0] = Serial1.read();
      data1[1] = Serial1.read();
      data2[0] = Serial1.read();
      data2[1] = Serial1.read();
   
      f = 256*data1[1] + data1[0];
      t = 256*data2[1] + data2[0];
      while (t == 1) {
            Serial.println(f);
            Serial.println(t);
            if(t!= 1){
              break;
            }
            delay(1000);
     }
    }
  
   delay(10);
 }

There is something fundamentally wrong with how you are dealing with the serial input to the Arduino.

  if(Serial1.available() > 0)

This checks whether there is serial data available but does not check how many bytes there are.

    data1[0] = Serial1.read();
    data1[1] = Serial1.read();
    data2[0] = Serial1.read();
    data2[1] = Serial1.read();

Without knowing how many bytes are available you immediately read from serial 4 times. At best the results are going to be erratic.

If you know that you will always be receiving 4 bytes then read each of them as they become available and do not assume that because one byte is available that you can sensibly read four.

hi UKHeliBo,

Thanks alot for taking time to diagnose my code. The reason I Serial1.read() 4 times is that I send out 4 bytes from my matlab code. So that part code should be working properly, which I tested this part already. I think something is wrong with the way I wrote the while loop.

     f = 256*data1[1] + data1[0];
      t = 256*data2[1] + data2[0];
      while (t == 1) {
            Serial.println(f);
            Serial.println(t);
            if(t!= 1){
              break;
            }
            delay(1000);
     }

How can t = 1?

Even supposing t = 1 when you enter the WHILE loop there is no code within the loop to change the value of t - hence you have an infinite loop.

In a situation like this get into the habit of taking pencil and paper and working through the code manually line by line. That would immediately have shown you that t was not changing.

If the loop works because t = 1 there is not a lot to be gained by printing the value of t?

Why not lose the WHILE temporarily and just print out the two values.

Perhaps you should just replace the WHILE with IF ???

...R

33chen: hi UKHeliBo,

Thanks alot for taking time to diagnose my code. The reason I Serial1.read() 4 times is that I send out 4 bytes from my matlab code. So that part code should be working properly, which I tested this part already.

You are wrong about this. If you did a test it was not correct. Bytes arrive one at a time, much slower than the arduino can read them. So there could be one byte in the buffer with the others comming. The arduino will then try and read four bytes with only one of them being real.

Thank you very much Robin and Grump_Mike.

To Robin, yes, I am thinking to use the IF statement. The reason I want to use while loop is that I want to run some complicated code inside it continuously. And at the same time, if I want to break out of the while loop, I can send a number from my matlab code to break it successfully. I did not post the code here. The Serial.println() inside the while loop here is just the way I want to demonstrate if my idea works. As you can way, after the value of serial.println() runs continuously on my serial monitor, I am not able to break it. I am pretty sure that a number has been sent to my arduino from serial communication ( LED light flash once). Do you have any other idea to break the while loop or if there is another way to run something continuously.

To Grump_ Mike, I want to want to explore more about the issue of Bytes.

“Bytes arrive one at a time, much slower than the arduino can read them.”

I think that is the reason my Serial1.available() works fine since the Arduino would not miss any byte coming to memory. I have spent a mount of time checking the reliability of data. But again I welcome any doubts and what would you think the best way to read the bytes coming in? Thanks again.

If you want to read four bytes then in the if statement simply do not proceed until the bytes avaliable is greater than three.

33chen: after the value of serial.println() runs continuously on my serial monitor, I am not able to break it. I am pretty sure that a number has been sent to my arduino from serial communication ( LED light flash once).

Something may be sent but how can it get inside the WHILE loop? You must do something to the value of t inside the loop if you want to break out of it OR you must do something else which uses the command break; In your case you are using t (which never changes) for the control of WHILE and to trigger BREAK. Either do something to make t change or use some other basis for calling BREAK.

...R

Thanks Grumpy_Mike and Robin 2 for the insights.

To Robin,

Just curious wheter or not the lines in our old Arduino code can break out of the while loop. I set the loop breaks when t is not 1 (t != 1). IS that not enough? Apparently yes, it didnt break out once I applied it to my test. What do you think is the problem with these lines of code. Thanks again.

byte data1[2];
byte data2[2];
int f;
int t;


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

void loop()
{
  
    if(Serial1.available()>0) {
      data1[0] = Serial1.read();
      data1[1] = Serial1.read();
      data2[0] = Serial1.read();
      data2[1] = Serial1.read();
   
      f = 256*data1[1] + data1[0];
      t = 256*data2[1] + data2[0];
      while (t == 1) {
            Serial.println(f);
            Serial.println(t);
            if(t!= 1){  [font=Verdana] %% when t is not equal to 1, it is supposed to break out of the while loop here.[/font]
              break;
            }
            delay(1000);
     }
    }
  
   delay(10);
 }

What do you think is the problem with these lines of code.

You are STILL reading data that has not arrived.

    if(Serial1.available()>0) {
      data1[0] = Serial1.read();
      data1[1] = Serial1.read();
      data2[0] = Serial1.read();
      data2[1] = Serial1.read();

Serial.available() will return 1 when the first byte arrives. That does NOT mean that it is OK read read 4 bytes.

33chen: Just curious wheter or not the lines in our old Arduino code can break out of the while loop. I set the loop breaks when t is not 1 (t != 1). IS that not enough?

I think your grey cells are on holidays - drag them back to work :) It can only get into the loop if t EQUALS 1 so how could it ever NOT EQUAL 1 when there is no code to change the value of t within the WHILE loop.

What do you think is the problem with these lines of code. Thanks again.

See above. See the same advice in earlier posts.

...R