Compare commits

..

13 Commits

20 changed files with 12514 additions and 84 deletions

3037
001rec_ADC_data.csv Normal file

File diff suppressed because it is too large Load Diff

23
001rec_SI.csv Normal file
View File

@@ -0,0 +1,23 @@
3601,PING
314696,PING
397567,SET_ST_SPEED
428427,PING
509624,START_STREAM
878205,ARM
878207,ENTER_ARM
895800,STATIC_FIRE3
895800,EXIT_ARM
895803,ENTER_STATIC_FIRE
900817,NITROGEN_OPEN_FULL
905320,ETHANOL_OPEN
905627,LOX_OPEN
907331,ETHANOL_OPEN_FULL
907337,LOX_OPEN_FULL
911840,ETHANOL_FULL_CLOSED
911840,LOX_FULL_CLOSED
917347,ETHANOL_DRAIN_OPEN
917349,LOX_DRAIN_OPEN
919351,NITROGEN_FULL_CLOSED
920111,EXIT_STATIC_FIRE
949806,STOP_STREAM
1553500,START_USB
1 3601 PING
2 314696 PING
3 397567 SET_ST_SPEED
4 428427 PING
5 509624 START_STREAM
6 878205 ARM
7 878207 ENTER_ARM
8 895800 STATIC_FIRE3
9 895800 EXIT_ARM
10 895803 ENTER_STATIC_FIRE
11 900817 NITROGEN_OPEN_FULL
12 905320 ETHANOL_OPEN
13 905627 LOX_OPEN
14 907331 ETHANOL_OPEN_FULL
15 907337 LOX_OPEN_FULL
16 911840 ETHANOL_FULL_CLOSED
17 911840 LOX_FULL_CLOSED
18 917347 ETHANOL_DRAIN_OPEN
19 917349 LOX_DRAIN_OPEN
20 919351 NITROGEN_FULL_CLOSED
21 920111 EXIT_STATIC_FIRE
22 949806 STOP_STREAM
23 1553500 START_USB

View File

@@ -0,0 +1,20 @@
START_STREAM
STOP_STREAM
ARM
DISARM
STATIC_FIRE3
STATIC_FIRE5
STATIC_FIRE7
STATIC_FIRE9
ABORT
SERVO_SWEEP
START_FLASH
START_USB
RESET
WIPE_STM
UPTIME
PING
GET_STATE
VERSION
START_OXYVENT
STOP_OXYVENT

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
Time,EVENT
3601,PING
314696,PING
397567,SET_ST_SPEED
428427,PING
509624,START_STREAM
878205,ARM
878207,ENTER_ARM
895800,STATIC_FIRE3
895800,EXIT_ARM
895803,ENTER_STATIC_FIRE
900817,NITROGEN_OPEN_FULL
905320,ETHANOL_OPEN
905627,LOX_OPEN
907331,ETHANOL_OPEN_FULL
907337,LOX_OPEN_FULL
911840,ETHANOL_FULL_CLOSED
911840,LOX_FULL_CLOSED
917347,ETHANOL_DRAIN_OPEN
917349,LOX_DRAIN_OPEN
919351,NITROGEN_FULL_CLOSED
920111,EXIT_STATIC_FIRE
949806,STOP_STREAM
1553500,START_USB
1 Time EVENT
2 3601 PING
3 314696 PING
4 397567 SET_ST_SPEED
5 428427 PING
6 509624 START_STREAM
7 878205 ARM
8 878207 ENTER_ARM
9 895800 STATIC_FIRE3
10 895800 EXIT_ARM
11 895803 ENTER_STATIC_FIRE
12 900817 NITROGEN_OPEN_FULL
13 905320 ETHANOL_OPEN
14 905627 LOX_OPEN
15 907331 ETHANOL_OPEN_FULL
16 907337 LOX_OPEN_FULL
17 911840 ETHANOL_FULL_CLOSED
18 911840 LOX_FULL_CLOSED
19 917347 ETHANOL_DRAIN_OPEN
20 917349 LOX_DRAIN_OPEN
21 919351 NITROGEN_FULL_CLOSED
22 920111 EXIT_STATIC_FIRE
23 949806 STOP_STREAM
24 1553500 START_USB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
close all; clear all;
%% Final Static Fire Sequence
% Time vector
dt = 0.0001; % or 0.01, etc.
t = -8:dt:14; % colon, not linspace
%% Define sequence for each valve
% [ start_time, target_value, ramp_duration ]
N2_events = [
-3 100 0
];
Fuel_events = [
1.5 25 0.5
3.5 100 1.5
8 0 0.5
];
LOX_events = [
1.8 25 0.2
3.5 100 1.5
8 0 0.3
];
Pyro_events = [
0 100 0.01
1.8 0 0.01
];
%% Generate profiles (initial value = 0)
N2 = valve_profile(t, N2_events, 0);
Fuel = valve_profile(t, Fuel_events, 0);
LOX = valve_profile(t, LOX_events, 0);
Pyro = valve_profile(t, Pyro_events, 0);
%% Plot
% Existing
figure; hold on; grid on; box on;
plot(t, N2, '--', 'LineWidth', 1, 'Color', [0 0 1 0.5]);
plot(t, Fuel, '-', 'LineWidth', 1.5);
plot(t, LOX, '-', 'LineWidth', 1.5);
%plot(t, Pyro, '--', 'LineWidth', 1);
plot([0,0],[0,100],'-', 'LineWidth', 2,'Color', [1 0 0 0.5]); %Ignition
ax = gca;
ax.XTick = -4:1:10;
ax.XMinorTick = 'on';
ax.XAxis.MinorTickValues = -4:0.1:10;
ax.XMinorGrid = 'on';
ax.MinorGridAlpha = 0.15; % transparency
ax.MinorGridLineStyle = '-'; % solid but faint
ax.MinorGridColor = [0.8 0.8 0.8];
xlabel('Time [s]');
ylabel('Opening[%]');
legend('Nitrogen','Ethanol','LOX','Ignition','Location','best');
ylim([-5 105]);
xlim([-4 10]);
title('Final Ignition Sequence');
%% Helper function
function u = valve_profile(t, events, initial_value)
% events: [t_start, target_value, ramp_duration]
% assumes events are sorted by t_start
u = initial_value * ones(size(t));
prev_value = initial_value;
for k = 1:size(events,1)
t0 = events(k,1);
target = events(k,2);
dur = events(k,3);
if dur <= 0
% Instant step
u(t >= t0) = target;
else
% Linear ramp from prev_value to target
t1 = t0 + dur;
idx_ramp = (t >= t0) & (t <= t1);
u(idx_ramp) = prev_value + ...
(target - prev_value) .* (t(idx_ramp) - t0) / dur;
% Hold new value after ramp
u(t > t1) = target;
end
prev_value = target;
end
end

