MATLAB could not read multi-line serial port data using a loop

조회 수: 11 (최근 30일)
Miao
Miao 2016년 3월 2일
댓글: Miao 2016년 3월 3일
I'm designing a firmware with Arduino C. In my code, I try to send multi-line data to the MATLAB.
I tried two methods on the Arduino side:
TOTAL_ROWS = 16;
for (MY_COUNTER = 0; MY_COUNTER < TOTAL_ROWS; MY_COUNTER++) {
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
}
Serial.println("Batch read complete");
or
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
Serial.println("Batch read complete");
You can see they should give exactly the same output to the MATLAB and I have verified it using the serial monitor embedded in mpide compiler.
On the MATLAB side (MATLAB version: 2015a) I try to use the code below to receive the data:
serConn = serial('COM1','BaudRate', 115200, 'InputBufferSize', 16784);
fopen(serConn);
readLines = 1;
Batch_DATA{readLines} = fscanf(serConn);
display(Batch_DATA{readLines});
while ~strcmp(Batch_DATA{readLines}(1:5),'Batch')
readLines = readLines + 1;
Batch_DATA{readLines} = fscanf(serConn);
display(Batch_DATA{readLines});
end
Surprisingly, with the first Arduino I can only get "Batch read complete" in Batch_DATA (1x1 cell), and only with the second Arduino code I get get all the data in Batch _DATA(1x17 cell).
I find it hard to explain and give me a lot of trouble in serial communication. Anyone encountered the same problem?
  댓글 수: 3
Miao
Miao 2016년 3월 3일
I have added a delay from 1us to 500ms in the loop, as below:
TOTAL_ROWS = 16;
for (MY_COUNTER = 0; MY_COUNTER < TOTAL_ROWS; MY_COUNTER++) {
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
// delaymicroseconds(1);
// delay(500);
}
Serial.println("Batch read complete");
But nothing changes...the data is definitely sent from the Arduino hardware not but forwarded to the input buffer of MATLAB. The only thing I can catch for this case is "Batch read complete".
Another interesting thing is that if I add more "words" after the data, MATLAB can capture them as well. For example add these two lines right above Serial.println("Batch read complete");
Serial.println("Does MATLAB love word?");
Serial.println("Yes");
Serial.println("Does MATLAB hate data?");
Serial.println("Yes");
MATALAB can receive these words as well.
One last test, I change to loop into below:
for(int i = 0; i < 16; i = i + 1){
Serial.println("40025, 40081, 40093, 40085, 40084, 40096, 40069, 40081");
}
This one works, and if I replace 16 with TOTAL_ROWS then it does not work with MATLAB, but still work with the serial monintor.
It appears that the data must be sent fast enough to avoid being missed by MATLAB instead of adding delays.

댓글을 달려면 로그인하십시오.

채택된 답변

Miao
Miao 2016년 3월 3일
편집: Miao 2016년 3월 3일
I have fixed the problem by changing the way of reading commands from MATLAB in firmware. Originally I was using some code as below from some online tutorials:
while(Serial.available()>0) {
V_BATCH_READ = Serial.parseFloat();
}
I change it to the code below and the problem is fixed:
while(Serial.available()==0) {}
V_BATCH_READ = Serial.parseFloat();
First I want to confirm both methods work with the mpide serial monitor. Why the first code cause problem with MATLAB?
I guess it's because when using MATLAB to send the command, it sends something extra and causes the data reading problem. I don't know why the mpide serial monitor would be different from the MATLAB's, but anyway here is the lesson I learned: don't use the first way to enter your command in firmware if you are communicating with MATLAB...
  댓글 수: 2
Walter Roberson
Walter Roberson 2016년 3월 3일
The first code stops the loop as soon as Serial.available is false. But it can be false if there is no data available because it has not been received yet due to delays in transmission.
Contrawise of there was data queued after the parseFloat (perhaps because more was being received quickly) the first code would read it and overwrite V_BATCH_READ with the new value.
The second version of the code spins until data is available and then reads one group, and does not try again to see if there is more.
Miao
Miao 2016년 3월 3일
Thanks a lot for your comment, Walter.
I'm curious that why MATLAB serial port is different with the mpide one. Is it mainly due to the delay? It feels that mpide serial monitor is also much faster than the MATLAB one.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 MATLAB Support Package for Arduino Hardware에 대해 자세히 알아보기

태그

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by