MATLAB Communication between Arduino and Matlab Help

Click For Summary
The discussion centers on the challenge of achieving real-time plotting of accelerometer data using an Arduino, XBee, and MATLAB. The user encounters issues with receiving mixed or incomplete data lines, which disrupts the data processing in MATLAB. The Arduino code is designed to read accelerometer data and transmit it via XBee, while the MATLAB code is set up to read this data and plot it. Suggestions for improvement include simplifying the data format by removing unnecessary characters and combining multiple print statements into a single line to ensure cleaner data transmission. Additionally, using spaces or commas instead of tab characters for data separation is recommended to enhance compatibility with MATLAB's data parsing. The overall goal is to ensure consistent and complete data transmission for accurate real-time plotting.
Jonathan_36
Messages
1
Reaction score
1
I am trying to achieve real time plotting of accelerometer data using an arduino, an Xbee, and Matlab. Usually when the Matlab program gets data, it gets something like this:

~ #� ' X: -2 Y: 20 Z: 4080 t: 33232

~ !� ' X: 4 Y: 2 Z: 4066 t: 33255

b~ &� ' X: 1090 Y: 218 Z: 4086 t: 33277

]~ %� ' X: -204 Y: 48 Z: 4084 t: 33300

¢~ $� ' X: 86 Y: 104 Z: 4060 t: 33323

which is fine, and is what I want but there are also times in which I will get data like this:Ï~ %� $ X: 210 Y: 116 Z: 4074 t~ #� $ X: -2 Y: -2 Z: 4074 t: 33684

~ #� $ X: 16 Y: -4 Z: 4084 t: 33707

~ "� $ X: -2 Y: 4 Z: 4064 t: 33729

where I will get an incomplete line of code mashed together with a complete line of code and I am stuck on how to fix this. Is there anything in my code I overlooked or is there something else I should try?

On the arduino side, the code is below:

Code:
#include <Wire.h>
#include "RTClib.h"
#include <Adafruit_MMA8451.h>  //accelerometer
#include <Adafruit_Sensor.h>
#include <SoftwareSerial.h> //for wireless transmission with the xbee

Adafruit_MMA8451 mma = Adafruit_MMA8451();
SoftwareSerial XBee(2, 3);

void setup(void) {
  Serial.begin(57600);
  XBee.begin(57600);
  Serial.println("Here we go!");
 
  #ifdef AVR
    Wire.begin();
  #else
    Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino Due
  #endif

  if (! mma.begin()) {
    Serial.println("Couldnt start");
    while (1);
  }
  Serial.println("MMA8451 found!");
 
  mma.setRange(MMA8451_RANGE_2_G);
  Serial.print("Range = "); Serial.print(2 << mma.getRange()); 
  Serial.println("G");
 
}

void loop() {

  XBee.write(Serial.read());
  // Read the 'raw' data in 14-bit counts
  mma.read();
 
  Serial.print("X:\t"); Serial.print(mma.x);
  Serial.print("\tY:\t"); Serial.print(mma.y);
  Serial.print("\tZ:\t"); Serial.print(mma.z);
  Serial.print("\t");
  Serial.print("t:\t"); Serial.print(millis());
  Serial.println();
 
delay(20);
}

On the Matlab side, I simplified my code down to this:

Code:
close all
clear all
clc

%% Setup

% Clears open COM ports that are already in use by MATLAB
instrreset

% Sets communication channel with the sensor to COM4
s = serial('COM4');

% Sets the baud rate for the connection
% This must be the same baud rate of the XBee transmission
set(s, 'BaudRate', 57600);

% Opens the communication channel with the sensor
fopen(s);

%% Initializing Variables and setting up data matrix

% Initializing variables
Number_of_Samples = 500;
i = 1;
j = 1;
k = 1;
l = 1;
x = [];
y = [];
z = [];
time = [];
t_arduino = [];
t_difference = [];

data = [];

%%

% Startup messages
fprintf('Setup complete. \nStarting data collection.\n');

figure();
hold on
grid on
axis auto
xlabel('Time (seconds)');
ylabel('x, y, and z 4096/g');
title('Real Time Accelerometer Data');

t1 = clock;
%%

while i <= Number_of_Samples
   
    Line = fgets(s)
    
    Raw_Data = sscanf(Line, '%*s%f');
   
    Size = size(Raw_Data);
   
    for j = 1:Size(1)
       
        %Gets placed in the x-data column
        if mod(j, 4) == 1
            data(l,k) = Raw_Data(j);
            x_temp = Raw_Data(j);
            x = [x x_temp];
            k = k + 1;
        end
       
        %Gets placed in the y-data column
        if mod(j, 4) == 2
            data(l,k) = Raw_Data(j);
            y_temp = Raw_Data(j);
            y = [y y_temp];
            k = k + 1;
        end
       
        %Gets placed in the z-data column
        if mod(j, 4) == 3
            data(l,k) = Raw_Data(j);
            z_temp = Raw_Data(j);
            z = [z z_temp];
            k = k + 1;
        end
       
        %Gets placed in the time column
        if mod(j, 4) == 0
            data(l,k) = Raw_Data(j);
            t_arduino_temp = Raw_Data(j);
            t_arduino = [t_arduino t_arduino_temp];
            t2 = clock;
            t_temp = etime(t2,t1);
            time = [time t_temp];
            l = l + 1;
            k = 1;
        end
   
    end
   
     plot(time, x, 'r', time, y, 'k', time, z, 'b')
     legend('x', 'y', 'z')
   
    if mod(i, 50) == 0
        drawnow
        %fprintf('Collected %d samples. \n', i)
    end
   
    i = i + 1;
   
end

%% Finishing up

% Housekeeping - close and clean up all data streams
fclose(s);
fclose(dat);
delete(s);
clear s;
 
  • Like
Likes berkeman
Physics news on Phys.org
I'd get rid of the X,Y,Z,T stuff. Its unneeded as you know the order of your data.

And I'd get rid of the \t characters as also unneeded and use spaces or if its better in your MATLAB code use commas as in comma separated values (CSV) file format.

Also I'd combine the four prints into one print line call.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
3K
  • · Replies 9 ·
Replies
9
Views
5K
  • · Replies 4 ·
Replies
4
Views
1K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 2 ·
Replies
2
Views
15K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 7 ·
Replies
7
Views
2K