Arduino communication with MATLAB is too slow
28 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
I recently tried to connect my arduino Uno with MATLAB R2014a. In mathworks.com they suggest the use of the following new package http://www.mathworks.com/hardware-support/arduino-matlab.html
Now it seems that many commands that existed in previous versions are no longer supported (e.g. analogRead is now readVoltage) My problem is that the communication between MATLAB and Arduino is VERY slow. I timed a readVoltage() command and it takes about 25-35 ms to read the voltage of an analog pin. Is that as fast as it can get? I hope not! But what am I missing here?
You can see what I mean in the attempted real time plot that I'm trying to do below...
a=arduino();
interv=50;
elapsed_time=0;
figure
initial_time=tic;
while(elapsed_time<interv)
elapsed_time=toc(initial_time);
b=readVoltage(a,0);
plot(elapsed_time,b)
hold on
end
clear a
0 Commenti
Risposte (3)
Klont
il 16 Mar 2015
i get the same ~30 ms latencies on my setup (windows 7, asus n550jv laptop, aduino uno r3, matlab 2014b). very disappointing. does anyone know how fast the equivalent calls are in when using compiled C-code?
0 Commenti
Maarten
il 21 Mag 2015
I have the same problem if I read multiple analog ports. However your code could be faster if you do not update your plot within the loop. Without plotting I have a sample time of around 70 Hz.
a = arduino(serialPort);
input = nan(1,round(time/dt));
sampleRate = nan(1,round(time/dt));
i = 1;
h = waitbar(0,'Reading sensor output');
tic
while toc < time
tstart = tic;
waitbar(toc/time,h);
input(1,i) = readVoltage(a,0);
sampleRate(1,i) = toc(tstart);
i = i+1;
end
close(h)
plot(sampleRate)
5 Commenti
Walter Roberson
il 23 Mar 2016
I recommend that you do not name a variable "input" as that interferes with using the input() function.
What speed (baud) do you have the arduino configured to communicate at?
Kiki
il 29 Mar 2016
Hi
The baud I use is 115200. Do I just set the baud rate for the arduino, or do I need to write other functions in my arduino code in order to use the readVoltage() function?
Brian Rasnow
il 19 Ott 2022
Modificato: Brian Rasnow
il 19 Ott 2022
The Arduino package has enormous overhead, both in Matlab, and on the Arduino. I program the Arduino in C using its IDE to respond to simple commands, e.g.,
const int analogOutPin = 5;
#define NUMSAMP 400
int data[NUMSAMP + 1][2], i;
unsigned long t0, t1;
void measureWaveformsBinary()
{ //read A0 and A1 NUMSAMP times and return with the elapsed time
t0 = micros(); // time it to compute sample rate
for (i = 0; i < NUMSAMP; i++)
{
data[i][0] = analogRead(A0);
data[i][1] = analogRead(A1);
}
t1 = micros();
data[i][0] = t1 - t0; // put dt at end of data
data[i][1] = (t1 - t0) >> 16; // most significant 2 bytes
Serial.write((uint8_t*)data, (NUMSAMP + 1) * 2 * sizeof(int));
} // measureWaveformsBinary
void setup()
{
Serial.begin(115200);
pinMode(analogOutPin, OUTPUT);
} // setup
void loop()
{
if (Serial.available())
{
switch (Serial.read())
{
case 'p': // set pwm value
{
int pwmVal = Serial.parseInt();
analogWrite(analogOutPin, constrain(pwmVal, 0, 255));
break;
}
case 'b':
{
measureWaveformsBinary();
break;
}
} // switch
}
delay(1);
} // loop
Upload that code to the Arduino in the IDE, then quit the IDE or disconnect it from the Arduino (set menu Tools -> Port -> to anything else), since serial devices can't be shared between apps. In Matlab, open a serial port to the Arduino. I haven't found a great way to identify the Arduino in the port list, but on my Macintosh, it's always the last in the list so, in Matlab:
ports = serialportlist;
ard = serialport(ports{end},115200)
ard.Timeout = 1;
clear ports;
pause(1); % time to boot
To read and plot the data, send the 'b' character to the Arduino and then read the buffer. readLine and writeLine work for ascii data, but the buffer size isn't predictable, and binary is faster:
write(ard,'b','char');
bin = read(ard,802,'int16');
dt = bitshift(bin(802),16)+bin(801); % microseconds
data = reshape(bin(1:800),2,400)';
t = linspace(0,dt/2/1000,400)'; % calibrate the time axis
plot(t, data, '.-')
xlabel('msec'); ylabel('ADU')
legend('A0','A1');
Data is read at ~8.9kHz, each channel half of that and there is channel skew (which spline or fft can fix). This loops around 3 times per second, with plot being the bottleneck. h = plot(...) the first time, and changing the line data in the graphics objects speeds that up significantly. Want faster? I could get >20 frames per second with a Raspberry pi Pico or Teensy microcontroller (and 12 bits ...).
Added a uicontrol radiobutton to a figure to toggle an oscilloscope display, and you can nicely see audio waveforms and the like, using just Matlab and a $5 microcontroller.
0 Commenti
Vedere anche
Categorie
Scopri di più su MATLAB Support Package for Arduino Hardware in Help Center e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!