Arduino code
#include <Servo.h>
#define IR_MOTION_PIN 8 // digital “motion” IR (0 when object present, 1 otherwise)
#define IR_DISTANCE_PIN A3 // analog “distance” IR (0–1023)
#define MQ7_PIN A4 // analog MQ-7 (0–~>1023)
#define SERVO_PIN 2 // PWM pin for servo
Servo doorServo;
void setup() {
Serial.begin(115200);
// Give MATLAB a second to connect
delay(1000);
pinMode(IR_MOTION_PIN, INPUT);
// analog pins A3/A4 work automatically with analogRead
doorServo.attach(SERVO_PIN);
doorServo.write(0);
Serial.println("Arduino Ready");
void loop() {
// --- 1) Read all three sensors ---
int motionRaw = digitalRead(IR_MOTION_PIN); // 0=object, 1=no object
int distanceRaw = analogRead(IR_DISTANCE_PIN); // 0..1023
int gasRaw = analogRead(MQ7_PIN); // 0..(spikes >1023 possible)
// Clamp gas into [0..1023] so MATLAB side never sees out‐of‐range
int gasClamped = constrain(gasRaw, 0, 1023);
// --- 2) Print them in a single line “motion,distance,gas” ---
// MATLAB will read this line via serial, parse by commas
Serial.print(motionRaw);
Serial.print(',');
Serial.print(distanceRaw);
Serial.print(',');
Serial.println(gasClamped);
// --- 3) Check if MATLAB has sent back a servo angle yet ---
// We expect MATLAB to send a single integer (0..90)
if (Serial.available() > 0) {
String angleString = Serial.readStringUntil('\n');
int angle = angleString.toInt();
if (angle < 0) angle = 0;
if (angle > 90) angle = 90;
doorServo.write(angle);
// Optionally print back confirmation
Serial.print("→Servo:");
Serial.println(angle);
delay(200); // adjust loop rate as desired (e.g. 5 Hz = 200 ms)
MATLAB code
clearvars
clc
%% 1) Specify your COM port & baud
portName = "COM4";
baudRate = 115200;
% 2) Open serial port
try
s = serialport(portName, baudRate);
configureTerminator(s, "LF");
flush(s);
fprintf("Opened serial port %s @ %d baud.\n\n", portName, baudRate);
catch ME
error("Failed to open %s at %d baud:\n%s", portName, baudRate,
ME.message);
end
%% 3) Load your FIS
fisFilename = 'myDoorFIS.fis';
if exist(fisFilename, 'file') ~= 2
error('Cannot find FIS file "%s" in this folder.', fisFilename);
end
% Try reading as FIS 1.0 first
try
fis = readfis(fisFilename);
catch
% If that fails, try reading as FIS 2.0
fis = readfis(fisFilename, 'FileType', 'fisx');
end
fprintf("Loaded FIS from “%s”.\n\n", fisFilename);
%% 3.5) Plot Membership Functions Before Starting Serial Loop
% Plot Inputs
numInputs = length(fis.Inputs);
figure('Name', 'Input Membership Functions');
for i = 1:numInputs
subplot(1, numInputs, i);
plotmf(fis, 'input', i);
title(['Input ', num2str(i), ': ', fis.Inputs(i).Name], 'FontWeight', 'bold');
xlabel('Input Value');
ylabel('Degree of Membership');
grid on;
end
% Plot Outputs
numOutputs = length(fis.Outputs);
figure('Name', 'Output Membership Functions');
for i = 1:numOutputs
subplot(1, numOutputs, i);
plotmf(fis, 'output', i);
title(['Output ', num2str(i), ': ', fis.Outputs(i).Name], 'FontWeight', 'bold');
xlabel('Output Value');
ylabel('Degree of Membership');
grid on;
end
%% 4) Main loop: read, eval, send
fprintf("Entering main control loop. Press Ctrl+C to stop.\n\n");
while true
try
% Read one line from Arduino (e.g., "0,200,160")
line = readline(s);
catch
warning("Serial read timed out; retrying...");
pause(0.1);
continue;
end
% Parse the CSV input
tokens = split(strtrim(line), ',');
if numel(tokens) ~= 3
continue; % malformed line
end
motionVal = str2double(tokens{1});
distanceVal = str2double(tokens{2});
gasVal = str2double(tokens{3});
if isnan(motionVal) || isnan(distanceVal) || isnan(gasVal)
continue;
end
% 5) Evaluate FIS
inputVec = [motionVal, distanceVal, gasVal];
angleCrisp = evalfis(fis, inputVec);
angleCmd = round(max(min(angleCrisp, 90), 0)); % Clamp to [0..90]
% 6) Send angle back to Arduino
writeline(s, string(angleCmd));
% 7) Debug info
fprintf("Raw→ m=%d d=%d g=%d → angle=%d°\n", ...
motionVal, distanceVal, gasVal, angleCmd);
pause(0.05); % slight delay for stability
end
% clear s; % <-- Use if breaking with Ctrl+C to close serial port
Fuzzy logic designer
OUTPUTS
Arduino output
Matlab output