Lettura di dati in non-blocking mode
L'esempio è riadattato dall'Help Center di Matlab alla pagina https://it.mathworks.com/help/matlab/import_export/read-streaming-data-from-arduino.html
La lettura dei dati viene fatta in non-blocking mode attraverso un'interrupt e l'avvio di una funzione di callback.
Codice da caricare in Arduino
Per prima cosa è necessario caricare in Arduino il seguente programma che manda in seriale i valori di un'onda sinusoidale, seguiti dai terminatori 'Carriage Return' e 'Linefeed'.
int i = 0;
// The setup routine runs once when you press reset:
void setup() {
// Initialize serial communication at 9600 bits per second:
Serial.begin(9600);
}
// The loop routine runs over and over again forever:
void loop() {
// Write the sinewave points, followed by the terminator "Carriage Return" and "Linefeed".
Serial.print(sin(i*50.0/360.0));
Serial.write(13);
Serial.write(10);
i += 1;
}
Inizializzazione DELLA porta seriale in matlab
Per verificare quali sono i dispositivi collegati alla porta seriale è sufficiente utilizzare la funzione serialportlist()
>> serialportlist('available')'
ans = 3×1 string
"COM1"
"COM3"
"COM13"
Supponendo che l'Arduino sia collegato alla COM13, il comando da utilizzare per inizializzare la comunicazione serale è:
>> arduinoObj = serialport('COM13',9600)
arduinoObj =
Serialport with properties
Port: "COM13"
BaudRate: 9600
NumBytesAvailable: 0
NumBytesWritten: 0
Show all properties
Una volta collegato l'oggetto è necessario inizializzare correttamente il terminatore
>> configureTerminator(arduinoObj,'CR/LF');
Successivamente è necessario "svuotare" (in inglese flush) l'oggetto seriale per cancellare tutti i vecchi dati dal buffer di ingresso:
>> flush(arduinoObj);
A questo punto è necessario inizializzare la proprietà UserData per immagazzinare i dati provenienti dall'Arduino:
>> arduinoObj.UserData = struct('Data',[],'Count',1)
arduinoObj =
Serialport with properties
Port: "COM13"
BaudRate: 9600
NumBytesAvailable: 10626
NumBytesWritten: 0
Show all properties
Realizzazione della funzione di callback in matlab
La procedura di lettura prevede l'utilizzo di una funzione di callback che viene avviata quando viene un nuovo dato (con il terminatore corretto) è pronto per essere letto dal buffer d'ingresso della porta seriale.
Nell'esempio la funzione di callback viene chiamata readSineWaveData che quindi si trova nel file readSineWaveData.m
function readSineWaveData(src, ~)
% Read the ASCII data from the serialport object.
data = readline(src);
% Convert the string data to numeric type and save it in the UserData
% property of the serialport object.
src.UserData.Data(end+1) = str2double(data);
% Update the Count value of the serialport object.
src.UserData.Count = src.UserData.Count + 1;
% If 1001 data points have been collected from the Arduino, switch off the
% callbacks and plot the data.
if src.UserData.Count > 1001
configureCallback(src, 'off');
plot(src.UserData.Data(2:end));
end
end
Ogni qualvolta viene invocata la funzione di callback, se non già aperta, apre una figura Matlab e vi realizza all'interno un grafico dei primi 1000 punti dati dell'onda sinusoidale creata da Arduino.
Avvio della comunicazione in Matlab
Per avviare la comunicazione è necessario settare la funzione di callback. Tale settaggio deve indicare la condizione di attivazione e il nome della funzione che deve essere attivata preceduta da @
>> configureCallback(arduinoObj,'terminator',@readSineWaveData);
Nel caso specifico la funzione viene attivata quand0 viene rilevato il terminatore.
Se si osserva la funzione di callback si nota che essa si disattiva automaticamente dopo aver disegnato il grafico dei campioni acquisiti. In generale per disattivare la comunicazione in non-blocking mode si utilizza ancora la funzione configureCallback:
>> configureCallback(s, 'off');