Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Communication between Arduino and Matlab Help

  1. Jun 19, 2015 #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 (Text):
    #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 (Text):
    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;
     
  2. jcsd
  3. Jun 22, 2015 #2

    jedishrfu

    Staff: Mentor

    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.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Communication between Arduino and Matlab Help
Loading...