Month: February 2025
Summation of graphs to one graph
I have multiple graphs and i wand to sum all these graphs together to have a simple one. (adding them like 1+1=2)I have multiple graphs and i wand to sum all these graphs together to have a simple one. (adding them like 1+1=2) I have multiple graphs and i wand to sum all these graphs together to have a simple one. (adding them like 1+1=2) sum, graph MATLAB Answers — New Questions
embeddedLinuxExplorer cannot talk to ZCU208 Xilinx board
I have a working SOC Blockset design on a Xilinx ZCU208 RFSoC eval card. SOC Blockset talks to the Matlab enbedded Linux running on the board well. I would like to use embeddedLinuxExplorer, but it will not recognize the board. When I invoke embeddedLinuxExplorer, it does not list the board, even though SOC Blockset can talk to it. If I try to add the IP address and login manually to embeddedLinuxExplorer, it says "Board is already present". So, no way to use embeddedLinuxExplorer on this board. Has anyone else run into this problem?
Thanks,
PaulI have a working SOC Blockset design on a Xilinx ZCU208 RFSoC eval card. SOC Blockset talks to the Matlab enbedded Linux running on the board well. I would like to use embeddedLinuxExplorer, but it will not recognize the board. When I invoke embeddedLinuxExplorer, it does not list the board, even though SOC Blockset can talk to it. If I try to add the IP address and login manually to embeddedLinuxExplorer, it says "Board is already present". So, no way to use embeddedLinuxExplorer on this board. Has anyone else run into this problem?
Thanks,
Paul I have a working SOC Blockset design on a Xilinx ZCU208 RFSoC eval card. SOC Blockset talks to the Matlab enbedded Linux running on the board well. I would like to use embeddedLinuxExplorer, but it will not recognize the board. When I invoke embeddedLinuxExplorer, it does not list the board, even though SOC Blockset can talk to it. If I try to add the IP address and login manually to embeddedLinuxExplorer, it says "Board is already present". So, no way to use embeddedLinuxExplorer on this board. Has anyone else run into this problem?
Thanks,
Paul embeddedlinuxexplorer, zcu208, linux MATLAB Answers — New Questions
How to make matlab and simulink work simultaneously.
Hi, im working on a ball on a plate system, i dont have a system model and i want to auto tune my PID controller on the basis of the data received from sensors. I want to know how to auto tune PID in matlab or if theres a way to connect sensor data with simulink in real time for auto tuning purpose. Moreover, i find it difficult to perfrom image processing to gather data in simulink. My code is shared below for further assistance.
%% Initialize Environment
clear all;
clc;
close all;
%% Initialize Data Logging
logFile = fopen(‘data_log.csv’, ‘w’); % Open a CSV file for writing
fprintf(logFile, ‘Time,Disturbance1,Disturbance2,Disturbance3,RollAngle,PitchAngle,CentroidX,CentroidY,Servo1,Servo2,Servo3n’); % Header row
stateLogFile = fopen(‘state_log.csv’, ‘w’); % Open another CSV file for writing
fprintf(stateLogFile, ‘Time,Phi,Theta,X_Offset,Y_Offset,Zp,Gamman’); % Header row
%% Initialize Image Processing
% Load the camera parameters
load(‘test.mat’); % Ensure the file ‘cameraParams.mat’ is in your working directory
% Create a webcam object
cap = webcam(‘Adesso CyberTrack H3’);
dist_1 = 0;
dist_2=dist_1
dist_3=dist_2
% Adjust camera settings if supported
try
% Set exposure time within valid range
exposureTime = -6; % Adjust as needed within the valid range
cap.ExposureMode = ‘manual’;
cap.Exposure = exposureTime;
catch ME
disp(‘Warning: Unable to set exposure time for the camera.’);
disp(ME.message);
end
%% Anomaly Variables
% Parameters for angle adjustments
p_a = 0;
p_r = 0;
%% Blob Object
% Blob analysis object for ball detection
% Blob analysis object for ball detection using vision.BlobAnalysis
blobAnalyzer = vision.BlobAnalysis(…
‘MinimumBlobArea’, 200, … % Adjust to filter small noise
‘MaximumBlobArea’, 50000, … % Adjust to ensure the ball is detected
‘BoundingBoxOutputPort’, true, …
‘CentroidOutputPort’, true, …
‘AreaOutputPort’, true);
%% Create Figure and Axes
hFig = figure(‘DoubleBuffer’, ‘on’);
hAxes = axes(‘Parent’, hFig);
s = 1;
%% Main Loop
%% Measure Sampling Time
%% Servo Motor Control Initial Position
% Port at which your Arduino is connected
port = ‘COM5’;
% Model of your Arduino board
board = ‘Uno’;
% Creating Arduino object with servo library
arduino_board = arduino(port, board, ‘Libraries’, ‘Servo’);
% Creating servo motor object
servo_motor = servo(arduino_board, ‘D9′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor, 0.333); % 45 degrees in as per calculations and in radians = 0.333
servo_motor1 = servo(arduino_board, ‘D10′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor1, 0.333);
servo_motor2 = servo(arduino_board, ‘D11′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor2, 0.333);
A= 45;
B= 45;
C = 45;
disp(‘done here1’);
h = 1;
for i = 1:2
%% Image Processing Started
start = tic;
[Zp,alpha] = forwardkinfunc(A,B,C);
% Read frame from webcam
frame = snapshot(cap);
% Undistort the frame using the camera parameters
undistortedFrame = undistortImage(frame, cameraParams2);
% Resize the undistorted frame to a lower resolution (e.g., half the original size)
undistortedFrame = imresize(undistortedFrame, 0.2); % Reduce resolution to 50%
%% Calculate the center of the image
[frameHeight, frameWidth, ~] = size(undistortedFrame);
centerX = frameWidth / 2;
centerY = frameHeight / 2;
%% Circle (Dot) Detection
% Convert to grayscale and adjust contrast
I_gray = rgb2gray(undistortedFrame);
I_contrast = imadjust(I_gray);
% Detect circles in the image (dots)
[Centers, Radii] = imfindcircles(I_contrast, [1 5], ‘ObjectPolarity’, ‘dark’, ‘Sensitivity’, 0.9);
% Check if circles are detected
if isempty(Centers)
disp(‘No circles detected’);
else
disp([‘Detected ‘, num2str(size(Centers, 1)), ‘ circles’]);
end
% Display the undistorted frame and detected circles
imshow(undistortedFrame, ‘Parent’, hAxes);
hold(hAxes, ‘on’);
viscircles(hAxes, Centers, Radii, ‘EdgeColor’, ‘r’);
% Plot a magenta dot at the center of the image
plot(hAxes, centerX, centerY, ‘m.’, ‘MarkerSize’, 20); % Magenta dot
% Check if at least 2 circles are detected for line fitting
if size(Centers, 1) >= 2
% Fit lines to X and Y coordinates separately
x = Centers(:, 1);
yof = Centers(:, 2);
pX = polyfit(yof, x, 1); % Line fit for X as a function of Y
pY = polyfit(x, yof, 1); % Line fit for Y as a function of X
% Display fitted line coefficients
disp([‘Line fit for X (Y): slope = ‘, num2str(pX(1))]);
disp([‘Line fit for Y (X): slope = ‘, num2str(pY(1))]);
% Calculate the slopes
slopeX = pX(1);
slopeY = pY(1);
% Calculate roll and pitch angles from the slopes
Theta = -atan2(slopeX, 1); % Tilt along X-axis (roll)
Phi = atan2(slopeY, 1); % Tilt along Y-axis (pitch)
% Display calculated angles
disp([‘Roll Angle: ‘, num2str(Theta)]);
disp([‘Pitch Angle: ‘, num2str(Phi)]);
% Draw the X and Y axis lines
plot(hAxes, [0, size(I_contrast, 2)], [mean(yof), mean(yof)], ‘g–‘, ‘LineWidth’, 2); % X-axis line
plot(hAxes, [mean(x), mean(x)], [0, size(I_contrast, 1)], ‘y–‘, ‘LineWidth’, 2); % Y-axis line
% Draw the slope lines
yFitLineX = polyval(pX, [0, size(I_contrast, 1)]);
plot(hAxes, yFitLineX, [0, size(I_contrast, 1)], ‘b-‘, ‘LineWidth’, 2); % Slope line for X
xFitLineY = polyval(pY, [0, size(I_contrast, 2)]);
plot(hAxes, [0, size(I_contrast, 2)], xFitLineY, ‘r-‘, ‘LineWidth’, 2); % Slope line for Y
% Display the calculated angles
title(hAxes, sprintf(‘Roll: %.2f°, Pitch: %.2f°’, Theta, Phi));
else
title(hAxes, ‘Not enough circles detected’);
end
%% Ball Detection Using vision.BlobAnalysis
% Check if any blobs are detected
%% Ball Detection Using vision.BlobAnalysis
hsvFrame = rgb2hsv(undistortedFrame);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.845;
channel1Max = 0.081;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.133;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.519;
channel3Max = 1.000;
% Create a binary mask based on chosen histogram thresholds
sliderBW = ((hsvFrame(:,:,1) >= channel1Min) | (hsvFrame(:,:,1) <= channel1Max)) & …
(hsvFrame(:,:,2) >= channel2Min) & (hsvFrame(:,:,2) <= channel2Max) & …
(hsvFrame(:,:,3) >= channel3Min) & (hsvFrame(:,:,3) <= channel3Max);
BW = sliderBW;
BW = imfill(BW, ‘holes’); % Fill any small holes
BW = bwareaopen(BW, 200); % Remove small noise (adjust 200 as needed)
% Apply morphological operations to clean up the mask
BW = imopen(BW, strel(‘disk’, 5));
BW = imclose(BW, strel(‘disk’, 20));
% Perform blob analysis
[area,centroid,bbox] = step(blobAnalyzer,BW);
if ~isempty(centroid)
x_p = centroid(1);
y_p = centroid(2);
% Draw the bounding box on the undistorted frame
rectangle(‘Position’, bbox, ‘EdgeColor’, ‘green’, ‘LineWidth’, 2);
plot(hAxes, x_p, y_p, ‘ro’, ‘MarkerSize’, 10);
pix_cm = 32/frameWidth;
xc = x_p*pix_cm;
yc = y_p*pix_cm
[xof1, yof1] = camera_base(xc,yc)
end
elapsed_time = toc(start); % Compute elapsed time dynamically
Ts = getElapsedTime();% Use elapsed time for PID calculations
tic;
Kp_x = 10; Ki_x = 0; Kd_x = 0
Kp_y = 10; Ki_y = 0; Kd_y = 0;
Kp_phi = 80; Ki_phi = 0; Kd_phi = 0.5;
Kp_theta =80; Ki_theta =0; Kd_theta = 0.5;
% Setpoints (target values)
setpoint_x = -0.1;
setpoint_y = -5.5;
setpoint_phi = 0.00;
setpoint_theta = 0.00;
previous_errorx = 0;
integral_errorx=0
derivative_errorx = 0
previous_errory = 0;
integral_errory=0
derivative_errory = 0
previous_errorphi = 0;
integral_errorphi=0
derivative_errorphi = 0
previous_errortheta = 0;
integral_errortheta=0
derivative_errortheta = 0
prev_filtest = 0;
filte_est =0;
prev_filtesty = 0;
filte_esty =0;
prev_filtestp = 0;
filte_estp =0;
prev_filtestth = 0;
filte_estth =0;
o = 0.05;
K_xp = 4/100;
K_yp= 4.8/100;
K_xr = 0.63/100;
K_yr = 3.05/100;
error_x= setpoint_x – xof1;
integral_errorx = integral_errorx + error_x * Ts;
derivative_errorx = (error_x – previous_errorx);
filte_est = (o*prev_filtest)+(1-o)*derivative_errorx
derivative = filte_est/Ts;
prev_filtest = filte_est;
control_signalx = Kp_x * error_x + Ki_x * integral_errorx + Kd_x * derivative;
previous_errorx = error_x;
% Cross-coupling effect on phi due to x_error
theta_coupling_effect = K_xr * error_x;
error_y= setpoint_y – yof1;
integral_errory = integral_errory + error_y * Ts;
derivative_errory = (error_y – previous_errory)
filte_esty = (o*prev_filtesty)+(1-o)*derivative_errory
derivativey = filte_esty/Ts;
prev_filtesty = filte_esty;
control_signaly = Kp_y * error_y + Ki_y * integral_errory + Kd_y * derivativey;
previous_errory = error_y;
% Cross-coupling effect on theta due to y_error
phi_coupling_effect = K_yp * error_y;
% Step 5: Compute final tilt angles
theta_desired =(K_yr * error_y) + phi_coupling_effect; % Roll (tilt about X-axis)
phi_desired = (K_xp * error_x) + theta_coupling_effect; % Pitch (tilt about Y-axis)
error_phi= phi_desired – Phi;
integral_errorphi = integral_errorphi + error_phi * Ts;
derivative_errorphi = (error_phi – previous_errorphi)
filte_estp = (o*prev_filtestp)+(1-o)*derivative_errorphi
derivativep = filte_estp/Ts;
prev_filtestp = filte_estp;
control_signalphi = Kp_phi * error_phi + Ki_phi * integral_errorphi + Kd_phi * derivativep;
previous_errorphi = error_phi;
Phi1 = (Phi + control_signalphi * Ts); % Update tilt
Phi1 = max(-0.6, min(Phi1, 0.6));
pidTuner(Phi1)
error_theta= theta_desired – Theta;
integral_errortheta = integral_errortheta + error_theta * Ts;
derivative_errortheta = (error_theta – previous_errortheta)
filte_estth = (o*prev_filtestth)+(1-o)*derivative_errortheta;
derivativeth = filte_estth/Ts;
prev_filtestth = filte_estth;
control_signaltheta = Kp_theta * error_theta + Ki_theta * integral_errortheta + Kd_theta * derivativeth;
previous_errortheta = error_theta;
Theta1 = (Theta + control_signaltheta * Ts); % Update tilt
Theta1 = max(-0.6, min(Theta1, 0.6));
xof1 = xof1+(control_signalx*Ts);
yof1 = yof1+(control_signaly*Ts)
disp(‘done here 3’)
xo= 82*sin(Phi);
yo =-82*sin(Theta);
[a11f,a22f,a33f] = inversekin(xof1,yof1,Phi1,Theta1,Zp,alpha)
% [a11f,a22f,a33f] = inversekin(xof1,yof1,phi_control,theta_control,Zp,gamma)
a11 = a11f;
a22 = a22f;
a33 = a33f;
disp(‘done here 4’)
% Clamp the angles to the range 40° to 50°
a11 = max(42, min(a11, 48));
a22 = max(42, min(a22, 48));
a33 = max(42, min(a33, 48));
currentTime = datestr(now, ‘HH:MM:SS.FFF’); % Get current time
fprintf(logFile, ‘%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.4f,%.4f,%.4fn’, …
currentTime, dist_1, dist_2, dist_3, Phi, Theta, xof1, yof1,a11, a22, a33);
% fprintf(stateLogFile, ‘%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3fn’, Ts, Phi, Theta, xof1, yof1, Zp, gamma);
%% Servo Motor Code
% Clamp the angles to the range 40° to 50°
a = normalize(a11);
b = normalize(a22);
c = normalize(a33);
writePosition(servo_motor,a)
writePosition(servo_motor1,b)
writePosition(servo_motor2,c)
stop_it = toc(start);
A = a11;
B = a22;
C= a33;
stop = toc(start)
disp(‘done here 5’);
if (xof1 <=0.5 && xof1>=-0.5)&&(yof1 <= 1.5 &&yof1>=-1.5)
% if (xof1==0 && yof1==0)
disp(‘im done’)
writePosition(servo_motor,0.3300)
writePosition(servo_motor1,0.3300)
writePosition(servo_motor2,0.3300)
break;
else
disp(‘continued’)
h = h+1
end
end
% Clean up
fclose(logFile); % Close the log file
clear arduino_board servo_motor servo_motor1 servo_motor2 s
clear cap;
release(blobAnalyzer);
close(hFig); % Close the figure when done
disp(‘System is Stable’);
function norm_position = normalize(angle_deg)
angle_deg = angle_deg/1.5;
angle_deg = 90 – angle_deg;
angle_deg = angle_deg – (angle_deg/100);
norm_position = angle_deg/180;
endHi, im working on a ball on a plate system, i dont have a system model and i want to auto tune my PID controller on the basis of the data received from sensors. I want to know how to auto tune PID in matlab or if theres a way to connect sensor data with simulink in real time for auto tuning purpose. Moreover, i find it difficult to perfrom image processing to gather data in simulink. My code is shared below for further assistance.
%% Initialize Environment
clear all;
clc;
close all;
%% Initialize Data Logging
logFile = fopen(‘data_log.csv’, ‘w’); % Open a CSV file for writing
fprintf(logFile, ‘Time,Disturbance1,Disturbance2,Disturbance3,RollAngle,PitchAngle,CentroidX,CentroidY,Servo1,Servo2,Servo3n’); % Header row
stateLogFile = fopen(‘state_log.csv’, ‘w’); % Open another CSV file for writing
fprintf(stateLogFile, ‘Time,Phi,Theta,X_Offset,Y_Offset,Zp,Gamman’); % Header row
%% Initialize Image Processing
% Load the camera parameters
load(‘test.mat’); % Ensure the file ‘cameraParams.mat’ is in your working directory
% Create a webcam object
cap = webcam(‘Adesso CyberTrack H3’);
dist_1 = 0;
dist_2=dist_1
dist_3=dist_2
% Adjust camera settings if supported
try
% Set exposure time within valid range
exposureTime = -6; % Adjust as needed within the valid range
cap.ExposureMode = ‘manual’;
cap.Exposure = exposureTime;
catch ME
disp(‘Warning: Unable to set exposure time for the camera.’);
disp(ME.message);
end
%% Anomaly Variables
% Parameters for angle adjustments
p_a = 0;
p_r = 0;
%% Blob Object
% Blob analysis object for ball detection
% Blob analysis object for ball detection using vision.BlobAnalysis
blobAnalyzer = vision.BlobAnalysis(…
‘MinimumBlobArea’, 200, … % Adjust to filter small noise
‘MaximumBlobArea’, 50000, … % Adjust to ensure the ball is detected
‘BoundingBoxOutputPort’, true, …
‘CentroidOutputPort’, true, …
‘AreaOutputPort’, true);
%% Create Figure and Axes
hFig = figure(‘DoubleBuffer’, ‘on’);
hAxes = axes(‘Parent’, hFig);
s = 1;
%% Main Loop
%% Measure Sampling Time
%% Servo Motor Control Initial Position
% Port at which your Arduino is connected
port = ‘COM5’;
% Model of your Arduino board
board = ‘Uno’;
% Creating Arduino object with servo library
arduino_board = arduino(port, board, ‘Libraries’, ‘Servo’);
% Creating servo motor object
servo_motor = servo(arduino_board, ‘D9′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor, 0.333); % 45 degrees in as per calculations and in radians = 0.333
servo_motor1 = servo(arduino_board, ‘D10′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor1, 0.333);
servo_motor2 = servo(arduino_board, ‘D11′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor2, 0.333);
A= 45;
B= 45;
C = 45;
disp(‘done here1’);
h = 1;
for i = 1:2
%% Image Processing Started
start = tic;
[Zp,alpha] = forwardkinfunc(A,B,C);
% Read frame from webcam
frame = snapshot(cap);
% Undistort the frame using the camera parameters
undistortedFrame = undistortImage(frame, cameraParams2);
% Resize the undistorted frame to a lower resolution (e.g., half the original size)
undistortedFrame = imresize(undistortedFrame, 0.2); % Reduce resolution to 50%
%% Calculate the center of the image
[frameHeight, frameWidth, ~] = size(undistortedFrame);
centerX = frameWidth / 2;
centerY = frameHeight / 2;
%% Circle (Dot) Detection
% Convert to grayscale and adjust contrast
I_gray = rgb2gray(undistortedFrame);
I_contrast = imadjust(I_gray);
% Detect circles in the image (dots)
[Centers, Radii] = imfindcircles(I_contrast, [1 5], ‘ObjectPolarity’, ‘dark’, ‘Sensitivity’, 0.9);
% Check if circles are detected
if isempty(Centers)
disp(‘No circles detected’);
else
disp([‘Detected ‘, num2str(size(Centers, 1)), ‘ circles’]);
end
% Display the undistorted frame and detected circles
imshow(undistortedFrame, ‘Parent’, hAxes);
hold(hAxes, ‘on’);
viscircles(hAxes, Centers, Radii, ‘EdgeColor’, ‘r’);
% Plot a magenta dot at the center of the image
plot(hAxes, centerX, centerY, ‘m.’, ‘MarkerSize’, 20); % Magenta dot
% Check if at least 2 circles are detected for line fitting
if size(Centers, 1) >= 2
% Fit lines to X and Y coordinates separately
x = Centers(:, 1);
yof = Centers(:, 2);
pX = polyfit(yof, x, 1); % Line fit for X as a function of Y
pY = polyfit(x, yof, 1); % Line fit for Y as a function of X
% Display fitted line coefficients
disp([‘Line fit for X (Y): slope = ‘, num2str(pX(1))]);
disp([‘Line fit for Y (X): slope = ‘, num2str(pY(1))]);
% Calculate the slopes
slopeX = pX(1);
slopeY = pY(1);
% Calculate roll and pitch angles from the slopes
Theta = -atan2(slopeX, 1); % Tilt along X-axis (roll)
Phi = atan2(slopeY, 1); % Tilt along Y-axis (pitch)
% Display calculated angles
disp([‘Roll Angle: ‘, num2str(Theta)]);
disp([‘Pitch Angle: ‘, num2str(Phi)]);
% Draw the X and Y axis lines
plot(hAxes, [0, size(I_contrast, 2)], [mean(yof), mean(yof)], ‘g–‘, ‘LineWidth’, 2); % X-axis line
plot(hAxes, [mean(x), mean(x)], [0, size(I_contrast, 1)], ‘y–‘, ‘LineWidth’, 2); % Y-axis line
% Draw the slope lines
yFitLineX = polyval(pX, [0, size(I_contrast, 1)]);
plot(hAxes, yFitLineX, [0, size(I_contrast, 1)], ‘b-‘, ‘LineWidth’, 2); % Slope line for X
xFitLineY = polyval(pY, [0, size(I_contrast, 2)]);
plot(hAxes, [0, size(I_contrast, 2)], xFitLineY, ‘r-‘, ‘LineWidth’, 2); % Slope line for Y
% Display the calculated angles
title(hAxes, sprintf(‘Roll: %.2f°, Pitch: %.2f°’, Theta, Phi));
else
title(hAxes, ‘Not enough circles detected’);
end
%% Ball Detection Using vision.BlobAnalysis
% Check if any blobs are detected
%% Ball Detection Using vision.BlobAnalysis
hsvFrame = rgb2hsv(undistortedFrame);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.845;
channel1Max = 0.081;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.133;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.519;
channel3Max = 1.000;
% Create a binary mask based on chosen histogram thresholds
sliderBW = ((hsvFrame(:,:,1) >= channel1Min) | (hsvFrame(:,:,1) <= channel1Max)) & …
(hsvFrame(:,:,2) >= channel2Min) & (hsvFrame(:,:,2) <= channel2Max) & …
(hsvFrame(:,:,3) >= channel3Min) & (hsvFrame(:,:,3) <= channel3Max);
BW = sliderBW;
BW = imfill(BW, ‘holes’); % Fill any small holes
BW = bwareaopen(BW, 200); % Remove small noise (adjust 200 as needed)
% Apply morphological operations to clean up the mask
BW = imopen(BW, strel(‘disk’, 5));
BW = imclose(BW, strel(‘disk’, 20));
% Perform blob analysis
[area,centroid,bbox] = step(blobAnalyzer,BW);
if ~isempty(centroid)
x_p = centroid(1);
y_p = centroid(2);
% Draw the bounding box on the undistorted frame
rectangle(‘Position’, bbox, ‘EdgeColor’, ‘green’, ‘LineWidth’, 2);
plot(hAxes, x_p, y_p, ‘ro’, ‘MarkerSize’, 10);
pix_cm = 32/frameWidth;
xc = x_p*pix_cm;
yc = y_p*pix_cm
[xof1, yof1] = camera_base(xc,yc)
end
elapsed_time = toc(start); % Compute elapsed time dynamically
Ts = getElapsedTime();% Use elapsed time for PID calculations
tic;
Kp_x = 10; Ki_x = 0; Kd_x = 0
Kp_y = 10; Ki_y = 0; Kd_y = 0;
Kp_phi = 80; Ki_phi = 0; Kd_phi = 0.5;
Kp_theta =80; Ki_theta =0; Kd_theta = 0.5;
% Setpoints (target values)
setpoint_x = -0.1;
setpoint_y = -5.5;
setpoint_phi = 0.00;
setpoint_theta = 0.00;
previous_errorx = 0;
integral_errorx=0
derivative_errorx = 0
previous_errory = 0;
integral_errory=0
derivative_errory = 0
previous_errorphi = 0;
integral_errorphi=0
derivative_errorphi = 0
previous_errortheta = 0;
integral_errortheta=0
derivative_errortheta = 0
prev_filtest = 0;
filte_est =0;
prev_filtesty = 0;
filte_esty =0;
prev_filtestp = 0;
filte_estp =0;
prev_filtestth = 0;
filte_estth =0;
o = 0.05;
K_xp = 4/100;
K_yp= 4.8/100;
K_xr = 0.63/100;
K_yr = 3.05/100;
error_x= setpoint_x – xof1;
integral_errorx = integral_errorx + error_x * Ts;
derivative_errorx = (error_x – previous_errorx);
filte_est = (o*prev_filtest)+(1-o)*derivative_errorx
derivative = filte_est/Ts;
prev_filtest = filte_est;
control_signalx = Kp_x * error_x + Ki_x * integral_errorx + Kd_x * derivative;
previous_errorx = error_x;
% Cross-coupling effect on phi due to x_error
theta_coupling_effect = K_xr * error_x;
error_y= setpoint_y – yof1;
integral_errory = integral_errory + error_y * Ts;
derivative_errory = (error_y – previous_errory)
filte_esty = (o*prev_filtesty)+(1-o)*derivative_errory
derivativey = filte_esty/Ts;
prev_filtesty = filte_esty;
control_signaly = Kp_y * error_y + Ki_y * integral_errory + Kd_y * derivativey;
previous_errory = error_y;
% Cross-coupling effect on theta due to y_error
phi_coupling_effect = K_yp * error_y;
% Step 5: Compute final tilt angles
theta_desired =(K_yr * error_y) + phi_coupling_effect; % Roll (tilt about X-axis)
phi_desired = (K_xp * error_x) + theta_coupling_effect; % Pitch (tilt about Y-axis)
error_phi= phi_desired – Phi;
integral_errorphi = integral_errorphi + error_phi * Ts;
derivative_errorphi = (error_phi – previous_errorphi)
filte_estp = (o*prev_filtestp)+(1-o)*derivative_errorphi
derivativep = filte_estp/Ts;
prev_filtestp = filte_estp;
control_signalphi = Kp_phi * error_phi + Ki_phi * integral_errorphi + Kd_phi * derivativep;
previous_errorphi = error_phi;
Phi1 = (Phi + control_signalphi * Ts); % Update tilt
Phi1 = max(-0.6, min(Phi1, 0.6));
pidTuner(Phi1)
error_theta= theta_desired – Theta;
integral_errortheta = integral_errortheta + error_theta * Ts;
derivative_errortheta = (error_theta – previous_errortheta)
filte_estth = (o*prev_filtestth)+(1-o)*derivative_errortheta;
derivativeth = filte_estth/Ts;
prev_filtestth = filte_estth;
control_signaltheta = Kp_theta * error_theta + Ki_theta * integral_errortheta + Kd_theta * derivativeth;
previous_errortheta = error_theta;
Theta1 = (Theta + control_signaltheta * Ts); % Update tilt
Theta1 = max(-0.6, min(Theta1, 0.6));
xof1 = xof1+(control_signalx*Ts);
yof1 = yof1+(control_signaly*Ts)
disp(‘done here 3’)
xo= 82*sin(Phi);
yo =-82*sin(Theta);
[a11f,a22f,a33f] = inversekin(xof1,yof1,Phi1,Theta1,Zp,alpha)
% [a11f,a22f,a33f] = inversekin(xof1,yof1,phi_control,theta_control,Zp,gamma)
a11 = a11f;
a22 = a22f;
a33 = a33f;
disp(‘done here 4’)
% Clamp the angles to the range 40° to 50°
a11 = max(42, min(a11, 48));
a22 = max(42, min(a22, 48));
a33 = max(42, min(a33, 48));
currentTime = datestr(now, ‘HH:MM:SS.FFF’); % Get current time
fprintf(logFile, ‘%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.4f,%.4f,%.4fn’, …
currentTime, dist_1, dist_2, dist_3, Phi, Theta, xof1, yof1,a11, a22, a33);
% fprintf(stateLogFile, ‘%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3fn’, Ts, Phi, Theta, xof1, yof1, Zp, gamma);
%% Servo Motor Code
% Clamp the angles to the range 40° to 50°
a = normalize(a11);
b = normalize(a22);
c = normalize(a33);
writePosition(servo_motor,a)
writePosition(servo_motor1,b)
writePosition(servo_motor2,c)
stop_it = toc(start);
A = a11;
B = a22;
C= a33;
stop = toc(start)
disp(‘done here 5’);
if (xof1 <=0.5 && xof1>=-0.5)&&(yof1 <= 1.5 &&yof1>=-1.5)
% if (xof1==0 && yof1==0)
disp(‘im done’)
writePosition(servo_motor,0.3300)
writePosition(servo_motor1,0.3300)
writePosition(servo_motor2,0.3300)
break;
else
disp(‘continued’)
h = h+1
end
end
% Clean up
fclose(logFile); % Close the log file
clear arduino_board servo_motor servo_motor1 servo_motor2 s
clear cap;
release(blobAnalyzer);
close(hFig); % Close the figure when done
disp(‘System is Stable’);
function norm_position = normalize(angle_deg)
angle_deg = angle_deg/1.5;
angle_deg = 90 – angle_deg;
angle_deg = angle_deg – (angle_deg/100);
norm_position = angle_deg/180;
end Hi, im working on a ball on a plate system, i dont have a system model and i want to auto tune my PID controller on the basis of the data received from sensors. I want to know how to auto tune PID in matlab or if theres a way to connect sensor data with simulink in real time for auto tuning purpose. Moreover, i find it difficult to perfrom image processing to gather data in simulink. My code is shared below for further assistance.
%% Initialize Environment
clear all;
clc;
close all;
%% Initialize Data Logging
logFile = fopen(‘data_log.csv’, ‘w’); % Open a CSV file for writing
fprintf(logFile, ‘Time,Disturbance1,Disturbance2,Disturbance3,RollAngle,PitchAngle,CentroidX,CentroidY,Servo1,Servo2,Servo3n’); % Header row
stateLogFile = fopen(‘state_log.csv’, ‘w’); % Open another CSV file for writing
fprintf(stateLogFile, ‘Time,Phi,Theta,X_Offset,Y_Offset,Zp,Gamman’); % Header row
%% Initialize Image Processing
% Load the camera parameters
load(‘test.mat’); % Ensure the file ‘cameraParams.mat’ is in your working directory
% Create a webcam object
cap = webcam(‘Adesso CyberTrack H3’);
dist_1 = 0;
dist_2=dist_1
dist_3=dist_2
% Adjust camera settings if supported
try
% Set exposure time within valid range
exposureTime = -6; % Adjust as needed within the valid range
cap.ExposureMode = ‘manual’;
cap.Exposure = exposureTime;
catch ME
disp(‘Warning: Unable to set exposure time for the camera.’);
disp(ME.message);
end
%% Anomaly Variables
% Parameters for angle adjustments
p_a = 0;
p_r = 0;
%% Blob Object
% Blob analysis object for ball detection
% Blob analysis object for ball detection using vision.BlobAnalysis
blobAnalyzer = vision.BlobAnalysis(…
‘MinimumBlobArea’, 200, … % Adjust to filter small noise
‘MaximumBlobArea’, 50000, … % Adjust to ensure the ball is detected
‘BoundingBoxOutputPort’, true, …
‘CentroidOutputPort’, true, …
‘AreaOutputPort’, true);
%% Create Figure and Axes
hFig = figure(‘DoubleBuffer’, ‘on’);
hAxes = axes(‘Parent’, hFig);
s = 1;
%% Main Loop
%% Measure Sampling Time
%% Servo Motor Control Initial Position
% Port at which your Arduino is connected
port = ‘COM5’;
% Model of your Arduino board
board = ‘Uno’;
% Creating Arduino object with servo library
arduino_board = arduino(port, board, ‘Libraries’, ‘Servo’);
% Creating servo motor object
servo_motor = servo(arduino_board, ‘D9′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor, 0.333); % 45 degrees in as per calculations and in radians = 0.333
servo_motor1 = servo(arduino_board, ‘D10′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor1, 0.333);
servo_motor2 = servo(arduino_board, ‘D11′,’MinPulseDuration’, 500e-6, ‘MaxPulseDuration’, 2500e-6);
writePosition(servo_motor2, 0.333);
A= 45;
B= 45;
C = 45;
disp(‘done here1’);
h = 1;
for i = 1:2
%% Image Processing Started
start = tic;
[Zp,alpha] = forwardkinfunc(A,B,C);
% Read frame from webcam
frame = snapshot(cap);
% Undistort the frame using the camera parameters
undistortedFrame = undistortImage(frame, cameraParams2);
% Resize the undistorted frame to a lower resolution (e.g., half the original size)
undistortedFrame = imresize(undistortedFrame, 0.2); % Reduce resolution to 50%
%% Calculate the center of the image
[frameHeight, frameWidth, ~] = size(undistortedFrame);
centerX = frameWidth / 2;
centerY = frameHeight / 2;
%% Circle (Dot) Detection
% Convert to grayscale and adjust contrast
I_gray = rgb2gray(undistortedFrame);
I_contrast = imadjust(I_gray);
% Detect circles in the image (dots)
[Centers, Radii] = imfindcircles(I_contrast, [1 5], ‘ObjectPolarity’, ‘dark’, ‘Sensitivity’, 0.9);
% Check if circles are detected
if isempty(Centers)
disp(‘No circles detected’);
else
disp([‘Detected ‘, num2str(size(Centers, 1)), ‘ circles’]);
end
% Display the undistorted frame and detected circles
imshow(undistortedFrame, ‘Parent’, hAxes);
hold(hAxes, ‘on’);
viscircles(hAxes, Centers, Radii, ‘EdgeColor’, ‘r’);
% Plot a magenta dot at the center of the image
plot(hAxes, centerX, centerY, ‘m.’, ‘MarkerSize’, 20); % Magenta dot
% Check if at least 2 circles are detected for line fitting
if size(Centers, 1) >= 2
% Fit lines to X and Y coordinates separately
x = Centers(:, 1);
yof = Centers(:, 2);
pX = polyfit(yof, x, 1); % Line fit for X as a function of Y
pY = polyfit(x, yof, 1); % Line fit for Y as a function of X
% Display fitted line coefficients
disp([‘Line fit for X (Y): slope = ‘, num2str(pX(1))]);
disp([‘Line fit for Y (X): slope = ‘, num2str(pY(1))]);
% Calculate the slopes
slopeX = pX(1);
slopeY = pY(1);
% Calculate roll and pitch angles from the slopes
Theta = -atan2(slopeX, 1); % Tilt along X-axis (roll)
Phi = atan2(slopeY, 1); % Tilt along Y-axis (pitch)
% Display calculated angles
disp([‘Roll Angle: ‘, num2str(Theta)]);
disp([‘Pitch Angle: ‘, num2str(Phi)]);
% Draw the X and Y axis lines
plot(hAxes, [0, size(I_contrast, 2)], [mean(yof), mean(yof)], ‘g–‘, ‘LineWidth’, 2); % X-axis line
plot(hAxes, [mean(x), mean(x)], [0, size(I_contrast, 1)], ‘y–‘, ‘LineWidth’, 2); % Y-axis line
% Draw the slope lines
yFitLineX = polyval(pX, [0, size(I_contrast, 1)]);
plot(hAxes, yFitLineX, [0, size(I_contrast, 1)], ‘b-‘, ‘LineWidth’, 2); % Slope line for X
xFitLineY = polyval(pY, [0, size(I_contrast, 2)]);
plot(hAxes, [0, size(I_contrast, 2)], xFitLineY, ‘r-‘, ‘LineWidth’, 2); % Slope line for Y
% Display the calculated angles
title(hAxes, sprintf(‘Roll: %.2f°, Pitch: %.2f°’, Theta, Phi));
else
title(hAxes, ‘Not enough circles detected’);
end
%% Ball Detection Using vision.BlobAnalysis
% Check if any blobs are detected
%% Ball Detection Using vision.BlobAnalysis
hsvFrame = rgb2hsv(undistortedFrame);
% Define thresholds for channel 1 based on histogram settings
channel1Min = 0.845;
channel1Max = 0.081;
% Define thresholds for channel 2 based on histogram settings
channel2Min = 0.133;
channel2Max = 1.000;
% Define thresholds for channel 3 based on histogram settings
channel3Min = 0.519;
channel3Max = 1.000;
% Create a binary mask based on chosen histogram thresholds
sliderBW = ((hsvFrame(:,:,1) >= channel1Min) | (hsvFrame(:,:,1) <= channel1Max)) & …
(hsvFrame(:,:,2) >= channel2Min) & (hsvFrame(:,:,2) <= channel2Max) & …
(hsvFrame(:,:,3) >= channel3Min) & (hsvFrame(:,:,3) <= channel3Max);
BW = sliderBW;
BW = imfill(BW, ‘holes’); % Fill any small holes
BW = bwareaopen(BW, 200); % Remove small noise (adjust 200 as needed)
% Apply morphological operations to clean up the mask
BW = imopen(BW, strel(‘disk’, 5));
BW = imclose(BW, strel(‘disk’, 20));
% Perform blob analysis
[area,centroid,bbox] = step(blobAnalyzer,BW);
if ~isempty(centroid)
x_p = centroid(1);
y_p = centroid(2);
% Draw the bounding box on the undistorted frame
rectangle(‘Position’, bbox, ‘EdgeColor’, ‘green’, ‘LineWidth’, 2);
plot(hAxes, x_p, y_p, ‘ro’, ‘MarkerSize’, 10);
pix_cm = 32/frameWidth;
xc = x_p*pix_cm;
yc = y_p*pix_cm
[xof1, yof1] = camera_base(xc,yc)
end
elapsed_time = toc(start); % Compute elapsed time dynamically
Ts = getElapsedTime();% Use elapsed time for PID calculations
tic;
Kp_x = 10; Ki_x = 0; Kd_x = 0
Kp_y = 10; Ki_y = 0; Kd_y = 0;
Kp_phi = 80; Ki_phi = 0; Kd_phi = 0.5;
Kp_theta =80; Ki_theta =0; Kd_theta = 0.5;
% Setpoints (target values)
setpoint_x = -0.1;
setpoint_y = -5.5;
setpoint_phi = 0.00;
setpoint_theta = 0.00;
previous_errorx = 0;
integral_errorx=0
derivative_errorx = 0
previous_errory = 0;
integral_errory=0
derivative_errory = 0
previous_errorphi = 0;
integral_errorphi=0
derivative_errorphi = 0
previous_errortheta = 0;
integral_errortheta=0
derivative_errortheta = 0
prev_filtest = 0;
filte_est =0;
prev_filtesty = 0;
filte_esty =0;
prev_filtestp = 0;
filte_estp =0;
prev_filtestth = 0;
filte_estth =0;
o = 0.05;
K_xp = 4/100;
K_yp= 4.8/100;
K_xr = 0.63/100;
K_yr = 3.05/100;
error_x= setpoint_x – xof1;
integral_errorx = integral_errorx + error_x * Ts;
derivative_errorx = (error_x – previous_errorx);
filte_est = (o*prev_filtest)+(1-o)*derivative_errorx
derivative = filte_est/Ts;
prev_filtest = filte_est;
control_signalx = Kp_x * error_x + Ki_x * integral_errorx + Kd_x * derivative;
previous_errorx = error_x;
% Cross-coupling effect on phi due to x_error
theta_coupling_effect = K_xr * error_x;
error_y= setpoint_y – yof1;
integral_errory = integral_errory + error_y * Ts;
derivative_errory = (error_y – previous_errory)
filte_esty = (o*prev_filtesty)+(1-o)*derivative_errory
derivativey = filte_esty/Ts;
prev_filtesty = filte_esty;
control_signaly = Kp_y * error_y + Ki_y * integral_errory + Kd_y * derivativey;
previous_errory = error_y;
% Cross-coupling effect on theta due to y_error
phi_coupling_effect = K_yp * error_y;
% Step 5: Compute final tilt angles
theta_desired =(K_yr * error_y) + phi_coupling_effect; % Roll (tilt about X-axis)
phi_desired = (K_xp * error_x) + theta_coupling_effect; % Pitch (tilt about Y-axis)
error_phi= phi_desired – Phi;
integral_errorphi = integral_errorphi + error_phi * Ts;
derivative_errorphi = (error_phi – previous_errorphi)
filte_estp = (o*prev_filtestp)+(1-o)*derivative_errorphi
derivativep = filte_estp/Ts;
prev_filtestp = filte_estp;
control_signalphi = Kp_phi * error_phi + Ki_phi * integral_errorphi + Kd_phi * derivativep;
previous_errorphi = error_phi;
Phi1 = (Phi + control_signalphi * Ts); % Update tilt
Phi1 = max(-0.6, min(Phi1, 0.6));
pidTuner(Phi1)
error_theta= theta_desired – Theta;
integral_errortheta = integral_errortheta + error_theta * Ts;
derivative_errortheta = (error_theta – previous_errortheta)
filte_estth = (o*prev_filtestth)+(1-o)*derivative_errortheta;
derivativeth = filte_estth/Ts;
prev_filtestth = filte_estth;
control_signaltheta = Kp_theta * error_theta + Ki_theta * integral_errortheta + Kd_theta * derivativeth;
previous_errortheta = error_theta;
Theta1 = (Theta + control_signaltheta * Ts); % Update tilt
Theta1 = max(-0.6, min(Theta1, 0.6));
xof1 = xof1+(control_signalx*Ts);
yof1 = yof1+(control_signaly*Ts)
disp(‘done here 3’)
xo= 82*sin(Phi);
yo =-82*sin(Theta);
[a11f,a22f,a33f] = inversekin(xof1,yof1,Phi1,Theta1,Zp,alpha)
% [a11f,a22f,a33f] = inversekin(xof1,yof1,phi_control,theta_control,Zp,gamma)
a11 = a11f;
a22 = a22f;
a33 = a33f;
disp(‘done here 4’)
% Clamp the angles to the range 40° to 50°
a11 = max(42, min(a11, 48));
a22 = max(42, min(a22, 48));
a33 = max(42, min(a33, 48));
currentTime = datestr(now, ‘HH:MM:SS.FFF’); % Get current time
fprintf(logFile, ‘%s,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%.4f,%.4f,%.4fn’, …
currentTime, dist_1, dist_2, dist_3, Phi, Theta, xof1, yof1,a11, a22, a33);
% fprintf(stateLogFile, ‘%.3f,%.3f,%.3f,%.3f,%.3f,%.3f,%.3fn’, Ts, Phi, Theta, xof1, yof1, Zp, gamma);
%% Servo Motor Code
% Clamp the angles to the range 40° to 50°
a = normalize(a11);
b = normalize(a22);
c = normalize(a33);
writePosition(servo_motor,a)
writePosition(servo_motor1,b)
writePosition(servo_motor2,c)
stop_it = toc(start);
A = a11;
B = a22;
C= a33;
stop = toc(start)
disp(‘done here 5’);
if (xof1 <=0.5 && xof1>=-0.5)&&(yof1 <= 1.5 &&yof1>=-1.5)
% if (xof1==0 && yof1==0)
disp(‘im done’)
writePosition(servo_motor,0.3300)
writePosition(servo_motor1,0.3300)
writePosition(servo_motor2,0.3300)
break;
else
disp(‘continued’)
h = h+1
end
end
% Clean up
fclose(logFile); % Close the log file
clear arduino_board servo_motor servo_motor1 servo_motor2 s
clear cap;
release(blobAnalyzer);
close(hFig); % Close the figure when done
disp(‘System is Stable’);
function norm_position = normalize(angle_deg)
angle_deg = angle_deg/1.5;
angle_deg = 90 – angle_deg;
angle_deg = angle_deg – (angle_deg/100);
norm_position = angle_deg/180;
end control, image processing MATLAB Answers — New Questions
How can I express a set of nonlinear differential equations in the form 𝑥 ˙ = 𝐴 ( 𝑥 ) ⋅ 𝑥 + 𝐵 using MATLAB code ?
dXdt = @(X) [
2*(x(1) + 0.005)^2 + 3*(x(1) + 0.005)*(x(2) + 0.003);
2*(x(1) + 0.005) + 4*(x(2) + 0.003)^2;
(x(1) + 0.005)^3 + (x(2) + 0.003)*(x(3) + 0.05);
2*(x(3) + 0.005) + (x(4) + 0.025)^2;
(x(1) + 0.005)*(x(5) + 0.0236) + (x(2) + 0.003) + (x(4) + 0.0125)
];
Given a set of nonlinear differential equations for dxdt , how can I express the system in the form x_dot = A(X)*X+B using MATLAB code?
X=[x(1), x(2)….x(5)] is the statesdXdt = @(X) [
2*(x(1) + 0.005)^2 + 3*(x(1) + 0.005)*(x(2) + 0.003);
2*(x(1) + 0.005) + 4*(x(2) + 0.003)^2;
(x(1) + 0.005)^3 + (x(2) + 0.003)*(x(3) + 0.05);
2*(x(3) + 0.005) + (x(4) + 0.025)^2;
(x(1) + 0.005)*(x(5) + 0.0236) + (x(2) + 0.003) + (x(4) + 0.0125)
];
Given a set of nonlinear differential equations for dxdt , how can I express the system in the form x_dot = A(X)*X+B using MATLAB code?
X=[x(1), x(2)….x(5)] is the states dXdt = @(X) [
2*(x(1) + 0.005)^2 + 3*(x(1) + 0.005)*(x(2) + 0.003);
2*(x(1) + 0.005) + 4*(x(2) + 0.003)^2;
(x(1) + 0.005)^3 + (x(2) + 0.003)*(x(3) + 0.05);
2*(x(3) + 0.005) + (x(4) + 0.025)^2;
(x(1) + 0.005)*(x(5) + 0.0236) + (x(2) + 0.003) + (x(4) + 0.0125)
];
Given a set of nonlinear differential equations for dxdt , how can I express the system in the form x_dot = A(X)*X+B using MATLAB code?
X=[x(1), x(2)….x(5)] is the states nonlinear MATLAB Answers — New Questions
probability- punctual graphs
starting from values of intensity and direction of the wind, I created the graphs relating to the probability of obtaining certain values of intensity and direction of the wind at the same time. I used the bar3 function which creates my instigrams in 3d. is there a function that allows me to calculate the same probability but with a punctual graph? that the numerical values are given back to me.starting from values of intensity and direction of the wind, I created the graphs relating to the probability of obtaining certain values of intensity and direction of the wind at the same time. I used the bar3 function which creates my instigrams in 3d. is there a function that allows me to calculate the same probability but with a punctual graph? that the numerical values are given back to me. starting from values of intensity and direction of the wind, I created the graphs relating to the probability of obtaining certain values of intensity and direction of the wind at the same time. I used the bar3 function which creates my instigrams in 3d. is there a function that allows me to calculate the same probability but with a punctual graph? that the numerical values are given back to me. probability, graph, intensity, velocity MATLAB Answers — New Questions
Animation of a volume
I have a volume (1040x1392x41 double) and I would like to create an animation that visualizes this volume. A simple one would be one visualizes the volume in the z-direction (going from 1 to 41) and back up again, without the need for user interference.I have a volume (1040x1392x41 double) and I would like to create an animation that visualizes this volume. A simple one would be one visualizes the volume in the z-direction (going from 1 to 41) and back up again, without the need for user interference. I have a volume (1040x1392x41 double) and I would like to create an animation that visualizes this volume. A simple one would be one visualizes the volume in the z-direction (going from 1 to 41) and back up again, without the need for user interference. animation MATLAB Answers — New Questions
New PAYG Service to Classify Historical SharePoint Data
On Demand Classification Processes Cold Files to Find Sensitive or Confidential Information
Message center notification MC1013459 (21 February 2025) announces that Microsoft will introduce a new Information Protection service to find and classify “historical data in SharePoint Online and OneDrive for Business,” or as Microsoft 365 roadmap item 475062 says “scan cold files.”
The idea seems to be that tenants might have a bunch of files in SharePoint and OneDrive that have never been scanned or not been scanned in some time. Purview solutions like Data Loss Prevention (DLP) and Information Protection (sensitivity labels) tend to operate against active files created and edited by users. Cold files gather the digital equivalent of dust and might never be accessed, and it’s possible that those files contain many types of sensitive data.
Closing the gap by finding and classifying the information discovered in “cold files” is what the new On Demand Classification service is all about. By processing historical data, an organization can make sure that the files present in the tenant are classified appropriately. Once classified, policies can be automatically invoked to apply actions like assigning sensitivity or retention labels to files.
Preview of On Demand Classification in March 2025
Perhaps because trainable classifiers are an important method for tenants to find information that’s specific to their business, On Demand Classification is available through the classifiers section of the Purview DLP solution.
Microsoft expects to begin the deployment of a preview version of the code to targeted release tenants in late March 2025 with the goal of attaining general availability in mid-June 2025. Dates have been known to slip in the past, especially with new services, so treat these dates with caution.
Pay As You Go On Demand Classification
The On Demand Classification service is an example of the kind of new functionality that Microsoft bundles into its Office 365 E5 and Microsoft 365 E5 products to tempt customers to upgrade. That’s not the situation in this case. On Demand Classification is the first Purview Pay-as-you-go (PAYG) service.
PAYG is not unknown in Microsoft 365. SharePoint Online has PAYG services like Microsoft 365 Backup, Microsoft 365 Archive, and Document Translation, all of which require customers to have an Azure subscription attached to a valid credit card to pay for metered resource consumption. Other examples include the Graph API to apply sensitivity labels programmatically to Office documents and PDF files in SharePoint Online and OneDrive for Business and the export APIs for Teams and Exchange Online.
The case can be made that all the PAYG offerings are optional and not mainline services. They fill niches that not every Microsoft 365 customer wants or needs. It would be possible to include these services in the Microsoft 365 E5 product, but likely at an increased cost for everyone. Overall, it seems fairer for Microsoft to do the software engineering to create the solutions and realize a return by selling metered services to customers that need these capabilities.
No Details about Service Limitations
Microsoft hasn’t released any details about potential service limitations like the 100,000 items per day maximum an auto-label policy (sensitivity labels) can process within a tenant. We don’t know what kind of cold file types can be processed or if specific policy-invoked actions are restricted to certain types. The screenshot released by Microsoft (Figure 1) doesn’t give any insight into how long a scan might take or how long the subsequent processing might require.