View File

@@ -0,0 +1,99 @@
close all; clear all;
%% Final Static Fire Sequence
% Time vector
dt = 0.0001; % or 0.01, etc.
t = -8:dt:14; % colon, not linspace
%% Define sequence for each valve
% [ start_time, target_value, ramp_duration ]
N2_events = [
-3 100 0
];
Fuel_events = [
1 33.33 0.5
2 100 0.5
3.5 0 0.5
];
LOX_events = [
1.3 33.33 0.2
2 100 0.5
3.5 0 0.3
];
Pyro_events = [
0 100 0.01
1.8 0 0.01
];
%% Generate profiles (initial value = 0)
N2 = valve_profile(t, N2_events, 0);
Fuel = valve_profile(t, Fuel_events, 0);
LOX = valve_profile(t, LOX_events, 0);
Pyro = valve_profile(t, Pyro_events, 0);
%% Plot
% Existing
figure; hold on; grid on; box on;
plot(t, N2, '--', 'LineWidth', 1, 'Color', [0 0 1 0.5]);
plot(t, Fuel, '-', 'LineWidth', 1.5);
plot(t, LOX, '-', 'LineWidth', 1.5);
%plot(t, Pyro, '--', 'LineWidth', 1);
plot([0,0],[0,100],'-', 'LineWidth', 2,'Color', [1 0 0 0.5]); %Ignition
ax = gca;
ax.XTick = -4:1:10;
ax.XMinorTick = 'on';
ax.XAxis.MinorTickValues = -4:0.1:10;
ax.XMinorGrid = 'on';
ax.MinorGridAlpha = 0.15; % transparency
ax.MinorGridLineStyle = '-'; % solid but faint
ax.MinorGridColor = [0.8 0.8 0.8];
xlabel('Time [s]');
ylabel('Opening[%]');
legend('Nitrogen','Ethanol','LOX','Ignition','Location','best');
ylim([-5 105]);
xlim([-4 10]);
title('First Ignition Sequence (1 second)');
%% Helper function
function u = valve_profile(t, events, initial_value)
% events: [t_start, target_value, ramp_duration]
% assumes events are sorted by t_start
u = initial_value * ones(size(t));
prev_value = initial_value;
for k = 1:size(events,1)
t0 = events(k,1);
target = events(k,2);
dur = events(k,3);
if dur <= 0
% Instant step
u(t >= t0) = target;
else
% Linear ramp from prev_value to target
t1 = t0 + dur;
idx_ramp = (t >= t0) & (t <= t1);
u(idx_ramp) = prev_value + ...
(target - prev_value) .* (t(idx_ramp) - t0) / dur;
% Hold new value after ramp
u(t > t1) = target;
end
prev_value = target;
end
end

View File

