MATLAB: How to read multiple sensors through the serial

arduinosensorserial

Hello there, I want to read 4 sensor values into arrays and do DSP on them in MATLAB. I've already read the related issues in this platform.
I suppose my arduino code runs perfectly, but MATLAB throws an error saying "Index in position 2 exceeds array bounds (must not exceed 1)." at the second sensor reading line. Could you please help ? Thx 😉
% MATLAB code is as follows
clear all
clc
delete(instrfind)
arduino=serial('COM9');
set(arduino,'BaudRate',38400);
fopen(arduino);
%Handshake
fprintf(arduino,'R'); % Send Read Request to Arduino
x=linspace(1,500); % 500 samples are recorded
y = {}; % all data is thrown in y.
for i=1:length(x)
data =fscanf(arduino,'%d'); % '%d' get ints
y = char(data); % The incoming data is converted to characters
y = regexp(y, '\s*', 'split'); % The data is split up into spaces and in columns.
% Data format: data1-tab-data2-tab-data3-tab-data4
reading1(i,1)= y(1,1); % reads in column 1
reading2(i,1)= y(1,3); % reads in column 2
reading3(i,1)= y(1,5); % reads in column 3
reading4(i,1)= y(1,7); % reads in column 4
end
% Done reading !
fclose(arduino);
delete(instrfind);
reading1plot = str2double(reading1); % Converts data that is on cell array to double data



figure(1)
plot(reading1plot);
title('sensor 1'); xlabel('Sample Index'); ylabel('Analog Reading1');
reading2plot = str2double(reading2); % Converts data that is on cell array to double data
figure(2)
plot(reading2plot);
title('sensor 2'); xlabel('Sample Index'); ylabel('Analog Reading2');
reading3plot = str2double(reading3); % Converts data that is on cell array to double data
figure(3)
plot(reading3plot);
title('sensor 3'); xlabel('Sample Index'); ylabel('Analog Reading3');
reading4plot = str2double(reading4); % Converts data that is on cell array to double data
figure(4)
plot(reading4plot);
title('sensor 4'); xlabel('Sample Index'); ylabel('Analog Reading4');
end
Arduino Code:
int flag= 0;
int ctr = 0;
int ReadReq=0;
int reading1;
int reading2;
int reading3;
int reading4;
void setup() {
Serial.begin(38400);
cli();//stop interrupts
// Sampling rate is 1000 Hz.
//set timer1 interrupt at 1000 Hz
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
// set timer count for 100Hz increments
OCR1A = 1999;// = (16*10^6) / (1000*8) - 1
//had to use 16 bit timer1 for this bc 1999>255, but could switch to timers 0 or 2 with larger prescaler
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS11 bit for 8 prescaler
TCCR1B |= (1 << CS11);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei();//allow interrupts
}
void loop(){
if(Serial.available()>0) { // Check if any data has been sent by the PC
ReadReq = Serial.read();
if((ReadReq=='R')&&(flag == 0)){
ctr = 0;
flag= 1;
}
}
}
ISR(TIMER1_COMPA_vect) { // FREQ 1000 Hz.
if(flag == 1)
{ // takes 500 samples and send it to the MATLAB
reading1 = analogRead(A0);
reading2 = analogRead(A1);
reading3 = analogRead(A2);
reading4 = analogRead(A3);
Serial.print(reading1);
Serial.print("\t");
Serial.print(reading2);
Serial.print("\t");
Serial.print(reading3);
Serial.print("\t");
Serial.print(reading4);
Serial.print("\n");
ctr = ctr + 1;
if(ctr == 499)
{
flag = 0;
}
}
};

Best Answer

You have
data =fscanf(arduino,'%d'); % '%d' get ints
so data will be a vector of numbers, text representation of decimal having been converted to numeric form
y = char(data); % The incoming data is converted to characters
This implicitly looks up the character codes associated with each numeric value, such as 97 being associated with 'a' . For example '97' received in text form from the arduino would have been converted to 97.0 decimal by the fscanf(), and char(97.0) would be 'a'
y = regexp(y, '\s*', 'split'); % The data is split up into spaces and in columns.
This splits at any number of whitespace, including none. This will happen to work the same as if you had specified '\s+' . But remember for char(data) to match whitespace, the data would have had to be numeric 9 (tab), 10 (newline), 12 (formfeed), 13 (carriage return), 32 (space), and possibly some others. As in if the arduino had sent '49 50 9 51 52 53 9 54' which got parsed to [49 50 9 51 52 53 9 54] and then char() of that became '12\t345\t6' and then regexp split would make it {'12' '345' '6'}
Related Question