Reading too slow from ESP32 and inconsistent data output

6 views (last 30 days)
I have been attempting to read serial data from the ESP32, trying to read from a spectrometer C12880MA. While getting the data, we are getting the buffer overflow, and only getting 1x171 data, expected 288 data points for each line and ending with a '\n', with very inconsistent data that is just NaN at the very end. Attempted to add buffer size but it seems to make it slightly better, a lot closer to the 1x288 data target, and now it doesn't have the buffer overflow warning but the plot dimention for the data dont match.
The attempted "live" plot doesn't work for some reason, it just displays with no line. But the data is being written into the specified document. We have a live plot from processing that works perfectly fine with the serial data, but MATLAB just doesn't work assuming it takes a lot more time to process the data that is being sent in. (processing code posted at the end)
I just simply want the MATLAB to be able to read serial from the ESP32 and get the 288 pixel data that is being sent from the device.
clear all; clc;
% Define serial port
serialPort = 'COM3'; % Change this to the appropriate COM port
baudRate = 115200;
% Open serial port
s = serialport(serialPort, baudRate);
configureTerminator(s, "LF"); % set the terminator to newline character
s.InputBufferSize = 4096; %increase buffer size
% totalBytes = 288 * 1.125; % for 9byte info 9/8=1.125
% setup x-axis values (spectrum distribution)
spec = linspace(340, 850, 288); %linear distribution
% Set up figure for live plotting
figure;
hPlot = plot(spec, zeros(size(spec))); % Initialize plot
xlabel('Data Point');
ylabel('Sensor Value');
title('Live Data from ESP32');
grid on;
% Set up file for data logging
fileName = 'serial_data.txt';
fileID = fopen('Data(3).txt', 'w');
try
% Read and plot data continuously
while ishandle(hPlot)
% Read data from serial port
% dataStr = fread(s, totalBytes);
% dataStr = char(dataStr');
dataStr = read(s, s.InputBufferSize, "char");
%look for terminator
terminatorIndex = find(dataStr == newline, 1);
if ~isempty(terminatorIndex)
%extract the entire line first
dataStr = dataStr(1:terminatorIndex-1);
% Convert the received string to numeric array
data = str2double(strsplit(dataStr, ','));
% Plot live data
set(hPlot, 'YData', (512-data));
% disp(['Received data: ' dataStr]); % for debug use
% Log data to file
fprintf(fileID, '%s\n', dataStr);
end
drawnow; % Update the plot
end
catch
% Close the serial port and file when the figure is closed
fclose(fileID);
disp('Serial port closed.');
delete(s);
end
Here is the Arduino code
#include <SPI.h>
#include <Wire.h>
/*-----------------------------------(Spectrometer setup)--------------------------------------------*/
#define SPEC_TRG 12
#define SPEC_ST 14
#define SPEC_CLK 27
#define SPEC_VIDEO 26
#define SPEC_CHANNELS 288 // New Spec Channels
int data[SPEC_CHANNELS];
/*-----------------------------------(Setup)--------------------------------------------*/
void setup(void) {
Serial.begin(115200);
//Set desired pins to OUTPUT
pinMode(SPEC_CLK, OUTPUT);
pinMode(SPEC_ST, OUTPUT);
digitalWrite(SPEC_CLK, HIGH); // Set SPEC_CLK High
digitalWrite(SPEC_ST, LOW); // Set SPEC_ST Low
while (!Serial);
}
/*-----------------------------------(SPEC_VIDEO interfacing)--------------------------------------------*/
void readSpectrometer(){
int delayTime = 30; // delay time
// Start clock cycle and set start pulse to signal start
digitalWrite(SPEC_CLK, LOW); delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, HIGH); delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW); digitalWrite(SPEC_ST, HIGH);
delayMicroseconds(delayTime);
//Sample for a period of time
for(int i = 0; i < 15; i++){
digitalWrite(SPEC_CLK, HIGH); delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW); delayMicroseconds(delayTime);
}
//Set SPEC_ST to low
digitalWrite(SPEC_ST, LOW);
//Sample for a period of time
for(int i = 0; i < 85; i++){
digitalWrite(SPEC_CLK, HIGH);delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW);delayMicroseconds(delayTime);
}
//One more clock pulse before the actual read
digitalWrite(SPEC_CLK, HIGH);delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW); delayMicroseconds(delayTime);
//Read from SPEC_VIDEO
for(int i = 0; i < SPEC_CHANNELS; i++){
data[i] = analogRead(SPEC_VIDEO)/8;
digitalWrite(SPEC_CLK, HIGH); delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW); delayMicroseconds(delayTime);
}
//Set SPEC_ST to high
digitalWrite(SPEC_ST, HIGH);
//Sample for a small amount of time
for(int i = 0; i < 7; i++){
digitalWrite(SPEC_CLK, HIGH); delayMicroseconds(delayTime);
digitalWrite(SPEC_CLK, LOW); delayMicroseconds(delayTime);
}
digitalWrite(SPEC_CLK, HIGH); delayMicroseconds(delayTime);
}
/*-----------------------------------(data print)--------------------------------------------*/
void printData(){
for (int i = 0; i < SPEC_CHANNELS; i++){Serial.print(data[i]); Serial.print(',');}
}
/*-----------------------------------(Loop)--------------------------------------------*/
void loop(void) {
readSpectrometer();printData();
Serial.print("\n");
}
The serial works in processing code perfectly so I'm not sure what is wrong with MATLAB
import processing.serial.*;
Serial myPort;
String val;
int[] data;
/**************************(Window setup)*****************************************/
int WinWidth = 970; int WinHeight = 570;
void plotdata()
{
background(240); stroke(255,0,0); strokeWeight(2); noFill();
int canvasWidth = 560; // Adjust this value to set the width of the canvas
int xOffset = 40; // Adjust this value to set the horizontal offset of the graph
int yOffset = -40; // Adjust this value to set the vertical offset of the graph
beginShape();
for (int i = 0; i < data.length - 1; i++) {
float x = map(i, 0, data.length - 1, xOffset, xOffset + canvasWidth);
float y = height - (data[i]) - yOffset; // Apply the vertical offset
vertex(x, y);
}
endShape();
}
void settings() {size(WinWidth, WinHeight);}
void setup()
{
println(Serial.list());
String portName = Serial.list()[0]; //This is the index into the serial list, if you only have one serial device the index is 0
myPort = new Serial(this, portName, 115200);
}
void draw(){
if (myPort.available() > 0) {
val = myPort.readStringUntil('\n'); // read it and store it in val
if (val != null){
data = int(split(val, ','));
plotdata();
}
}
}

Answers (0)

Categories

Find more on Analog Input and Output in Help Center and File Exchange

Products


Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!