Real time audio data plot from COM/serial port
Afficher commentaires plus anciens
need to know how i can plot audio data in real-time from serial port. am getting error using this code.
clear; clc;
%create a serial object
s= serialport("COM4", 115200);
%open serial port
fopen(s);
%plotting data
i= 1;
while(1)
data(i)= str2double(fscanf(s));
plot(data);
pause(0.01);
i= i+1;
end
%error i am getting is---
Error using fopen
First input must be a file name or a file identifier.
Error in pltsril (line 5)
fopen(s);
Réponses (1)
Cris LaPierre
le 7 Avr 2023
0 votes
fopen does not work with a serialport object. See the available methods here:
27 commentaires
Walter Roberson
le 8 Avr 2023
Modifié(e) : Walter Roberson
le 8 Avr 2023
Or sscanf(readline(s)) if the information is formatted as text.
Also consider using animatedline
Kulbir
le 10 Avr 2023
Walter Roberson
le 10 Avr 2023
How are you reading the audio data?
Walter Roberson
le 11 Avr 2023
device = serialport("COM3",9600)
write(device,1:5,"uint8");
read(device,5,"uint8");
h = animatedline('MaximumNumPoints', 10000);
start = tic;
while(1)
data = str2double(fscanf(device));
now = toc(start);
addpoints(h, now, data);
drawnow limitrate
end
Kulbir
le 13 Avr 2023
Cris LaPierre
le 13 Avr 2023
Your workspace is conspicuously empty. I would expect to see device, data, now and other variables created by your script appear there.
Kulbir
le 13 Avr 2023
Cris LaPierre
le 13 Avr 2023
Modifié(e) : Cris LaPierre
le 13 Avr 2023
The error message is stating that you are not connected to the serial port device.
I suggest adding the following to the bottom of your script to clear your serialport object each time.
clear device
I would also suggest not using fscanf with a serialport object. Try this.
data = str2double(readline(device));
Walter Roberson
le 13 Avr 2023
Cris beat me by a small number of seconds in pointing out you need readline().
Kulbir
le 13 Avr 2023
Kulbir
le 13 Avr 2023
Walter Roberson
le 13 Avr 2023
Did you possibly close the drawing figure?
Your code has no natural way to stop. If you tried to stop by closing the figure then you would get exactly the message you saw about needing a handle.
Cris LaPierre
le 13 Avr 2023
I'll add the observation that the result of your read command appears to have been successful (variable ans in the Workspace has values), but data is NaN. Are you sure your device is streaming anything?
Kulbir
le 13 Avr 2023
Kulbir
le 13 Avr 2023
Walter Roberson
le 13 Avr 2023
For testing purposes, please try this:
device = serialport("COM4",9600)
write(device,1:5,"uint8");
first_5 = read(device,5,"uint8");
fprintf('Not sure why we are reading 5 bytes, but the values received were:\n');
disp(first_5);
h = animatedline('MaximumNumPoints', 10000);
start = tic;
while isvalid(h) && toc(start) < 30 %FOR TESTING
currentline = readline(device);
data = str2double(currentline);
if isnan(data)
fprintf('data nan, line as text was: "%s"\n', currentline);
continue;
end
now = toc(start);
if isvalid(h)
addpoints(h, now, data);
drawnow limitrate
end
end
At this point I would not be surprised if it turned out that each line of data received is text with multiple numeric values.
Kulbir
le 13 Avr 2023
Cris LaPierre
le 13 Avr 2023
It would be more helpful to see the results in MATLAB
Kulbir
le 13 Avr 2023
Kulbir
le 13 Avr 2023
Kulbir
le 13 Avr 2023
Walter Roberson
le 13 Avr 2023
So far, except for the first 5 bytes, your code has been as-if the data being sent from the other side is text. For example your existing code is expecting to receive lines similar to
0.15180
-0.3351
as text .
But the other end is not sending text, it is sending binary values. Instead of using readline() and str2double(), you need to use read . But to use that successfully, you need to know what format the other end is sending the samples. The most common data formats would correspond to
read(device, 1, 'uint8') %8 bit unsigned data
read(device, 1, 'uint16') %16 bit unsigned data, little-endian
read(device, 1, 'float') %32 bit single precision, little-endian
swapbytes(read(device, 1, 'uint16')) %16 bit unsigned data, big-endian
swapbytes(read(device, 1, 'float')) %32 bit single precision, big-endian
but there are other possibilities as well.
For example, it would not be uncommon to send packed 12-bit data, 2 samples stored across 3 bytes.
Kulbir
le 13 Avr 2023
Kulbir
le 13 Avr 2023
Walter Roberson
le 13 Avr 2023
Using readline(device) is not going to be useful for you. You need to find out what data format the device is sending, and you need to use read() of the device, probably using one of the commands I showed above.
What model of device are you reading from?
Kulbir
le 14 Avr 2023
Catégories
En savoir plus sur Multirate Signal Processing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!







