2
votes

I'm using the analog pins of an Arduino to measure voltage and print it to the serial port with serial.print(string). This is working, it outputs one value in the form of xxxx.yyyy with varying length, this I checked with the build in serial viewer. To read it, I'm using Matlab with fscanf() or fgetl(). This shows the correct thing, aaaa.bbbb, but with a weird kind of delay. When I change the voltage, the reading lags behind 5-10 seconds, but when I increase the voltage from 0 to 3 to 5, within this timeframe, like 3 seconds between 3 and 5, the reading changes as well. It does not in the same way as I changed the voltage, but it does get these values, as if it were 2 step inputs, even though I changed them by hand not super fast.

When reading and researching, I came across the fact that maybe the BaudRate was too low, so I changed it to the maximum of the Arduino at 115200. I changed the value in the Matlab code as well. I also tried the Arduino Hardware support package, with the readVoltage() function, but this has a too low sampling rate.

The settings for the serial port:

s = serial('com3');
set(s, 'BaudRate', 115200); % set BaudRate to 115200
set(s, 'Parity', 'none'); % set Parity Bit to None
set(s, 'DataBits', 8); % set DataBits to 8
set(s, 'StopBit', 1); % set StopBit to 1
set(s,'Terminator','LF') % set terminating character to LF/new line
fopen(s);

The reading loop:

for i =1:am
    val(:,i) = string(fgetl(s));    %retrieve value of serial port, in the form aaaa.bbbb where a and b can vary in length
    if mod(i,10) == 0           %Display every 10 iterations
        volt1 = floor(val)*5/1023;          %Calculating actual voltage for A1, where floor(val) is first value
        volt2= (volt1-floor(val))*5/0.1023;         %getting only decimals for second voltage
        plot(volt1)         %plot the values
        hold on
        plot(volt2)
        hold off
        ylim([0 5])
        xlim([i-1000 i])        %make the plot chug along
        drawnow                 %Live
    end
    clc
    toc
end

There are no error messages and using the other serial port, I had no visible delay. This should also be possible with Matlab, as people get refresh rates of 2-3kHz using this.

1
Are you sure set(s,'Terminator','LF') is correct? Does the transmitting side actually transmit a "line feed" character at the end of each transmission?Rotem
How is it working at all? You are using floor(val), but val is a string?Rotem
@Rotemthat is a very interesting point you make, the values saved in matlab val aren't strings, but when I remove the string command, it reads the value in the serial port as individual characters, instead of one number. As for the terminator statement, in the arduino code, every string is followed by '\n'6Steven8
@Rotem I'm not entirely sure what the terminator statement should be, but I believe it was used this way in another script6Steven8

1 Answers

0
votes

The problem is the way you are using plot in a loop. This is very inefficient.

Depending on your Matlab version and the overhead on your serial link you might be able to speed things up calling clf at the beginning of the loop to prevent a wild number of plots stacking on top of each other.

If the problem persist you might want to try animated line and addpoints in the loop.

Finally, there are a couple of things you might want to check: the Arduino connection for Matlab (I never tried it myself but I've read it gives good performance) and the latency timer on your serial port (that might be having an effect at low baud rates).