Matlab - serial read bug

What I want to do is to sample an analog voltage from an Arduino pin (0 to 5 V, read as integer values from 0 to 1024), and transmit these samples to Matlab to be plotted. The code below is for the Arduino, it sets up the serial port and then in the loop it reads the voltage from pin 1, sends it to the serial port using “Serial.println”, pauses and then keeps repeating this. The sample rate is set by the pause length.

int analogPin = 1; // Analog read pin. This is the e.g. photodiode input
int result;
int sample = 100; // Sampling period (ms)
int Baud = 9600; // Serial baud rate

void setup() {
  pinMode(analogPin,INPUT);
  Serial.begin(Baud); // Setup serial port
  delay(1000); // 1 sec delay
}

void loop() {
  result = analogRead(analogPin); // read the analog pin
  Serial.println(result);
  delay (sample);
}

The following Matlab code configures and opens the serial port, and reads the serial port 100 times and saves these sample values to “y”. The results are then plotted.

clear all
clc

baud = 9600;
arduino=serial('COM3','BaudRate',baud);
 
fopen(arduino);
 
x=linspace(1,100);
y=zeros(1,100);   
for i=1:length(x)
    y(i) = fscanf(arduino,'%d');
end
	
fclose(arduino);
disp('making plot..')
plot(x,y);

When I have a relatively long delay between sampling the pin (say, 100 ms), everything works perfectly. I switch the input to pin 1 between the 3.3 V and 5 V pins on the Arduino, and the correct values are plotted in Matlab. The problem I encounter is when I decrease the sampling rate (to, say 1 ms). I get the following error:

Warning: Unsuccessful read: Matching failure in format..
In an assignment A(I) = B, the number of elements in B and I must be the same.
Error in Testexample (line 12)
y(i) = fscanf(arduino,'%d');

I guess I’m having a problem with reading the serial data, either Matlab is reading in more than one value, or there’s no value to read, and the error occurs because the array y(i) will only accept one entry per column? The data looks fine on the Arduino serial monitor, it looks the same there regardless of the sampling rate.

I don’t really know how to troubleshoot this further, so any pointers would be appreciated.
Thanks!

As MatLab reference page say

"A = fscanf(obj) reads ASCII data from the device connected to the serial port object, obj, and returns it to A. The data is converted to text using the %c format. For binary data, use fread."

So try with fread, maybe then you will need other specifications in the arduino sketch, and you should use serial.write instead of serial.print. Maybe the endline characted is confusing the matlab reader.

In my (little) experience, when using a serial communication is better to work with bytes instead of "human readable" characters but probably someone more experienced will say that the best approach depends on the case.

Let me know if it works in this way.

Regards,
FrAxl

Hi FrAxl,

On your advice I changed the line in my Matlab script:

From y(i) = fscanf(arduino,'%d');

To y(i) = fread(arduino,1,'uint8');

On my Arduino code, I changed the "void loop" so that the AnalogRead value (which is usually a value from 0 to 1023) is now mapped to a value between 0 and 255. The idea behind that is to map the AnalogRead value to a single byte - I copied the idea from: here

New void loop code:

void loop() {
  result = analogRead(analogPin); // read the analog pin
  outputValue = map(result, 0, 1023, 0, 255);
  Serial.write(outputValue);
  delay (sample);
}

Now it seems to work fine, even when I shorten the sampling time on my Arduino to 1 ms (from 100 ms).

Thanks for your help!