All will be revealed when we get the software to test sometime in March 2025. Of course, some historic data must be found for On Demand Classification to process, but I’m sure that I have some old articles or book files hanging around that deserve to be heated up.
So much change, all the time. It’s a challenge to stay abreast of all the updates Microsoft makes across the Microsoft 365 ecosystem. Subscribe to the Office 365 for IT Pros eBook to receive monthly insights into what happens, why it happens, and what new features and capabilities mean for your tenant.
How to search a table inside a cell
I have been given a workspace that has a cell variable that is 1×10 inside each cell is a table that is 100×16. Each column in each table has the same var names (time, rpm, temp, p1, p2, etc…).
I want to search the table in data(1,1) to find the first time what the temp is 300, but cannot figure out how.I have been given a workspace that has a cell variable that is 1×10 inside each cell is a table that is 100×16. Each column in each table has the same var names (time, rpm, temp, p1, p2, etc…).
I want to search the table in data(1,1) to find the first time what the temp is 300, but cannot figure out how. I have been given a workspace that has a cell variable that is 1×10 inside each cell is a table that is 100×16. Each column in each table has the same var names (time, rpm, temp, p1, p2, etc…).
I want to search the table in data(1,1) to find the first time what the temp is 300, but cannot figure out how. table, cell MATLAB Answers — New Questions
Arduino NanoRP2040 Connect to Matlab via bluetooth
I’m consistently getting an error when trying to connect the Arduino Board RP2040 to Matlab via bluetooth, i needed to plot some images from sensor data, using matlab, but withouth the connection being allowed, i can’t plot or see any interation between Arduino and Matlab, any solutions?
when using the code:
btlist = blelist; disp(btlist);
The board does appear in the BLE list, however, when:
device = ble("NanoRP2040");
The interactions does start, but stops almost imediatly, showing the error:
"Error using ble (line 149)
Failed to connect to device. Make sure device is within proper range and not connected elsewhere. For more
information, see Troubleshooting section in Documentation."
Any suggestions?!I’m consistently getting an error when trying to connect the Arduino Board RP2040 to Matlab via bluetooth, i needed to plot some images from sensor data, using matlab, but withouth the connection being allowed, i can’t plot or see any interation between Arduino and Matlab, any solutions?
when using the code:
btlist = blelist; disp(btlist);
The board does appear in the BLE list, however, when:
device = ble("NanoRP2040");
The interactions does start, but stops almost imediatly, showing the error:
"Error using ble (line 149)
Failed to connect to device. Make sure device is within proper range and not connected elsewhere. For more
information, see Troubleshooting section in Documentation."
Any suggestions?! I’m consistently getting an error when trying to connect the Arduino Board RP2040 to Matlab via bluetooth, i needed to plot some images from sensor data, using matlab, but withouth the connection being allowed, i can’t plot or see any interation between Arduino and Matlab, any solutions?
when using the code:
btlist = blelist; disp(btlist);
The board does appear in the BLE list, however, when:
device = ble("NanoRP2040");
The interactions does start, but stops almost imediatly, showing the error:
"Error using ble (line 149)
Failed to connect to device. Make sure device is within proper range and not connected elsewhere. For more
information, see Troubleshooting section in Documentation."
Any suggestions?! arduino, bluetooth, matlab MATLAB Answers — New Questions
How to run a MATLAB file without opening the MATLAB GUI?
Hello,
I am trying to test a batch file that runs matlab with an input file
the batch file is one line:
"C:Program FilesMATLABR2024bbinmatlab.exe" -noFigureWindows -minimize -nosplash -r "c:tmptesttest_matlab_no_GUI_batch.m"
the MATLAB file is:
a=6;
b=7;
c=a+b;
dlmwrite(‘c:tmptestHFSS_Batchtest_matlab_no_gui.txt’,c)
I would expect to see the "test_matlab_no_gui.txt" file in "c:tmptest" folder.
I am not. what am I missing?
Thank youHello,
I am trying to test a batch file that runs matlab with an input file
the batch file is one line:
"C:Program FilesMATLABR2024bbinmatlab.exe" -noFigureWindows -minimize -nosplash -r "c:tmptesttest_matlab_no_GUI_batch.m"
the MATLAB file is:
a=6;
b=7;
c=a+b;
dlmwrite(‘c:tmptestHFSS_Batchtest_matlab_no_gui.txt’,c)
I would expect to see the "test_matlab_no_gui.txt" file in "c:tmptest" folder.
I am not. what am I missing?
Thank you Hello,
I am trying to test a batch file that runs matlab with an input file
the batch file is one line:
"C:Program FilesMATLABR2024bbinmatlab.exe" -noFigureWindows -minimize -nosplash -r "c:tmptesttest_matlab_no_GUI_batch.m"
the MATLAB file is:
a=6;
b=7;
c=a+b;
dlmwrite(‘c:tmptestHFSS_Batchtest_matlab_no_gui.txt’,c)
I would expect to see the "test_matlab_no_gui.txt" file in "c:tmptest" folder.
I am not. what am I missing?
Thank you gui, matlab gui, batch MATLAB Answers — New Questions
how to plot a certain level in a contour?
I ‘m using contour option in Matlab R2014a to plot many curves: contour(x,y,c,cilevels); with cilevels = [0.0,.005,0.019];
but I need to select one curve (level) from the contour: the option peaks is not working? and I have tried : contour(x,y,c,[1 1]); but it was error also?
could you please help me?I ‘m using contour option in Matlab R2014a to plot many curves: contour(x,y,c,cilevels); with cilevels = [0.0,.005,0.019];
but I need to select one curve (level) from the contour: the option peaks is not working? and I have tried : contour(x,y,c,[1 1]); but it was error also?
could you please help me? I ‘m using contour option in Matlab R2014a to plot many curves: contour(x,y,c,cilevels); with cilevels = [0.0,.005,0.019];
but I need to select one curve (level) from the contour: the option peaks is not working? and I have tried : contour(x,y,c,[1 1]); but it was error also?
could you please help me? contour, single level MATLAB Answers — New Questions
Using fft and ifft with less frequencies than input points
I want to use fft and ifft in the context of heat equation. Therefore the grid needs to be refined, but I dont want to use as many coefficients in the fft:
%Grid
Nx = 10001;
dx = L/(Nx-1);
x = linspace(0,L,Nx)’;
%Function
f = @(x) rectangularPulse(0.5, 1.5, x);
f_values = arrayfun(f,x);
u0 = ifft(fft(f_values)); %Takes very long
What I would want to do, is to insert an N, f.e. N=100, but get an array 10001×1.
Thanks.I want to use fft and ifft in the context of heat equation. Therefore the grid needs to be refined, but I dont want to use as many coefficients in the fft:
%Grid
Nx = 10001;
dx = L/(Nx-1);
x = linspace(0,L,Nx)’;
%Function
f = @(x) rectangularPulse(0.5, 1.5, x);
f_values = arrayfun(f,x);
u0 = ifft(fft(f_values)); %Takes very long
What I would want to do, is to insert an N, f.e. N=100, but get an array 10001×1.
Thanks. I want to use fft and ifft in the context of heat equation. Therefore the grid needs to be refined, but I dont want to use as many coefficients in the fft:
%Grid
Nx = 10001;
dx = L/(Nx-1);
x = linspace(0,L,Nx)’;
%Function
f = @(x) rectangularPulse(0.5, 1.5, x);
f_values = arrayfun(f,x);
u0 = ifft(fft(f_values)); %Takes very long
What I would want to do, is to insert an N, f.e. N=100, but get an array 10001×1.
Thanks. fft, ode MATLAB Answers — New Questions
SharePoint Online Adds Support for Sensitivity Labels with User Defined Permissions
Opens Access to UDP-Protected Files to Search, eDiscovery, and DLP – but not Copilot
Originally announced in preview in an August 1, 2023 technical community post, message center notification MC1013467 (21 February 2025) contains the good news that SharePoint Online will deploy support for sensitivity labels with user-defined permissions (UDP) in mid-March 2025. The reason why this development is important is that SharePoint Online support for UDP enables support for these files in content searches, Purview eDiscovery, and Purview Data Loss Prevention (DLP).
Configuring Permissions for Sensitivity Labels
Most sensitivity labels that protect files with rights-management based encryption use permissions configured by administrators. Permissions are formed by a set of usage rights that dictate what level of access an authenticated user has to a file. The same permissions apply to all files that receive a label with preconfigured access.
User-defined permissions allow file owners to assign different permissions for different files. To allow this to happen, administrators must configure a sensitivity label to support UDP (Figure 1).

