Arduino-Matlalb/Simulink Real Time DAQ problem

Hi,
I'm interfacing an Arduino Uno with matlab, using the arduino as a real time DAQ and PWM generator.
Arduino receives a duty cycle value to generate the right PWM wave and sends back a couple of analog inputs, all real-time, all through the usb communication interface.

The time it takes for the arduino to send back a value via USB and for matlab to receive it is mostly around 1-0.7 ms, but every few fractions of second the delay jumps up to 20-25x higher at 20-25ms.

I'm using the arduino as a real time daq: Simulink uses the real time data to compute a quite complex control scheme (model predictive control). The system is very slow (useful modes between 0.1Hz and 2Hz) so i don't need extreme sampling speeds, but 25ms leaves me a too tight margin to compute the control action, which must run at a fixed frequency.

I tried to use the Matlab-Arduino package (provided on the Mathworks website) and the results were similar but with even more peak latency.

I'm using just a Serial.println(sensor_value) on the arduino side and an fscanf(serialPort,'%s') on the matlab side, with the right tricks to acknowledge the data in the right format.

Anyone can help? Is this an interface limit?

Thank you

Arduino's code:

int ledPin = 13;
int sensorPin = A0;
int num;
int matlab=0;
int start=0;
short sensor;
void setup() {
Serial.begin(115200);
pinMode(ledPin,INPUT);
pinMode(A0,INPUT);
}

void loop() {

while(Serial.available()>0) {
start = Serial.read();
delay(1);
}
while(start==1){
sensor = analogRead(A0);

Serial.println(sensor);
delay(10);
}
}

-Matlab's code:

%receive and convert an int from
% 0 to 1023

clc
clear all
serialPort=serial('COM4','BaudRate',115200); %port initialization
set(serialPort,'InputBufferSize',5)
set(serialPort,'Timeout',2)
fopen(serialPort); % port opening
i=1;
tic
disp('start')

while(serialPort.BytesAvailable == 0)
fprintf(serialPort,'%s',char(start)); % send answer variable content to arduino
disp('connecting')
end

disp('connected')
while(i < 1000)
if(serialPort.BytesAvailable > 0)
tic
data_received = fscanf(serialPort,'%s',4);
data_received = [data_received fscanf(serialPort,'%s')];
duration(i) = toc;
data(i) = str2num(data_received);
i = i+1;
end
i
end
fclose(serialPort);

Anyone can help?

Without seeing your code? No.

It's there now, enjoy! :stuck_out_tongue:

(deleted)

spycatcher2k:
Dont use delay in your code - There is no need to ever use it.

For some reason, sometimes, on the matlab side the scan attempt times out/fails if i let arduino write without a delay between a cycle and another.

Actually it's not the first case where i find out that a short delay is needed to make the processor of a peripheral digest an instruction, update buffers, etc...

For some reason, sometimes, on the matlab side the scan attempt times out/fails if i let arduino write without a delay between a cycle and another.

In terms of sending data periodically, you have two choices. First, sit on your ass doing nothing while delay() wastes some time. Second, use millis() to see if enough time has elapsed since you last sent data to mean that it is time to send data again.

When Robin2 said that delay wasn't necessary, he was absolutely correct. That doesn't mean that some other method of not spamming the receiver isn't required.

  pinMode(A0,INPUT);

Setting the nature of the digital pin, and then using the pin as an analog pin is pointless. Get rid of this. Analog pins are input ONLY. You can't make an analog pin output.

Your choice of variable types is interesting. The variable that will hold one character is an int, while the one that will receive a value between 0 and 1023 is a short. Why? Just how big is a short? Will it hold the required range of values? If it saves any memory, is that memory savings needed? Does it warrant using a non-standard type?

Once the Arduino starts sending data, there is no stop. Is that reasonable?

Simulink uses the real time data to compute a quite complex control scheme (model predictive control).

Could have fooled me...

@stretch: did any of the suggestions help with the issues reported? Were you able to diagnose the culprit?