@@ -0,0 +1,425 @@
close all; clear; clc;
%% ================= CONFIG =================
eventsFile = "001rec_SI.csv"; % Events: time (ms), event name
dataFile = "001rec_ADC_data.csv"; % ADC data: time (ms), channels...
PARTIAL_OPEN_FRACTION = 0.25; % Valve position for *_OPEN (between 0 and 1)
IGNITION_DELAY = 3.0; % [s] after nitrogen open to assume ignition
% Valve ramp times [s] for each valve (you can tweak these)
rampConfig.LOX.open = 0.2; % CLOSED -> PARTIAL on LOX_OPEN
rampConfig.LOX.openFull = 1.5; % -> FULL on LOX_OPEN_FULL
rampConfig.LOX.close = 0.3; % -> CLOSED on LOX_FULL_CLOSED
rampConfig.ETHANOL.open = 0.5;
rampConfig.ETHANOL.openFull = 1.5;
rampConfig.ETHANOL.close = 0.5;
rampConfig.NITROGEN.open = 0.0;
rampConfig.NITROGEN.openFull = 0.0;
rampConfig.NITROGEN.close = 0.5;
%% ================= LOAD DATA =================
events = readtable(eventsFile);
eventTime_ms = events{:,1}; % first column: time in ms
eventLabel = string(events{:,2}); % second column: event name as string array
result = readmatrix(dataFile); % ADC data
% result(:,1) assumed to be time in ms
%% ================= TIME ALIGNMENT =================
% Reference = NITROGEN_OPEN_FULL if available, else NITROGEN_OPEN, else first event.
% We set that reference event to t = -3 s.
idxN2full = find(eventLabel == "NITROGEN_OPEN_FULL", 1, 'first');
idxN2open = find(eventLabel == "NITROGEN_OPEN", 1, 'first');
if ~isempty(idxN2full)
idxRef = idxN2full;
elseif ~isempty(idxN2open)
idxRef = idxN2open;
else
warning("No NITROGEN_OPEN[_FULL] event found. Using first event as reference.");
idxRef = 1;
end
tRef_ms = eventTime_ms(idxRef);
% ADC time in seconds, such that nitrogen-open is at t = -3 s:
% t = (t_ms - tRef_ms)/1000 - 3 -> at t_ms = tRef_ms => t = -3
time = (result(:,1) - tRef_ms) ./ 1000 - 3; % [s]
% Event times in the same reference
eventTime_s = (eventTime_ms - tRef_ms) ./ 1000 - 3;
%% ================= SYNTHETIC IGNITION EVENT =================
% Assume ignition occurs IGNITION_DELAY seconds after nitrogen open.
tN2open_s = eventTime_s(idxRef); % should be -3
tIgn_s = tN2open_s + IGNITION_DELAY; % typically 0 s
eventTime_s(end+1) = tIgn_s;
eventLabel(end+1) = "IGNITION";
% Sort events in time again
[eventTime_s, sortIdx] = sort(eventTime_s);
eventLabel = eventLabel(sortIdx);
%% ================= CALIBRATIONS =================
% Your original scaling on column 14
result(:,14) = result(:,14) ./ 2;
% Temperature calibration (columns 49)
temp = 0.000111 .* result(:,4:9) + 2.31991;
% Pressure calibration (columns 1017)
pressure = result(:,10:17) .* 0.000015 - 6.565;
% Load cell channels
load_cell = result(:,2:3);
% Thrust / weight calibration (in kg)
weight = -1.166759307845543e-04 .* 0.5 .* (load_cell(:,1) + load_cell(:,2)) ...
+ 4.971416323340051e+02;
%% ================= IMPORTANT EVENTS FILTER =================
% Only show these in the event markers (others are hidden)
importantEvents = [ ... % "ENTER_STATIC_FIRE", ..."EXIT_STATIC_FIRE", ... %"ENTER_ARM", ...
"UPDATE_ARM", ... "EXIT_ARM", ...
"LOX_OPEN", ...
"LOX_OPEN_FULL", ...
"ETHANOL_OPEN", ...
"ETHANOL_OPEN_FULL", ...
"NITROGEN_OPEN", ...
"NITROGEN_OPEN_FULL", ...
"LOX_FULL_CLOSED", ...
"ETHANOL_FULL_CLOSED", ..."NITROGEN_FULL_CLOSED", ...
"ENTER_ABORT", ...
"EXIT_ABORT", ...
"IGNITION" ...
];
maskImportant = ismember(eventLabel, importantEvents);
%% ================= RECONSTRUCT VALVE SEQUENCES =================
loxCmd = buildValveCmd(time, eventTime_s, eventLabel, "LOX", PARTIAL_OPEN_FRACTION, rampConfig.LOX);
ethCmd = buildValveCmd(time, eventTime_s, eventLabel, "ETHANOL", PARTIAL_OPEN_FRACTION, rampConfig.ETHANOL);
n2Cmd = buildValveCmd(time, eventTime_s, eventLabel, "NITROGEN", PARTIAL_OPEN_FRACTION, rampConfig.NITROGEN);
%% ================= PLOTTING: 3 STACKED SUBPLOTS =================
pressureNames = { ...
'LOX tank pressure', ...
'Ethanol tank pressure', ...
'Ethanol pressure in injection plate', ...
'Chamber pressure', ...
'Ethanol pressure at inlet', ...
'Pressure channel 6', ...
'Pressure channel 7'};
figure;
tiledlayout(3,1,'TileSpacing','compact');
% ----- Top: reconstructed valve sequence -----
ax1 = nexttile; hold on;
plot(time, loxCmd, 'LineWidth', 1.2, 'DisplayName', 'LOX');
plot(time, ethCmd, 'LineWidth', 1.2, 'DisplayName', 'ETHANOL');
plot(time, n2Cmd, 'LineWidth', 1.2, 'DisplayName', 'NITROGEN');
ylabel('Valve Opening');
ylim([-0.1 1.1]);
yticks([0 PARTIAL_OPEN_FRACTION 1]);
yticklabels({'0', sprintf(' %.2g',PARTIAL_OPEN_FRACTION*100), '100%'});
title('Final Hot Fire');
legend('Location','eastoutside');
grid on;
addEventLines(eventTime_s, eventLabel, maskImportant);
% ----- Middle: thrust -----
ax2 = nexttile; hold on;
plot(time, weight);
ylabel('Thrust [kg]');
grid on;
addEventLines(eventTime_s, eventLabel, maskImportant);
% ----- Bottom: all pressures overlayed -----
ax3 = nexttile; hold on;
for i = 1:5
plot(time, pressure(:,i), 'DisplayName', pressureNames{i});
end
ylabel('Pressure [bar]');
xlabel('Time [s]');
legend('Location','eastoutside');
grid on;
addEventLines(eventTime_s, eventLabel, maskImportant);
% Link x-axes for all subplots
linkaxes([ax1 ax2 ax3], 'x');
xlim([-4 10]);
%% ====== Make animation video (time-cursor moving in real time) ======
%{
videoName = 'nova2_run_animation.mp4';
v = VideoWriter(videoName, 'MPEG-4'); % use 'MPEG-4' for .mp4
v.FrameRate = 30; % frames per second
open(v);
% Time range of your data (already in seconds)
tMin = min(time);
tMax = max(time);
fps = v.FrameRate;
duration = tMax - tMin; % [s] actual test duration
nFrames = ceil(duration * fps); % so video length duration
tFrame = linspace(tMin, tMax, nFrames);
% Create a vertical cursor line on each subplot
axAll = [ax1 ax2 ax3];
hCursor = gobjects(numel(axAll), 1);
for i = 1:numel(axAll)
axes(axAll(i)); %#ok<LAXES> to make it current
hold(axAll(i), 'on');
hCursor(i) = xline(axAll(i), tMin, 'k-', 'LineWidth', 1.5);
end
% Sweep cursor across time and record each frame
for k = 1:nFrames
tCurr = tFrame(k);
% Move cursor to current time on all axes
for i = 1:numel(axAll)
hCursor(i).Value = tCurr;
end
drawnow limitrate; % update figure
frame = getframe(gcf); % capture current figure
writeVideo(v, frame); % write to video
end
close(v);
disp("Saved video to: " + videoName);
%}
%% ============= LOCAL FUNCTIONS (same file) =================
function addEventLines(eventTime_s, eventLabel, mask)
% addEventLines Draw vertical event markers (lines + rotated text) on current axes.
% addEventLines(eventTime_s, eventLabel)
% addEventLines(eventTime_s, eventLabel, mask)
%
% eventTime_s : vector of event times in seconds
% eventLabel : string/cellstr array of labels, same size as eventTime_s
% mask : optional logical mask to select which events to draw
if nargin < 3 || isempty(mask)
mask = true(size(eventTime_s));
end
ax = gca;
ylims = ylim(ax);
yrange = diff(ylims);
% Put label a bit inside the top of the axis
yLabel = ylims(2) - 0.02 * yrange;
% Keep only selected events
tAll = eventTime_s(mask);
labelsAll = eventLabel(mask);
if isempty(tAll)
return;
end
% Group by unique time
[tUnique, ~, groupIdx] = unique(tAll);
for g = 1:numel(tUnique)
t = tUnique(g);
% All events at this time
inds = find(groupIdx == g);
groupLabels = labelsAll(inds);
n = numel(inds);
% ---- Decide label text ----
if n == 1
% Single event show its actual name
lbl = char(groupLabels);
else
% Multiple events at same timestamp
if any(endsWith(groupLabels, "FULL_CLOSED"))
lbl = 'VALVES CLOSING ';
elseif any(endsWith(groupLabels, "OPEN_FULL"))
lbl = 'VALVES OPEN FULL';
else
lbl = 'MULTIPLE EVENTS';
end
end
% ---- Draw one vertical line ----
xline(ax, t, 'r--', 'HandleVisibility', 'off');
% ---- Draw one label on that line, inside the axis ----
text(ax, t, yLabel, lbl, ...
'Rotation', 90, ...
'Interpreter', 'none', ... % so "_" isn't treated as subscript
'VerticalAlignment', 'top', ...
'HorizontalAlignment', 'right', ...
'FontSize', 8, ...
'Clipping', 'on'); % keep it inside the axes
end
end
function cmd = buildValveCmd(time, eventTime_s, eventLabel, prefix, partialFrac, rampCfg)
% buildValveCmd Reconstruct valve command (0..1) for a given valve.
%
% cmd = buildValveCmd(time, eventTime_s, eventLabel, "LOX", partialFrac, rampCfg)
%
% prefix : "LOX", "ETHANOL", or "NITROGEN"
% partialFrac : value used for *_OPEN (e.g. 0.4)
% rampCfg : struct with fields .open, .openFull, .close (in seconds)
% Masks for events relevant to this valve
maskOpen = eventLabel == prefix + "_OPEN";
maskOpenFull = eventLabel == prefix + "_OPEN_FULL";
maskClosed = eventLabel == prefix + "_FULL_CLOSED";
timesAll = [ eventTime_s(maskOpen); ...
eventTime_s(maskOpenFull); ...
eventTime_s(maskClosed) ];
labelsAll = [ eventLabel(maskOpen); ...
eventLabel(maskOpenFull); ...
eventLabel(maskClosed) ];
if isempty(timesAll)
% No events for this valve: always closed
cmd = zeros(size(time));
return;
end
% Sort valve events by time
[timesAll, idxSort] = sort(timesAll);
labelsAll = labelsAll(idxSort);
% Determine state right before the first time sample
currentState = 0.0; % start closed
for k = 1:numel(timesAll)
if timesAll(k) <= time(1)
lbl = labelsAll(k);
if lbl == prefix + "_OPEN"
currentState = partialFrac;
elseif lbl == prefix + "_OPEN_FULL"
currentState = 1.0;
elseif lbl == prefix + "_FULL_CLOSED"
currentState = 0.0;
end
end
end
% Build event list (for this valve) starting at time(1)
eTimes = time(1);
eTargets = currentState;
eRampDur = 0;
for k = 1:numel(timesAll)
t = timesAll(k);
if t <= time(1)
continue; % already accounted in initial state
end
lbl = labelsAll(k);
if lbl == prefix + "_OPEN"
target = partialFrac;
ramp = rampCfg.open;
elseif lbl == prefix + "_OPEN_FULL"
target = 1.0;
ramp = rampCfg.openFull;
elseif lbl == prefix + "_FULL_CLOSED"
target = 0.0;
ramp = rampCfg.close;
else
continue;
end
eTimes(end+1) = t;
eTargets(end+1) = target;
eRampDur(end+1) = ramp;
end
% Convert these event + ramp definitions into a continuous command
cmd = applyValveRamps(time, eTimes, eTargets, eRampDur);
end
function cmd = applyValveRamps(time, eTimes, eTargets, eRampDur)
% applyValveRamps Build valve command with linear ramps between states.
%
% time : time vector
% eTimes : times of state changes
% eTargets : target state at each eTimes entry
% eRampDur : ramp duration after each event
cmd = zeros(size(time));
nEvents = numel(eTimes);
currentState = eTargets(1);
lastEndTime = time(1);
% Ensure row vectors
time = time(:).';
cmd = cmd(:).';
for i = 2:nEvents
tEvent = eTimes(i);
target = eTargets(i);
ramp = eRampDur(i);
% Constant segment from lastEndTime up to the event time
idxConst = time >= lastEndTime & time < tEvent;
cmd(idxConst) = currentState;
% Ramp segment from event time to event time + ramp
rampStart = tEvent;
rampEnd = tEvent + ramp;
if ramp > 0
idxRamp = time >= rampStart & time < rampEnd;
cmd(idxRamp) = currentState + (target - currentState) .* ...
(time(idxRamp) - rampStart) / ramp;
currentState = target;
lastEndTime = rampEnd;
else
% Instantaneous change
currentState = target;
lastEndTime = tEvent;
end
end
% Final constant segment after the last ramp
idxTail = time >= lastEndTime;
cmd(idxTail) = currentState;
% Return as column vector to match input style
cmd = cmd(:);
end

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -0,0 +1,66 @@
close all;
events= readtable("001rec_SI.csv");
result = readmatrix("001rec_ADC_data.csv");
%result = result(14430:end, : );
result(:,14) = result(:,14)./2;
time = result(:,1)./1000;
temp = 0.000111 .* result(:,4:9) + 2.31991;
pressure = result(:,10:17).*(0.000015)-6.565;
load_cell = result(:,2:3);
weight = -1.166759307845543e-04 .* 0.5.*(load_cell(:,1) + load_cell(:,2)) + 4.971416323340051e+02;
figure()
scatter(time,weight,10)
title("load cell in Kg")
xlabel("Time in s")
ylabel("KG")
xlim([878.207 920.111+5.000])
pressureNames = { ...
'LOX tank pressure', ...
'Ethanol tank pressure', ...
'Ethanol pressure in injection plate', ...
'Chamber pressure', ...
'Ethanol pressure at inlet', ...
'Pressure channel 6', ...
'Pressure channel 7'};
for x = 1:7
figure()
hold on;
% Left axis weight/thrust
yyaxis left
scatter(time, weight, 'DisplayName', 'Thrust');
ylabel("Thrust / Weight")
% Right axis pressure
yyaxis right
scatter(time, pressure(:,x), 10, 'DisplayName', 'Pressure');
ylabel("Pressure")
% Title using your descriptive spreadsheet names
title(pressureNames{x})
xlabel("Time in s")
legend()
xlim([878.207 920.111 + 5.000])
end
%{
for x = 1:6
figure()
scatter(time,temp(:,x),10)
title(sprintf("temperature channel %d",x))
xlabel("Time in s")
ylabel("Temprature in C")
xlim([878.207 920.111+5.000])
end
%}

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,28 @@
STOP_STREAM
START_STREAM
RESET
WIPE_STM
UPTIME
PING
GET_STATE
ARM
DISARM
STATIC_FIRE1
STATIC_FIRE2
STATIC_FIRE3
ABORT
SERVO_SWEEP
SERVO_SET
GET_READINGS
SET_ST_SPEED
START_FLASH
START_USB
START_STREAM,
RESET,
WIPE_STM,
UPTIME,
PING,
GET_STATE,
ARM,
DISARM,
STATIC_FIRE,
STATIC_FIRE3,
STATIC_FIRE5,
STATIC_FIRE7,
STATIC_FIRE9,
ABORT,
SERVO_SWEEP,
SERVO_SET,
SERVO_WIGGLE,
SERVO_STOP,
GET_READINGS,
SET_ST_SPEED,
START_FLASH,
START_USB,
TEST_RECORDER,
START_OXYVENT,
STOP_OXYVENT,
VERSION,
GET_RSSI