After the label is published to make it available to users, they can assign the label and configure permissions for files (Figure 2). UDP labels are visible in Office web applications but can only be set by Office desktop applications.

Clicking more options reveals additional controls for a user to assign to protect a file, including an expiration date (which doesn’t pick up the date format configured for the workstation) for the permissions, a contact email address to request additional permissions, and whether a user must be online to validate their permission before they can open a file. The last option, to access content programmatically, allows Word and Excel to run code within a protected document.

Support for Microsoft Search
The initial SharePoint support for UDP-protected files previewed in August 2023 was limited. The big issue remained that files with UDP labels stored in SharePoint Online or OneDrive for Business couldn’t be indexed by Microsoft Search because Search had no way to gain access to file content (metadata for UDP-protected files is always indexed). This is important because Microsoft Search is an essential component for other services such as eDiscovery. In a nutshell, no indexing meant that UDP-protected files were invisible outside SharePoint Online.
The news announced in MC1013467 addresses the problem, but in a very focused manner. Although the number of UDP-protected files stored in SharePoint Online is likely a very small percentage of the billions of new files created daily, there’s no way that a trawl across all sites to find and process UDP-protected files could work in a practical sense.
To solve the problem, SharePoint Online processes newly-created UDP-protected files from mid-March 2025 to make their content accessible to Microsoft Search. Once indexed by Search, the file content is available to other Microsoft 365 workloads like eDiscovery. During the indexing process, SharePoint interprets the permissions assigned to a file by the author to ensure that those with relevant permissions can engage in co-authoring. In addition, SharePoint Online and the Office apps need permission to access the file before the autosave feature can work. It takes a little time to process a new file after it is uploaded to SharePoint Online. Microsoft reckons on ten minutes, but I have experienced longer delays before features like autosave work.
Older files stored in sites remain inaccessible to SharePoint Online until the next time they are edited. At this point, SharePoint processes the file content to make it searchable. Over time, the idea is that the number of inaccessible UDP-protected files will gradually decrease, and the problem will go away. Once a file is processed by Search, it becomes available to content searches, eDiscovery, and DLP.
Even when UDP-protected files are processed by Microsoft Search, MC1013467 says that “files with labels configured for user-defined permissions will continue to not be available for Microsoft 365 Copilot processing.” In other words, although Search can find UDP-protected files, Copilot still does not have the necessary permissions to load content from those files to use when generating responses to user prompts.
No Big Change for Users in the Immediate Future
From a user perspective, the update for how SharePoint Online processes UDP-protected files won’t mean dramatic change in the immediate future. UDP sensitivity labels might become more popular and widespread, but that’s a process that needs time because it must be factored in the organization’s information protection policy, which is probably currently based on preconfigured permissions. Administrators will need time to absorb the news and figure out how and if UDP-protected files bring value to the business before they create and publish UPD labels.
Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.
Top Cloud Native Threats and Vulnerabilities of 2024
The complexity of cloud environments means that there is a virtually infinite list of potential security risks and vulnerabilities that could arise within cloud infrastructure or workloads. That said, some cloud security threats are more prevalent than others – and knowing which risks and vulnerabilities are trending is key to knowing what to prioritize when managing the attack surface for your organization. To that end, this article details seven of the most prominent cloud threats and vulnerabilities that emerged in 2024, including several discovered by Aqua researchers.
The complexity of cloud environments means that there is a virtually infinite list of potential security risks and vulnerabilities that could arise within cloud infrastructure or workloads. That said, some cloud security threats are more prevalent than others – and knowing which risks and vulnerabilities are trending is key to knowing what to prioritize when managing the attack surface for your organization. To that end, this article details seven of the most prominent cloud threats and vulnerabilities that emerged in 2024, including several discovered by Aqua researchers.
Read More
4×4 membrane switch set up
I’m trying to wire a 4×4 membrane switch to be able to input a string of numbers. The problem is A.) don’t have a lot of experience in matlab, and B.) all of the code libraries and stuff I’ve found for the switch is all based in the arduino software. Does anyone have any idea on how I can transfer it over or write my own?
here is a example of the arduino library:
#include “Keypad.h”
const byte ROWS = 4; // number of rows
const byte COLS = 3; // number of columns
char keys[ROWS][COLS] = {
{‘1′,’2′,’3’},
{‘4′,’5′,’6’},
{‘7′,’8′,’9’},
{‘#’,’0′,’*’}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {4, 3, 2}; // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
Serial.begin(9600);
}
void loop()
{
char key = keypad.getKey();
if (key ~= NO_KEY)
Serial.println(key);
}I’m trying to wire a 4×4 membrane switch to be able to input a string of numbers. The problem is A.) don’t have a lot of experience in matlab, and B.) all of the code libraries and stuff I’ve found for the switch is all based in the arduino software. Does anyone have any idea on how I can transfer it over or write my own?
here is a example of the arduino library:
#include “Keypad.h”
const byte ROWS = 4; // number of rows
const byte COLS = 3; // number of columns
char keys[ROWS][COLS] = {
{‘1′,’2′,’3’},
{‘4′,’5′,’6’},
{‘7′,’8′,’9’},
{‘#’,’0′,’*’}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {4, 3, 2}; // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
Serial.begin(9600);
}
void loop()
{
char key = keypad.getKey();
if (key ~= NO_KEY)
Serial.println(key);
} I’m trying to wire a 4×4 membrane switch to be able to input a string of numbers. The problem is A.) don’t have a lot of experience in matlab, and B.) all of the code libraries and stuff I’ve found for the switch is all based in the arduino software. Does anyone have any idea on how I can transfer it over or write my own?
here is a example of the arduino library:
#include “Keypad.h”
const byte ROWS = 4; // number of rows
const byte COLS = 3; // number of columns
char keys[ROWS][COLS] = {
{‘1′,’2′,’3’},
{‘4′,’5′,’6’},
{‘7′,’8′,’9’},
{‘#’,’0′,’*’}
};
byte rowPins[ROWS] = {8, 7, 6, 5}; // row pinouts of the keypad R1 = D8, R2 = D7, R3 = D6, R4 = D5
byte colPins[COLS] = {4, 3, 2}; // column pinouts of the keypad C1 = D4, C2 = D3, C3 = D2
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup()
{
Serial.begin(9600);
}
void loop()
{
char key = keypad.getKey();
if (key ~= NO_KEY)
Serial.println(key);
} keypad, membrane, button MATLAB Answers — New Questions
Wind rose with no degrees for direction
I am trying to plot a wind rose but for direction I only have N, NE, NNE etc rather than degrees. Is there a code or script for this?I am trying to plot a wind rose but for direction I only have N, NE, NNE etc rather than degrees. Is there a code or script for this? I am trying to plot a wind rose but for direction I only have N, NE, NNE etc rather than degrees. Is there a code or script for this? windrose MATLAB Answers — New Questions
Why do I write as Ib(1:478,31:565)(~BW) = 255
Ib(1:478,31:565)(~BW) = 255
Ib is a gray image. I want to set a fixed black region as blue, but this code is wrong.
Do we have simple method to finish it?Ib(1:478,31:565)(~BW) = 255
Ib is a gray image. I want to set a fixed black region as blue, but this code is wrong.
Do we have simple method to finish it? Ib(1:478,31:565)(~BW) = 255
Ib is a gray image. I want to set a fixed black region as blue, but this code is wrong.
Do we have simple method to finish it? matlab code MATLAB Answers — New Questions
way to legend a data organized into colours in simple plot?
first_data = [[3 4 8 1];[3 6 4 9]]; % desired legend (first) & color (green)
second_data = [[1 3 5];[3 2 7];[3 4 2]]; % desired legend (second) & color (cyan)
combine = {first_data,second_data}; % recieving new data in every ‘for’ loop iteration thats why combining
colours = {‘g’,’c’};
Legend_Names = {‘first’,’second’};
for i = 1:length(combine)
plot(cell2mat(combine(i)),’Color’,cell2mat(colours(i)),’LineWidth’,2); grid on; hold on;
end
legend(Legend_Names)
i wish to plot my each data set with same colour… in this case legend ”Second” should have ”cyan” colourfirst_data = [[3 4 8 1];[3 6 4 9]]; % desired legend (first) & color (green)
second_data = [[1 3 5];[3 2 7];[3 4 2]]; % desired legend (second) & color (cyan)
combine = {first_data,second_data}; % recieving new data in every ‘for’ loop iteration thats why combining
colours = {‘g’,’c’};
Legend_Names = {‘first’,’second’};
for i = 1:length(combine)
plot(cell2mat(combine(i)),’Color’,cell2mat(colours(i)),’LineWidth’,2); grid on; hold on;
end
legend(Legend_Names)
i wish to plot my each data set with same colour… in this case legend ”Second” should have ”cyan” colour first_data = [[3 4 8 1];[3 6 4 9]]; % desired legend (first) & color (green)
second_data = [[1 3 5];[3 2 7];[3 4 2]]; % desired legend (second) & color (cyan)
combine = {first_data,second_data}; % recieving new data in every ‘for’ loop iteration thats why combining
colours = {‘g’,’c’};
Legend_Names = {‘first’,’second’};
for i = 1:length(combine)
plot(cell2mat(combine(i)),’Color’,cell2mat(colours(i)),’LineWidth’,2); grid on; hold on;
end
legend(Legend_Names)
i wish to plot my each data set with same colour… in this case legend ”Second” should have ”cyan” colour plot, legend MATLAB Answers — New Questions
fixedpoint library linking issue with slbuild
I have a model with S-function which uses ssRegisterDataTypeFxpBinaryPoint for uint64, but I am getting error when try to create an executable with slbuild for my model.
It looks like linking error, how to link fixedpoint library when I create an executable of my model with slbuild.I have a model with S-function which uses ssRegisterDataTypeFxpBinaryPoint for uint64, but I am getting error when try to create an executable with slbuild for my model.
It looks like linking error, how to link fixedpoint library when I create an executable of my model with slbuild. I have a model with S-function which uses ssRegisterDataTypeFxpBinaryPoint for uint64, but I am getting error when try to create an executable with slbuild for my model.
It looks like linking error, how to link fixedpoint library when I create an executable of my model with slbuild. uint64, slbuild, simulink, lfixedpoint MATLAB Answers — New Questions
Microsoft Removes Reactivation Fee for Archived SharePoint Sites
No Microsoft 365 Archive Fee to Reactivate Sites After March 31, 2025
In a February 20, 2025 announcement, Microsoft said that they will remove reactivation fees for archived SharePoint Online sites. Some tenants will see the reduction in fees in early March and the change will roll out gradually worldwide for completion by the end of March 2025.
When Microsoft launched Microsoft 365 Archive, they charged $0.60 per GB to reactivate a site by moving its content from “cold” (long-term, archived) storage to “hot” (online, immediately-accessible) storage. Reactivation is immediate for sites archived within the last week, while sites archived for longer take approximately 24 hours to come back online.
Following the removal of the site reactivation fee, Microsoft will only charge the ongoing monthly storage cost of $0.05/GB. Storage fees don’t apply when they can be offset against the tenant’s unused SharePoint Online storage quota, so depending on how many sites they archive and how much content exists in those sites, some organizations might be able to use Microsoft 365 Archive for free.
A restriction does apply in that reactivated sites cannot be moved back into the archive for four months after reactivation. Microsoft says that the restriction is there to stop constant movement in and out of archive storage.
Keep Material Online but Prevent Copilot Access
One of the nice things about archiving sites is that it makes site content inaccessible for Microsoft 365 Copilot. There’s nothing worse than having AI-generated results being polluted by old, obsolete, and probably misleading information, and even if steps are taken to stop Copilot using content in its responses, Copilot can still find and use document library metadata because it exists in Microsoft Search.
I can’t think of a downside to moving old sites into the archive if you want to keep the material stored in the sites. Archived sites are still accessible for eDiscovery, the storage costs are a lot lower than hot online SharePoint storage, and now you can reactivate archived sites free when necessary.
Archived OneDrive Accounts
But you won’t be able to reactivate archived OneDrive for Business accounts free of charge because Microsoft excludes these objects from the removal of reactivation fees. The big idea behind automatically archiving unlicensed OneDrive for Business accounts is to force organizations to do something with accounts that might have been around for ten years or more. The unlicensed OneDrive accounts occupy valuable online storage and because Microsoft encourages the use of OneDrive for Business to hold all manner of files from Teams meeting recordings to PowerShell modules, a significant amount of storage can be occupied.
Microsoft released a report to help tenant administrators decide how to deal with unlicensed OneDrive for Business accounts in August 2024. By now, administrators should have a good handle on the unlicensed accounts within the tenant and know whether they will let automatic archiving happen (and be willing to pay the ongoing storage fees) or take action to remove the unlicensed accounts.
According to recently-revised Microsoft documentation, unlicensed accounts fall into two categories: those unlicensed before February 17, 2025, and those unlicensed afterward. The first batch includes all the historically unlicensed accounts. By April 25, 2025, these accounts will be in read-only mode to prepare them to move into the archive. This process will happen in the background and the unlicensed accounts will be archived by May 16, 2025, including the set shown in Figure 1. Once archived, tenants must pay to reactivate unlicensed OneDrive for Business accounts.

OneDrive for Business accounts that become unlicensed now are placed into read-only mode sixty days after they become unlicensed (for instance, the owning user account is deleted but the OneDrive data is kept by a retention policy, or the user account loses its license to allow them to use OneDrive for Business).
Thirty-three days afterward (93 days after the removal of the license), SharePoint Online will either move to the OneDrive account into the archive or into the recycle bin. Movement into the archive happens when a retention policy applies to the owner’s account.
Lower Fees are Always Appreciated
It’s good that Microsoft has removed the site reactivation fee. While not a lot in the overall scheme of things, getting rid of fees always encourage more use of facilities, and using Microsoft 365 Archive to store old material that the organization cannot remove is a good tactic. Some might question why the same logic doesn’t apply to archived OneDrive for Business accounts. That’s for Microsoft to answer, but I bet that they just want to get people used to the idea of paying to keep old OneDrive content online before they move on charges.
Insight like this doesn’t come easily. You’ve got to know the technology and understand how to look behind the scenes. Benefit from the knowledge and experience of the Office 365 for IT Pros team by subscribing to the best eBook covering Office 365 and the wider Microsoft 365 ecosystem.