I have experience working with the Arduino IDE; however, I am now being asked to use MATLAB for real-time acquisition of the 8×8 distance matrix, visualization (heatmaps, 2D/3D plots), and data logging. I do not know how to interface the SparkFun Artemis Thing Plus board with MATLAB. It would be really helpful if someone could guide me through this process
Because Artemis Thing Plus is not directly supported by MATLAB’s Arduino Support Package (which only supports specific boards like Uno, Mega, Due, etc.) you’ll want to pre-program the board to perform serial output
Upload this to the Artemis using the Arduino IDE
/*
Artemis Thing Plus - VL53L5CX 8x8 Distance Matrix to MATLAB
Hardware: SparkFun Artemis Thing Plus + Qwiic VL53L5CX
Communication: Serial USB at 115200 baud
*/
#include <Wire.h>
#include <SparkFun_VL53L5CX_Library.h>
SparkFun_VL53L5CX myImager;
VL53L5CX_ResultsData measurementData;
// Configuration
const uint8_t RESOLUTION = 8; // 8x8 matrix
const uint8_t RANGING_FREQ = 15; // 15Hz for 8x8 mode
const unsigned long SAMPLE_INTERVAL = 67; // ~15Hz in milliseconds
bool imagerReady = false;
unsigned long lastSampleTime = 0;
void setup() {
Serial.begin(115200);
while (!Serial) delay(10); // Wait for serial port to connect
Serial.println("Artemis_Thing_Plus_VL53L5CX_Ready");
Wire.begin();
Wire.setClock(400000); // Fast I2C
// Initialize VL53L5CX
if (myImager.begin() == false) {
Serial.println("ERROR:SensorNotDetected");
while (1) delay(10);
}
// Configure for 8x8 mode at 15Hz
myImager.setResolution(RESOLUTION * RESOLUTION);
myImager.setRangingFrequency(RANGING_FREQ);
if (myImager.startRanging() == false) {
Serial.println("ERROR:RangingStartFailed");
while (1) delay(10);
}
imagerReady = true;
Serial.println("STATUS:Ready");
}
void loop() {
if (!imagerReady) return;
// Check if it's time for next sample
if (millis() - lastSampleTime < SAMPLE_INTERVAL) return;
lastSampleTime = millis();
// Check if data is ready
if (myImager.isDataReady()) {
if (myImager.getRangingData(&measurementData)) {
// Send matrix in compact format for MATLAB
// Format: "MAT,[d00],[d01],...,[d77]\n"
Serial.print("MAT");
for (int y = 0; y < RESOLUTION; y++) {
for (int x = 0; x < RESOLUTION; x++) {
int index = (y * RESOLUTION) + x;
int16_t distance = measurementData.distance_mm[index];
Serial.print(",");
// Handle invalid readings
if (distance < 0 || distance > 4000) {
Serial.print("NaN");
} else {
Serial.print(distance);
}
}
}
Serial.println(); // Newline terminator
}
}
}
Then run back over to MATLAB and try this script:
%% MATLAB Real-Time 8x8 Distance Matrix Acquisition
% Hardware: SparkFun Artemis Thing Plus + VL53L5CX
% Features: Real-time heatmap, 3D surface plot, and data logging
clear; clc; close all;
%% Configuration
PORT = 'COM4'; % Change to your actual COM port
BAUDRATE = 115200;
MATRIX_SIZE = 8;
MAX_RANGE_MM = 4000; % Maximum sensor range
UPDATE_INTERVAL = 0.05; % 50ms display update
% Data logging settings
LOG_FILE = 'distance_matrix_data.mat';
SAVE_INTERVAL = 100; % Save every 100 samples
samplesCollected = 0;
dataLog = [];
%% Initialize Serial Port
% Use modern serialport object (R2019b+)
try
s = serialport(PORT, BAUDRATE);
configureTerminator(s, "LF");
flush(s);
disp('Serial port opened successfully');
catch ME
error('Failed to open serial port. Check COM port and connections.');
end
% Wait for Arduino initialization
disp('Waiting for Artemis Thing Plus to initialize...');
pause(3);
flush(s);
%% Setup Real-Time Visualization
figure('Name', 'VL53L5CX 8x8 Distance Matrix', 'Position', [100 100 1400 500]);
% Subplot 1: Heatmap
subplot(1, 3, 1);
hHeatmap = imagesc(zeros(MATRIX_SIZE, MATRIX_SIZE));
title('Real-Time Distance Heatmap');
xlabel('X Zone');
ylabel('Y Zone');
colorbar;
colormap(jet);
clim([0 MAX_RANGE_MM]);
axis image;
% Subplot 2: 3D Surface
subplot(1, 3, 2);
hSurf = surf(zeros(MATRIX_SIZE, MATRIX_SIZE));
title('3D Distance Surface');
xlabel('X');
ylabel('Y');
zlabel('Distance (mm)');
zlim([0 MAX_RANGE_MM]);
colorbar;
shading interp;
% Subplot 3: Time series of center pixel
subplot(1, 3, 3);
centerData = [];
hPlot = plot(NaN, NaN, 'b-', 'LineWidth', 1.5);
title('Center Pixel (4,4) Distance Over Time');
xlabel('Sample');
ylabel('Distance (mm)');
ylim([0 MAX_RANGE_MM]);
grid on;
hold on;
%% Main Acquisition Loop
disp('Starting data acquisition... Press Ctrl+C to stop');
tic;
try
while true
% Check for available data
if s.NumBytesAvailable > 0
line = readline(s);
line = strtrim(line);
% Parse data if it starts with "MAT"
if startsWith(line, "MAT")
% Parse comma-separated values
dataStr = split(line, ',');
if length(dataStr) >= (MATRIX_SIZE^2 + 1)
% Extract distance values
matrixData = zeros(MATRIX_SIZE, MATRIX_SIZE);
idx = 1;
for y = 1:MATRIX_SIZE
for x = 1:MATRIX_SIZE
valStr = dataStr{idx + 1}; % Skip "MAT" prefix
% Handle NaN values
if strcmp(valStr, "NaN")
matrixData(y, x) = NaN;
else
matrixData(y, x) = str2double(valStr);
end
idx = idx + 1;
end
end
% Update visualizations
updateVisualizations(matrixData, hHeatmap, hSurf, hPlot, centerData);
% Log data
samplesCollected = samplesCollected + 1;
timestamp = toc;
dataLog(samplesCollected).time = timestamp;
dataLog(samplesCollected).matrix = matrixData;
% Periodic save
if mod(samplesCollected, SAVE_INTERVAL) == 0
save(LOG_FILE, 'dataLog', 'samplesCollected');
fprintf('Saved %d samples to %s\n', samplesCollected, LOG_FILE);
end
% Update center pixel history for time plot
centerData(end+1) = matrixData(4, 4);
if length(centerData) > 200 % Keep last 200 points
centerData = centerData(end-199:end);
end
end
end
end
pause(UPDATE_INTERVAL);
end
catch ME
disp(['Error: ' ME.message]);
end
%% Cleanup
disp('Closing connection...');
save(LOG_FILE, 'dataLog', 'samplesCollected');
clear s;
disp(['Data saved to ' LOG_FILE]);
%% Helper Function
function updateVisualizations(matrixData, hHeatmap, hSurf, hPlot, centerData)
% Update heatmap
hHeatmap.CData = matrixData;
% Update 3D surface
hSurf.ZData = matrixData;
% Update time series plot
if ~isempty(centerData)
hPlot.XData = 1:length(centerData);
hPlot.YData = centerData;
xlim([max(1, length(centerData)-200) length(centerData)+10]);
end
drawnow limitrate;
end
That should get ya most of the way there
Thank you so much. It worked.
1 Like