View File

@@ -1,27 +1,33 @@
EMPTY_LOG = 0,
LOGGING_DATA,
FLASH_ERROR,
FLASH_START_ERROR,
FLASH_FULL,
FLASH_LOG_FULL,
ENTER_STATIC_FIRE,
EXIT_STATIC_FIRE,
ENTER_ARM,
UPDATE_ARM,
EXIT_ARM,
LOX_OPEN,
LOX_OPEN_FULL,
ETHANOL_OPEN,
ETHANOL_OPEN_FULL,
NITROGEN_OPEN,
NITROGEN_OPEN_FULL,
LOX_CLOSING,
LOX_FULL_CLOSED,
ETHANOL_CLOSING,
ETHANOL_FULL_CLOSED,
NITROGEN_CLOSING,
NITROGEN_FULL_CLOSED,
ETHANOL_DRAIN_OPEN,
LOX_DRAIN_OPEN,
ETHANOL_DRAIN_CLOSED,
LOX_DRAIN_CLOSED
EMPTY_LOG = 0,
LOGGING_DATA,
FLASH_ERROR,
FLASH_START_ERROR,
FLASH_FULL,
FLASH_LOG_FULL,
ENTER_STATIC_FIRE,
EXIT_STATIC_FIRE,
ENTER_ARM,
UPDATE_ARM,
EXIT_ARM,
LOX_OPEN,
LOX_OPEN_FULL,
ETHANOL_OPEN,
ETHANOL_OPEN_FULL,
NITROGEN_OPEN,
NITROGEN_OPEN_FULL,
LOX_CLOSING,
LOX_FULL_CLOSED,
ETHANOL_CLOSING,
ETHANOL_FULL_CLOSED,
NITROGEN_CLOSING,
NITROGEN_FULL_CLOSED,
ETHANOL_DRAIN_OPEN,
LOX_DRAIN_OPEN,
ETHANOL_DRAIN_CLOSED,
LOX_DRAIN_CLOSED,
LOX_VENT_OPEN,
LOX_VENT_CLOSED,
LOX_VENT_ERROR_OPEN,
ENTER_ABORT,
EXIT_ABORT,
ERROR_RESET_IWDG

