MATLAB Datalogger with Arduino

thermal_camera_gif_example_compressed.gif

“As an Amazon Associates Program member, clicking on links may result in Maker Portal receiving a small commission that helps support future projects.”

 

MATLAB is a powerful tool utilized by over 4 million engineers and scientists around the world [MATLAB facts]. It is often the first programming language exposed to students during university and is also a helpful stepping stone for transitioning into data analysis and numerical algorithm development. In this tutorial, I will introduce MATLAB as an interface for data acquisition from an Arduino board. The Arduino, in this particular case, will communicate with a Windows computer via the serial port and send data from an Arduino-compatible sensor, which will subsequently be read by MATLAB through its serial communication library. Serial communication from hardware to MATLAB is very simple and requires only a few lines of code. I will also introduce a real-time analysis and plotting routine to visualize the Arduino data as it arrives in real time. This particular method of data analysis and visualization in real time is incredibly useful for engineers interested in experimentation where microcontrollers and sensors may be used, along with complex data acquisition systems.


Parts List and Wiring

In my particular case, I will be using the AMG8833 infrared thermal camera sensor that is fully compatible with Arduino. I’m using the AMG8833 to test the limits of the serial upload speed and my computer’s ability to update a real-time plot of the 8x8 pixel temperature array data. It is an interesting project that has real-world applications in heat transfer, equipment health monitoring, and even military applications. The parts list used in this experiment is given below:

  1. Arduino Uno Board - $11.00 [Our Shop]

  2. AMG8833 Infrared Thermal Camera Sensor - $60.00 [Our Shop ]

  3. Jumper Wires - $0.15 each [Our Shop]

  4. Mini Breadboard - $3.00 [Our Shop]

Wiring the AMG8833 to an Arduino board is simple - all the AMG8833 needs is power and I2C communication with the following connections:

AMG8833 Pin Arduino Uno Pin
VIN 3.3V
GND GND
SDA A4
SCL A5
amg8833_arduino_wiring.png

In the next section, the basics of printing from Arduino and reading from MATLAB will be introduced.


Basic Serial Read with MATLAB

Here, I’m using randomized integers in Arduino that are printed to the serial port. Then, MATLAB reads the random data and plots it in real time. The code for the Arduino portion is shown first, followed by the MATLAB code.

// Arduino Code printing random integers to the serial port
void setup() {
  Serial.begin(115200);
}

void loop() {
  int ii = random(255);
  Serial.println(String(ii));
  delay(50);
}

The general process for reading data from the serial port involves:

  1. Setting the correct serial port

  2. Setting the baud rate

  3. Opening the serial port

  4. Reading from the serial port

This process is shown below:

% MATLAB data for reading Arduino serial prinout data
instrreset % reset all serial ports
s = serial('COM6'); % change this to desired Arduino board port
set(s,'BaudRate',115200); % baud rate for communication
fopen(s); % open the comm between Arduino and MATLAB
out = fscanf(s); % read data

The resulting output variable named ‘out’ contains the printed data plus a carriage return and newline. We can split the output using the MATLAB ‘split(out,‘,’)’ function, which separates the comma-separated values. We can finally convert the values to doubles using the ‘str2double()’ function. This process of reading from the serial port and converting to doubles is shown below:

% MATLAB data for reading Arduino serial prinout data
instrreset % reset all serial ports
s = serial('COM6'); % change this to desired Arduino board port
set(s,'BaudRate',115200); % baud rate for communication
fopen(s); % open the comm between Arduino and MATLAB
out = fscanf(s); % read data
data_str = split(out,',');
n_vars = 1; % number of variables printed
data_array = zeros(n_vars,1);
for ii=1:n_vars
    data_array(ii) = str2double(data_str(ii));
end

Next, if we want to create a loop for iterating through data and plotting in real time, we need to setup a more complex system for plotting. The MATLAB code for reading the Arduino serial data in real time is given below:

% MATLAB data for reading Arduino serial prinout data
instrreset % reset all serial ports
clear all
close all
clc

