Communication between Arduino and Matlab Help

Click For Summary
SUMMARY

This discussion focuses on achieving real-time plotting of accelerometer data using an Arduino, XBee, and MATLAB. The user encounters issues with receiving mixed and incomplete data lines, which disrupts the data processing in MATLAB. The Arduino code utilizes the Adafruit_MMA8451 accelerometer library and SoftwareSerial for wireless transmission, while the MATLAB code reads data from a serial port (COM4) at a baud rate of 57600. Recommendations include consolidating print statements in the Arduino code and using a consistent delimiter for data transmission to improve data integrity.

PREREQUISITES
  • Familiarity with Arduino programming and libraries, specifically Adafruit_MMA8451
  • Understanding of serial communication protocols, particularly with XBee modules
  • Basic knowledge of MATLAB for data acquisition and plotting
  • Experience with data parsing techniques in MATLAB, such as using sscanf
NEXT STEPS
  • Optimize Arduino code by consolidating print statements to reduce data transmission errors
  • Implement a consistent delimiter (e.g., commas) in the data output for easier parsing in MATLAB
  • Explore MATLAB's serial communication functions to enhance data handling and error checking
  • Investigate alternative methods for real-time data visualization in MATLAB, such as using timers or callbacks
USEFUL FOR

Electronics enthusiasts, embedded systems developers, and data analysts looking to integrate Arduino with MATLAB for real-time data visualization and analysis.

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   Reactions: 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 4 ·
Replies
4
Views
2K
  • · Replies 9 ·
Replies
9
Views
5K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 2 ·
Replies
2
Views
4K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 2 ·
Replies
2
Views
15K
  • · Replies 7 ·
Replies
7
Views
2K