View File

@@ -1,4 +1,3 @@
import Serial_decoder as SD
import tkinter as tk
from tkinter import ttk
@@ -16,14 +15,38 @@ FILENAME = f"SaveData/{datetime.today().strftime('%Y_%m_%d_%H_%M')}"
# === Plot history ===
MAX_POINTS = 100 # rolling window length
# Derived channels (what we actually plot):
# 0: Thrust (avg of load cells 1 & 2)
# 1-6: Temp 1..6
# 7-14: Pressure 1..8
DERIVED_CHANNEL_LABELS = [
"Thrust", # 0
"Temp 1", # 1
"Temp 2", # 2
"Temp 3", # 3
"Temp 4", # 4
"Temp 5", # 5
"Temp 6", # 6
"Pressure 1", # 7
"Pressure 2", # 8
"Pressure 3", # 9
"Pressure 4", # 10
"Pressure 5", # 11
"Pressure 6", # 12
"Pressure 7", # 13
"Pressure 8", # 14
]
NUM_DERIVED_CHANNELS = len(DERIVED_CHANNEL_LABELS) # 15
history_x = deque(maxlen=MAX_POINTS) # timestamps
history_y = [deque(maxlen=MAX_POINTS) for _ in range(16)] # per-channel values
history_y = [deque(maxlen=MAX_POINTS) for _ in range(NUM_DERIVED_CHANNELS)] # per-channel values
# === GUI setup ===
root = tk.Tk()
root.title("Live 4x4 Grid + Selectable Real-Time Plot")
# Left: 4x4 grid
# Left: 4x4 grid (raw ADC values from 16 channels)
grid_frame = ttk.Frame(root)
grid_frame.grid(row=0, column=0, padx=10, pady=10, sticky="n")
@@ -39,27 +62,29 @@ for row in range(4):
lbl.grid(row=row, column=col, padx=5, pady=5)
labels.append(lbl)
# Last tick label (as you had)
last_tick_lbl = tk.Label(
grid_frame, text="Last Tick: -", width=20, height=3,
borderwidth=2, relief="groove", font=("Arial", 14)
)
# Last / delta tick labels
lbl = tk.Label(root, text="Last Tick:0", width=20, height=3, borderwidth=2, relief="groove", font=("Arial", 14))
lbl.grid(row = 4, column=0, columnspan=2)
labels.append(lbl)
lbl = tk.Label(root, text="Delta Tick:0", width=20, height=3, borderwidth=2, relief="groove", font=("Arial", 14))
lbl.grid(row=4, column=2, columnspan= 2)
labels.append(lbl)
lbl.grid(row=4, column=0, columnspan=2)
labels.append(lbl) # index 16
# Checkboxes to select plotted channels
lbl = tk.Label(root, text="Delta Tick:0", width=20, height=3, borderwidth=2, relief="groove", font=("Arial", 14))
lbl.grid(row=4, column=2, columnspan=2)
labels.append(lbl) # index 17
# Checkboxes to select plotted (derived) channels
check_frame = ttk.LabelFrame(root, text="Plot Selection")
check_frame.grid(row=1, column=0, padx=10, pady=(0, 10), sticky="nw")
check_vars = []
for i in range(16):
for i, ch_label in enumerate(DERIVED_CHANNEL_LABELS):
var = tk.IntVar(value=0)
chk = ttk.Checkbutton(check_frame, text=f"Ch {i+1}", variable=var, command=lambda: update_plot())
chk.grid(row=i//4, column=i%4, sticky="w", padx=4, pady=2)
chk = ttk.Checkbutton(
check_frame,
text=ch_label,
variable=var,
command=update_plot if 'update_plot' in globals() else None # placeholder; will be updated below
)
chk.grid(row=i // 4, column=i % 4, sticky="w", padx=4, pady=2)
check_vars.append(var)
# Right: Matplotlib plot
@@ -68,7 +93,7 @@ plot_frame.grid(row=0, column=1, rowspan=2, padx=10, pady=10, sticky="n")
fig = Figure(figsize=(6, 4), dpi=100)
ax = fig.add_subplot(111)
ax.set_title("Selected Channels (rolling)")
ax.set_title("Selected Channels")
ax.set_xlabel("Timestamp")
ax.set_ylabel("Value")
canvas = FigureCanvasTkAgg(fig, master=plot_frame)
@@ -77,70 +102,123 @@ canvas.get_tk_widget().pack(fill="both", expand=True)
# Optional controls
controls_frame = ttk.Frame(plot_frame)
controls_frame.pack(fill="x", pady=5)
# Clear selection button
def clear_selection():
for v in check_vars:
v.set(0)
update_plot()
def clear_history():
"""Clear stored history for all plotted channels."""
history_x.clear()
for dq in history_y:
dq.clear()
update_plot() # refresh plot so it shows 'No data' message
ttk.Button(controls_frame, text="Clear Selection", command=clear_selection).pack(side="left")
ttk.Button(controls_frame, text="Clear History", command=clear_history).pack(side="left")
# === Update functions ===
Last_tick: int = 0
def update_grid(values: list,tick: int):
def update_grid(values: list, tick: int):
"""Update the 4x4 grid with raw ADC values and write ADC csv."""
global Last_tick
with open(f"{FILENAME}_ADC.csv","+a") as file:
# NOTE: mode should be "a" or "a+", not "+a"
with open(f"{FILENAME}_ADC.csv", "a") as file:
file.write(f"{tick}")
for i in range(16):
for i in range(16): # 16 raw ADC channels
file.write(f",{values[i]}")
labels[i].config(text=f"{values[i]:n}")
labels[16].config(text=f"Last Tick:{tick:n}")
labels[17].config(text=f"Delta Tick:{(tick-Last_tick):n}")
ms_total = tick
hours, rem = divmod(ms_total, 3_600_000) # 1000*60*60
minutes, rem = divmod(rem, 60_000) # 1000*60
seconds, milliseconds = divmod(rem, 1000)
labels[16].config( text=f"UP Time:{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}")
labels[17].config(text=f"Delta Tick:{(tick - Last_tick):n}")
Last_tick = tick
file.write("\n")
def update_SI(value:SD.ReturnDecoder):
with open(f"{FILENAME}_SI.csv","+a") as file:
def update_SI(value: SD.ReturnDecoder):
# NOTE: mode should be "a" or "a+", not "+a"
with open(f"{FILENAME}_SI.csv", "a") as file:
file.write(f"{value.timestamp},{value.log_message}\n")
print(f"\033[F\033[2Ktime:{value.timestamp}, SI:{value.log_message}",end="\n")
print(f"\033[F\033[2Ktime:{value.timestamp}, SI:{value.log_message}", end="\n")
Last_history_call: int = 0
def append_history(adc_values: list, timestamp: int):
"""Store the new sample in the rolling history."""
"""Store the new sample in the rolling history (derived units)."""
global Last_history_call
if len(history_x) > 0 and timestamp < history_x[-1]:
return # discard out-of-order samples
if len(history_x) > 0 and (history_x[-1] + (int(time.time_ns() / 1000000) - Last_history_call)*2) < timestamp:
print(f"Discarding future sample: {timestamp} > {history_x[-1]} + {(int(time.time_ns() / 1000000) - Last_history_call)*2}")
return # discard samples too far in future
history_x.append(timestamp)
for i in range(16):
history_y[i].append(adc_values[i])
Last_history_call = int(time.time_ns() / 1000000) # in ms
# 0: Thrust (average of load cells 0 and 1)
lc_avg = (adc_values[0] + adc_values[1]) / 2
weight = -1.166759308000000e-04 * lc_avg + 4.971416323340051e+02
history_y[0].append(weight)
# 1-6: Temperatures from channels 2..7
for i in range(2, 8): # six thermocouples
temp = 0.000111 * adc_values[i] + 2.31991
history_y[i - 1].append(temp) # 2→1, 7→6
# 7-14: Pressures from channels 8..15
for i in range(8, 16): # eight pressure sensors
pres = 0.0000153522 * adc_values[i] - 6.5652036917
history_y[i - 1].append(pres) # 8→7, 15→14
def update_plot():
"""Redraw plot based on selected channels and available history."""
"""Redraw plot based on selected derived channels and available history."""
ax.clear()
ax.set_title("Selected Channels (rolling)")
ax.set_title("Selected Channels")
ax.set_xlabel("Timestamp")
ax.set_ylabel("Value")
selected = [i for i, var in enumerate(check_vars) if var.get() == 1]
if len(history_x) == 0 or len(selected) == 0:
ax.text(0.5, 0.5, "No data / No channels selected", ha="center", va="center", transform=ax.transAxes)
ax.text(
0.5, 0.5,
"No data / No channels selected",
ha="center", va="center",
transform=ax.transAxes
)
canvas.draw()
return
x = list(history_x)
for idx in selected:
# safety: guard against any mismatch, just in case
if idx < len(history_y):
y = list(history_y[idx])
ax.plot(x, y, label=f"Ch {idx+1}")
ax.plot(x, y, label=DERIVED_CHANNEL_LABELS[idx])
ax.legend(loc="upper left", fontsize=8)
ax.grid(True, linestyle="--", alpha=0.3)
canvas.draw()
def update_panel():
"""Main polling loop that consumes Serial_decoder outputs (unchanged structure)."""
# Now that update_plot exists, fix the checkbox command to point to it
for chk_var, child in zip(check_vars, check_frame.winfo_children()):
if isinstance(child, ttk.Checkbutton):
child.config(command=update_plot)
def update_panel():
"""Main polling loop that consumes Serial_decoder outputs."""
values: SD.ReturnDecoder = SD.GetReturn(0.1) # non-blocking read with timeout
if values is None:
root.after(10, update_panel)
return
# Stop if input thread died
if tasks[1].is_alive() == False:
if tasks[1].is_alive() is False:
root.quit()
match values.name:

346
mainv2.py Normal file
View File

@@ -0,0 +1,346 @@
import Serial_decoder as SD
import tkinter as tk
from tkinter import ttk
from datetime import datetime
import time
from collections import deque
# Matplotlib embedding in Tkinter
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# === Serial threads (unchanged) ===
tasks = SD.StartInputOutput() # t1: output_loop (daemon), t2: input_loop (daemon)
FILENAME = f"SaveData/{datetime.today().strftime('%Y_%m_%d_%H_%M')}"
# === Commands window config ===
COMMANDS_FILE = "COMMANDS.txt" # one command per line
# === Plot history ===
MAX_POINTS = 100 # rolling window length
# Derived channels (what we actually plot):
# 0: Thrust (avg of load cells 1 & 2)
# 1-6: Temp 1..6
# 7-14: Pressure 1..8
DERIVED_CHANNEL_LABELS = [
"Thrust", # 0
"Temp 1", # 1
"Temp 2", # 2
"Temp 3", # 3
"Temp 4", # 4
"Temp 5", # 5
"Temp 6", # 6
"Pressure 1", # 7
"Pressure 2", # 8
"Pressure 3", # 9
"Pressure 4", # 10
"Pressure 5", # 11
"Pressure 6", # 12
"Pressure 7", # 13
"Pressure 8", # 14
]
NUM_DERIVED_CHANNELS = len(DERIVED_CHANNEL_LABELS) # 15
history_x = deque(maxlen=MAX_POINTS) # timestamps
history_y = [deque(maxlen=MAX_POINTS) for _ in range(NUM_DERIVED_CHANNELS)] # per-channel values
# === GUI setup ===
root = tk.Tk()
root.title("Live 4x4 Grid + Selectable Real-Time Plot")
# Left: 4x4 grid (raw ADC values from 16 channels)
grid_frame = ttk.Frame(root)
grid_frame.grid(row=0, column=0, padx=10, pady=10, sticky="n")
labels = []
for row in range(4):
for col in range(4):
idx = row * 4 + col
lbl = tk.Label(
grid_frame, name=f"channel{idx}",
text="0", width=10, height=3,
borderwidth=2, relief="groove", font=("Arial", 14)
)
lbl.grid(row=row, column=col, padx=5, pady=5)
labels.append(lbl)
# Last / delta tick labels
lbl = tk.Label(root, text="Last Tick:0", width=20, height=3, borderwidth=2, relief="groove", font=("Arial", 14))
lbl.grid(row=4, column=0, columnspan=2)
labels.append(lbl) # index 16
lbl = tk.Label(root, text="Delta Tick:0", width=20, height=3, borderwidth=2, relief="groove", font=("Arial", 14))
lbl.grid(row=4, column=1, columnspan=2)
labels.append(lbl) # index 17
# Checkboxes to select plotted (derived) channels
check_frame = ttk.LabelFrame(root, text="Plot Selection")
check_frame.grid(row=1, column=0, padx=10, pady=(0, 10), sticky="nw")
check_vars = []
for i, ch_label in enumerate(DERIVED_CHANNEL_LABELS):
var = tk.IntVar(value=0)
chk = ttk.Checkbutton(
check_frame,
text=ch_label,
variable=var,
command=None # will assign update_plot after it is defined
)
chk.grid(row=i // 4, column=i % 4, sticky="w", padx=4, pady=2)
check_vars.append(var)
# Right: Matplotlib plot
plot_frame = ttk.Frame(root)
plot_frame.grid(row=0, column=1, rowspan=2, padx=10, pady=10, sticky="n")
fig = Figure(figsize=(6, 4), dpi=100)
ax = fig.add_subplot(111)
ax.set_title("Selected Channels")
ax.set_xlabel("Timestamp")
ax.set_ylabel("Value")
canvas = FigureCanvasTkAgg(fig, master=plot_frame)
canvas.get_tk_widget().pack(fill="both", expand=True)
# Optional controls
controls_frame = ttk.Frame(plot_frame)
controls_frame.pack(fill="x", pady=5)
def clear_selection():
for v in check_vars:
v.set(0)
update_plot()
def clear_history():
"""Clear stored history for all plotted channels."""
history_x.clear()
for dq in history_y:
dq.clear()
update_plot() # refresh plot so it shows 'No data' message
ttk.Button(controls_frame, text="Clear Selection", command=clear_selection).pack(side="left")
ttk.Button(controls_frame, text="Clear History", command=clear_history).pack(side="left")
# === Commands window ===
def open_commands_window():
"""
Create an extra window that shows buttons for each command found in COMMANDS.txt.
Each button sends the corresponding command string via SD.SendCommand.
"""
cmd_win = tk.Toplevel(root)
cmd_win.title("Command Buttons")
outer = ttk.Frame(cmd_win, padding=10)
outer.pack(fill="both", expand=True)
# Scrollable area in case there are many commands
canvas_widget = tk.Canvas(outer, borderwidth=0)
scrollbar = ttk.Scrollbar(outer, orient="vertical", command=canvas_widget.yview)
cmds_frame = ttk.Frame(canvas_widget)
cmds_frame.bind(
"<Configure>",
lambda e: canvas_widget.configure(scrollregion=canvas_widget.bbox("all"))
)
canvas_widget.create_window((0, 0), window=cmds_frame, anchor="nw")
canvas_widget.configure(yscrollcommand=scrollbar.set)
canvas_widget.pack(side="left", fill="both", expand=True)
scrollbar.pack(side="right", fill="y")
# Load commands from file
try:
with open(COMMANDS_FILE, "r") as f:
commands = [
line.strip()
for line in f
if line.strip() and not line.lstrip().startswith("#")
]
except OSError as e:
ttk.Label(
cmds_frame,
text=f"Could not read {COMMANDS_FILE}:\n{e}",
foreground="red",
justify="left"
).pack(anchor="w")
return
if not commands:
ttk.Label(
cmds_frame,
text=f"No commands found in {COMMANDS_FILE}.",
foreground="red"
).pack(anchor="w")
return
s = ttk.Style()
s.configure('TButton', font=('Arial', 14))
# Create a button per command
for i , cmd in enumerate(commands):
def make_callback(c=cmd):
def _cb():
# Ensure it ends with newline/carriage return similar to console input
to_send = c
if not to_send.endswith("\n") and not to_send.endswith("\r"):
to_send = to_send + "\n\r"
SD.SendCommand(to_send)
return _cb
row = i // 2
col = i % 2
btn = ttk.Button(cmds_frame, text=cmd, command=make_callback(),style='TButton')
btn.grid(row=row, column=col, padx=5, pady=5, sticky="ew")
cmds_frame.columnconfigure(0, weight=1)
cmds_frame.columnconfigure(1, weight=1)
# Add a button in the main UI to reopen the commands window if needed
ttk.Button(controls_frame, text="Open Commands", command=open_commands_window).pack(side="left", padx=(10, 0))
# === Update functions ===
Last_tick: int = 0
def update_grid(values: list, tick: int):
"""Update the 4x4 grid with raw ADC values and write ADC csv."""
global Last_tick
# NOTE: mode should be "a" or "a+", not "+a"
with open(f"{FILENAME}_ADC.csv", "a") as file:
file.write(f"{tick}")
for i in range(16): # 16 raw ADC channels
file.write(f",{values[i]}")
labels[i].config(text=f"{values[i]:n}")
ms_total = tick
hours, rem = divmod(ms_total, 3_600_000) # 1000*60*60
minutes, rem = divmod(rem, 60_000) # 1000*60
seconds, milliseconds = divmod(rem, 1000)
labels[16].config(text=f"UP Time:{hours:02d}:{minutes:02d}:{seconds:02d}.{milliseconds:03d}")
labels[17].config(text=f"Delta Tick:{(tick - Last_tick):n}")
Last_tick = tick
file.write("\n")
def update_SI(value: SD.ReturnDecoder):
# NOTE: mode should be "a" or "a+", not "+a"
with open(f"{FILENAME}_SI.csv", "a") as file:
file.write(f"{value.timestamp},{value.log_message}\n")
print(f"Time:{value.timestamp}, SI:{value.log_message}", end="\n")
Last_history_call: int = 0
def append_history(adc_values: list, timestamp: int):
"""Store the new sample in the rolling history (derived units)."""
global Last_history_call
if len(history_x) > 0 and timestamp < history_x[-1]:
return # discard out-of-order samples
if len(history_x) > 0 and (history_x[-1] + (int(time.time_ns() / 1000000) - Last_history_call) * 2) < timestamp:
print(f"Discarding future sample: {timestamp} > {history_x[-1]} + "
f"{(int(time.time_ns() / 1000000) - Last_history_call) * 2}")
return # discard samples too far in future
history_x.append(timestamp)
Last_history_call = int(time.time_ns() / 1000000) # in ms
# 0: Thrust (average of load cells 0 and 1)
lc_avg = (adc_values[0] + adc_values[1]) / 2
weight = -1.166759308000000e-04 * lc_avg + 4.971416323340051e+02
history_y[0].append(weight)
# 1-6: Temperatures from channels 2..7
for i in range(2, 8): # six thermocouples
temp = 0.000111 * adc_values[i] + 2.31991
history_y[i - 1].append(temp) # 2→1, 7→6
# 7-14: Pressures from channels 8..15
for i in range(8, 16): # eight pressure sensors
if i == 12:
pres = 0.0000153522 * (adc_values[i] / 2) - 6.5652036917
history_y[i - 1].append(pres) # 8→7, 15→14
else:
pres = 0.0000153522 * adc_values[i] - 6.5652036917
history_y[i - 1].append(pres) # 8→7, 15→14
def update_plot():
"""Redraw plot based on selected derived channels and available history."""
ax.clear()
ax.set_title("Selected Channels")
ax.set_xlabel("Timestamp")
ax.set_ylabel("Value")
selected = [i for i, var in enumerate(check_vars) if var.get() == 1]
if len(history_x) == 0 or len(selected) == 0:
ax.text(
0.5, 0.5,
"No data / No channels selected",
ha="center", va="center",
transform=ax.transAxes
)
canvas.draw()
return
x = list(history_x)
for idx in selected:
# safety: guard against any mismatch, just in case
if idx < len(history_y):
y = list(history_y[idx])
ax.plot(x, y, label=DERIVED_CHANNEL_LABELS[idx])
ax.legend(loc="upper left", fontsize=8)
ax.grid(True, linestyle="--", alpha=0.3)
canvas.draw()
# Now that update_plot exists, fix the checkbox command to point to it
for child in check_frame.winfo_children():
if isinstance(child, ttk.Checkbutton):
child.config(command=update_plot)
def update_panel():
"""Main polling loop that consumes Serial_decoder outputs."""
values: SD.ReturnDecoder = SD.GetReturn(0.1) # non-blocking read with timeout
if values is None:
root.after(10, update_panel)
return
# Stop if input thread died
if tasks[1].is_alive() is False:
root.quit()
match values.name:
case "ADC_FULLRANK":
# Update grid + history + plot
update_grid(values=values.ADC_data, tick=values.timestamp)
append_history(values.ADC_data, values.timestamp)
update_plot() # draw right away; if too heavy, throttle with a timer
case "SI_DECODER":
update_SI(values)
case "PR_DECODER":
print(f"PRD:{values.text_respons}")
case _:
print(f"Error {values.name}")
# Continue polling
root.after(10, update_panel) # 10 ms
# Start polling and GUI loop
update_panel()
# FC commands
SD.SerialPort.write(b"SET_ST_SPEED 100\n\r")
# Open the commands window at startup
open_commands_window()
root.mainloop()

35
run1.m Normal file
View File

@@ -0,0 +1,35 @@
close all
result = readmatrix("2025_12_03_16_23_RUN1_ADC.csv");
%result = result(14430:end, : );
result(:,14) = result(:,14)./2;
time = result(:,1);
temp = 0.000111 .* result(:,4:9) + 2.31991;
pressure = result(:,10:17).*(0.000015)-6.565;
load_cell = result(:,2:3);
weight = -1.166759307845543e-04 .* 0.5.*(load_cell(:,1) + load_cell(:,2)) + 4.971416323340051e+02;
figure()
scatter(time,weight,10)
title("load cell in Kg")
xlabel("Time in ms")
ylabel("KG")
for x = 1:7
figure()
scatter(time,pressure(:,x),10)
title(sprintf("Pressure channel %d",x))
xlabel("Time in ms")
ylabel("Pressure")
end
for x = 1:6
figure()
scatter(time,temp(:,x),10)
title(sprintf("temperature channel %d",x))
xlabel("Time in ms")
ylabel("Temprature in C")
end

38
run2.m Normal file
View File

@@ -0,0 +1,38 @@
close all
result = readmatrix("RUN2_ADC_data.csv");
%result = result(14430:end, : );
result(:,14) = result(:,14)./2;
time = result(:,1)./1000;
temp = 0.000111 .* result(:,4:9) + 2.31991;
pressure = result(:,10:17).*(0.000015)-6.565;
load_cell = result(:,2:3);
weight = -1.166759307845543e-04 .* 0.5.*(load_cell(:,1) + load_cell(:,2)) + 4.971416323340051e+02;
figure()
scatter(time,weight,10)
title("load cell in Kg")
xlabel("Time in s")
ylabel("KG")
xlim([900.817 911.840])
for x = 1:7
figure()
scatter(time,pressure(:,x),10)
title(sprintf("Pressure channel %d",x))
xlabel("Time in s")
ylabel("Pressure")
xlim([900.817 911.840])
end
for x = 1:6
figure()
scatter(time,temp(:,x),10)
title(sprintf("temperature channel %d",x))
xlabel("Time in s")
ylabel("Temprature in C")
xlim([900.817 911.840])
end