s = serial('COM6'); % change this to desired Arduino board port
set(s,'BaudRate',115200); % baud rate for communication
fopen(s); % open the comm between Arduino and MATLAB
plot_len = 500; % length of plot that updates
x_vals = linspace(0,plot_len,plot_len); % x-values
plot_var = zeros(plot_len,1); % zeros before data comes in

% figure and axes parameters
f1 = figure();
title('MATLAB Serial Readout From Arduino')
xlabel('Sample')
ylabel('Amplitude')
screen = get(0,'screensize');
fig_span = 0.9; % figure size 90% of screen
set(gcf,'Position',[((1.0-fig_span)/2.0)*screen(3),((1.0-fig_span)/2.0)*screen(4),...
    (fig_span*screen(3))-((1.0-fig_span)/2.0)*screen(3),(fig_span*screen(4))-((1.0-fig_span)/2.0)*screen(3)],...
    'color',[252.0,252.0,252.0]/256.0)
f1.Color = [252.0,252.0,252.0]/256.0;
f1.InvertHardcopy = 'off';
set(gca,'FontSize',20,'Color',[205.0,205.0,205.0]/256.0,'GridColor',[252.0,252.0,252.0]/256.0,...
    'LineWidth',1.5,'GridAlpha',0.5)
grid('on')
hold on
loop_break = true; % dummy variable to exit loop when BREAK is pressed
dialogBox = uicontrol('Style', 'PushButton', 'String', 'Break Loop','Callback', 'loop_break = false;');
% plot zeros so we can just update it later
p1 = plot(x_vals,plot_var,'linewidth',2); 

while loop_break 
    out = fscanf(s);
    plot_var(1:end-1) = plot_var(2:end);
    plot_var(end) = str2double(out);
    set(p1,'Ydata',plot_var)
    pause(0.05)
end
fclose(s)
delete(s)
% delete(dialogBox) % delete dialog box that stops serial process
% print('matlab_serial_read_random','-dpng','-r300') % uncomment to save

The resulting output plot created by MATLAB is shown below:

matlab_serial_read_random.png

The following process should be followed when carrying-out this MATLAB serial port read procedure:

  1. Upload sketch to Arduino that prints out to the serial port

  2. Ensure the correct device comm port is inputted. In Windows, my port serial read port is ‘COM6,’ so the serial read is updated to : “serial('COM6')”

  3. Run MATLAB code

  4. When finished or if there is an error, hit the ‘Break Loop’ button in the bottom left corner of the plot (similar to that shown above)

In the next section, I will read AMG8833 thermal camera data from the Arduino serial printout, and use MATLAB to plot the 64 data points to populate a mesh plot that represents the 8x8 thermal temperature array.


AMG8833 MATLAB Thermal Camera in Real Time

In a similar method as above, we can read the AMG8833 Thermal Array sensor over the serial port by printing all 64 pixels onto the serial port from the Arduino side, then parsing the 64 pixels back on the MATLAB side. The Arduino code is shown below, where the 64 pixels are read and printed to the serial port, then at the end of the 64th pixel, we print a carriage return to notify MATLAB that the AMG8833 printout has finished.

// Arduino code for printing AMG8833 Temperature Data to Serial Port
#include <Wire.h>
#include <SparkFun_GridEYE_Arduino_Library.h>

GridEYE amg8833;

void setup() {
  Wire.begin(); // for connecting with AMG8833
  amg8833.begin(); // begin AMG8833 comm
  Serial.begin(115200); // larger baud rate for sending all 64 pixel values
}

void loop() {
  // Print the temperature of each pixel
  for(unsigned char i = 0; i < 64; i++){
    Serial.print(amg8833.getPixelTemperature(i));
    Serial.print(",");
  } 
  // end print with return
  Serial.println();
  // short delay between sends
  delay(50);
}

On the MATLAB side, we have to read the 64 AMG8833 pixels as a string from the serial port, convert each to a double, rearrange them as a 8x8 grid, and plot them onto our figure. This is done in the code given below:

% MATLAB data for reading Arduino serial prinout data
instrreset % reset all serial ports
s = serial('COM6'); % change this to desired Arduino board port
set(s,'BaudRate',115200); % baud rate for communication
fopen(s); % open the comm between Arduino and MATLAB
out = fscanf(s); % read data
data_str = split(out,',');
n_vars = 64; % number of variables printed
data_array = zeros(n_vars,1);
for ii=1:n_vars
    data_array(ii) = str2double(data_str(ii));
end
data_grid = reshape(data_array,8,8);
imagesc(data_grid)

With the subsequent figure plotted out as a result:

matlab_serial_AMG8833_8_by_8.png

If we wanted to create a real-time plot, similar to the single-variable real-time plot above, we can incorporate a more complicated routine to plot the thermal camera in real time. I also included an interpolation scheme to scale up the pixels from 8x8 to 100x100. The code is shown below:

% MATLAB data for reading Arduino serial prinout data
instrreset % reset all serial ports
clear all
close all
clc

s = serial('COM6'); % change this to desired Arduino board port
set(s,'BaudRate',115200); % baud rate for communication
fopen(s); % open the comm between Arduino and MATLAB

% figure and axes parameters
f1 = figure();
screen = get(0,'screensize');
fig_span = 0.75; % figure size 90% of screen
set(gcf,'Position',[((1.0-fig_span)/2.0)*screen(3),((1.0-fig_span)/2.0)*screen(4),...
    (fig_span*screen(3))-((1.0-fig_span)/2.0)*screen(3),(fig_span*screen(4))-((1.0-fig_span)/2.0)*screen(3)],...
    'color',[252.0,252.0,252.0]/256.0)
loop_break = true; % dummy variable to exit loop when BREAK is pressed
dialogBox = uicontrol('Style', 'PushButton', 'String', 'Break Loop','Callback', 'loop_break = false;');
% plot zeros so we can just update it later
[x_locs,y_locs] = meshgrid(1:8);
[x_interp,y_interp] = meshgrid(1:0.07:8-.07); % interpolate 8x8 to 100x100

% Sensor noise measurement
% for this: place a large object with uniform temperature in
% front of sensor (book, wall, table) - this is a psuedo calibration
out = fscanf(s); % read data
data_parse = split(out,','); % split by comma
data_array = zeros(64,1); 
for ii = 1:64
    data_array(ii) = str2double(data_parse(ii)); % convert to double
end
noise = reshape(data_array,[8,8]);
mean_noise = mean(mean(noise)); % calculate mean noise
noise = noise-mean_noise; % subtract mean noise from each pixel's noise
    
plot_bounds = [mean_noise-2 26]; % plot bounds - If colder or hotter are expected  - this may be changed
while loop_break 
    out = fscanf(s);
    data_parse = split(out,',');
    data_array = zeros(64,1);
    for ii = 1:64
        data_array(ii) = str2double(data_parse(ii));
    end
    data_array = reshape(data_array,[8,8])-noise;
    cla()
    % interpolate and plot onto image
    data_interp = interp2(x_locs,y_locs,data_array,x_interp,y_interp,'cubic');
    imagesc(data_interp,plot_bounds)
    c1 = colorbar; % colorbar for temperature reading
    ylabel(c1,'Temperature [C]','FontSize',16)
    pause(0.05) % briefly pause to allow graphics to catch-up
end

The resulting output should produce real-time images that look similar to the one shown below (and also the GIF at the top of this page):

amg8833_matlab_thermal_example.png

Conclusion

MATLAB is a powerful processing tool used by researchers and data analysts because of its vast set of libraries and wide-reaching community of users. In this tutorial, MATLAB’s serial tool was used to read Arduino data from the serial port in real time. This type of procedure could be useful for real-time data acquisition and data visualization. In the particular example given above, the AMG8833 thermal camera was used to create real-time thermal imagery. Thermal imagery can be used to diagnose hotspots in machine health, intruder alert systems, HVAC leakage detection, and much more. This short introduction into data acquisition with MATLAB acts as a starting point for anyone interested in interfacing their computer with Arduino, while also harnessing the powerful computational power of MATLAB.

 

See More in MATLAB and Data Analysis: