function [touchState, filteredData] = touchDetectionC2MATLAB(rawData)
% TOUCHDETECTIONC2MATLAB - 电容触摸检测算法的MATLAB实现
% 基于C语言代码转换,实现三级滤波和状态机驱动的触摸检测
%
% 输入参数:
% rawData - 原始电容采样数据向量
%
% 输出参数:
% touchState - 触摸状态向量 (0:未触摸, 1:触摸)
% filteredData - 滤波后的数据向量
%% ========================== 参数初始化 ==========================
% 从C代码宏定义转换的MATLAB参数
LPFCHx_Hapha = 0.1; % 深度滤波系数 (Q15格式转换)
LPFCHx_Hlimit_h = 200; % 深度滤波上限值
LPFCHx_Hlimit_l = 150; % 深度滤波下限值
LPFCHx_Lapha = 0.4; % 浅度滤波系数
LPFCHx_Llimit_h = 200; % 浅度滤波上限值
LPFCHx_Llimit_l = 150; % 浅度滤波下限值
LPFCHx_Mapha = 0.4; % 中间滤波系数
LPFCHx_Mlimit_h = 200; % 中间滤波上限值
LPFCHx_Mlimit_l = 150; % 中间滤波下限值
% 状态机参数
TOUCH_THRESHOLD = 8; % 触摸触发阈值
DEBOUNCE_TIME = 10; % 去抖时间(采样点数)
MAX_TIMEOUT = 300; % 最大触摸持续时间
COOLDOWN_TIME = 50; % 触摸冷却时间
RESAMPLE_INTERVAL = 5; % 重采样间隔
%% ========================== 数据结构初始化 ==========================
% 滤波器结构体 (MATLAB struct替代C的LPF结构)
LPF_H = struct(...
'apha', LPFCHx_Hapha, ...
'H_limit', LPFCHx_Hlimit_h, ...
'L_limit', LPFCHx_Hlimit_l, ...
'UPdata', true, ...
'in', 0, ...
'out', 0, ...
'P_out', 0, ...
'Mid_out', 0);
LPF_Mid = struct(...
'apha', LPFCHx_Mapha, ...
'H_limit', LPFCHx_Mlimit_h, ...
'L_limit', LPFCHx_Mlimit_l, ...
'UPdata', true, ...
'in', 0, ...
'out', 0, ...
'P_out', 0, ...
'Mid_out', 0);
LPF_L = struct(...
'apha', LPFCHx_Lapha, ...
'H_limit', LPFCHx_Llimit_h, ...
'L_limit', LPFCHx_Llimit_l, ...
'UPdata', true, ...
'in', 0, ...
'out', 0, ...
'P_out', 0, ...
'Mid_out', 0);
% 触摸检测状态机 (MATLAB struct替代C的TouchCmp结构)
TouchState = struct(...
'is_touch_detected', false, ...
'is_in_cooldown', false, ...
'direction', 0, ...
'current_value', 0, ...
'previous_value', 0, ...
'peak_value', 0, ...
'resampled_value', 0, ...
'shake_count', 0, ...
'timer', 0, ...
'Current_TouchSt', 0, ... % 0:TOUCH_IDLE_STATE
'previous_TouchSt', 0);
%% ========================== 主处理循环 ==========================
nSamples = length(rawData);
filteredData = zeros(1, nSamples);
touchState = zeros(1, nSamples);
for i = 1:nSamples
% 三级滤波处理
filteredValue = touchFilter(LPF_H, LPF_Mid, LPF_L, rawData(i));
filteredData(i) = filteredValue;
% 状态机触摸检测
[TouchState, detected] = stateMachineDetection(TouchState, filteredValue, LPF_Mid);
touchState(i) = detected;
end
%% ========================== 三级滤波函数 ==========================
function filteredValue = touchFilter(LPF_H, LPF_Mid, LPF_L, rawValue)
% TOUCHFILTER - 三级滤波处理实现
% 等效C函数: Touch_Filiter()
%
% 输入:
% LPF_H, LPF_Mid, LPF_L - 滤波器结构
% rawValue - 原始采样值
%
% 输出:
% filteredValue - 三级滤波后的值
% 中间滤波处理
LPF_Mid.in = rawValue;
LPF_Mid = limitLPF(LPF_Mid);
% 深度滤波处理
LPF_H.in = LPF_Mid.out;
LPF_H = limitLPF(LPF_H);
% 浅度滤波处理
LPF_L.in = LPF_Mid.out;
LPF_L = limitLPF(LPF_L);
% 返回深度与浅度滤波的差值
filteredValue = LPF_H.out - LPF_L.out;
end
%% ========================== 限幅低通滤波 ==========================
function p = limitLPF(p)
% LIMITLPF - 限幅低通滤波实现
% 等效C函数: My_LimitLPF()
%
% 数学模型:
% y[n] = α*x[n] + (1-α)*y[n-1]
% 其中α为滤波系数
if p.UPdata
% 初始化滤波器状态
p.out = p.in;
p.P_out = p.in;
p.Mid_out = p.in * 32768; % Q15格式等效
p.UPdata = false;
else
% 限幅处理
Hin = p.out + p.H_limit;
Lin = p.out - p.L_limit;
if p.in >= Hin
p.in = Hin;
elseif p.in <= Lin
p.in = Lin;
end
% 低通滤波实现 (Q15格式转换)
% 等效于: p.out = p.P_out + ((p.in - p.P_out) * p.apha) >> 15
p.Mid_out = p.Mid_out + (p.in - p.P_out) * p.apha;
p.out = p.Mid_out / 32768; % 反Q15转换
p.P_out = p.out;
end
end
%% ========================== 状态机检测函数 ==========================
function [TouchState, detected] = stateMachineDetection(TouchState, filteredValue, LPF)
% STATEMACHINEDETECTION - 触摸状态机实现
% 等效C函数: OptimizedTouchDetection1()
%
% 状态机状态:
% 0: TOUCH_IDLE_STATE - 空闲状态
% 1: MATCHING_DETECTION_STATUS - 匹配检测
% 2: MATCH_THE_WAITING_STATE - 匹配等待
% 3: TOUCH_TO_CONFIRM_STATUS - 触摸确认
% 4: JITTER_STATE - 抖动状态
% 预处理: 阈值裁剪
TouchState.current_value = filteredValue;
if abs(TouchState.current_value) < TOUCH_THRESHOLD
TouchState.current_value = 0;
end
% 状态机处理
switch TouchState.Current_TouchSt
case 0 % TOUCH_IDLE_STATE
TouchState = idleProcessing(TouchState);
case 1 % MATCHING_DETECTION_STATUS
TouchState = matchingDetection(TouchState);
case 2 % MATCH_THE_WAITING_STATE
TouchState = matchWaiting(TouchState, LPF);
case 3 % TOUCH_TO_CONFIRM_STATUS
TouchState = matchConfirm(TouchState);
case 4 % JITTER_STATE
TouchState = jitterProcessing(TouchState, LPF);
end
% 更新前值并返回检测状态
TouchState.previous_value = TouchState.current_value;
detected = TouchState.is_touch_detected;
% 重置瞬时检测标志
TouchState.is_touch_detected = false;
end
%% ========================== 状态处理子函数 ==========================
function state = idleProcessing(state)
% IDLEPROCESSING - 空闲状态处理
if state.current_value ~= 0
state.direction = sign(state.current_value);
state.Current_TouchSt = 1; % 切换到匹配检测
end
end
function state = matchingDetection(state)
% MATCHINGDETECTION - 匹配检测状态
abs_current = abs(state.current_value);
abs_previous = abs(state.previous_value);
% 更新重采样值
state.resampled_value = state.current_value;
% 峰值检测
if abs_current < abs_previous
state.peak_value = state.previous_value;
state.Current_TouchSt = 2; % 切换到匹配等待
state.timer = 0;
end
end
function state = matchWaiting(state, LPF)
% MATCHWAITING - 匹配等待状态
state.timer = state.timer + 1;
% 重采样处理
if mod(state.timer, RESAMPLE_INTERVAL) == 0
state.resampled_value = state.current_value;
end
% 极性反转检测
current_dir = sign(state.current_value);
if (abs(state.current_value) > abs(state.peak_value)/4) && ...
(state.direction + current_dir == 0)
if state.timer > DEBOUNCE_TIME
state.Current_TouchSt = 3; % 切换到触摸确认
else
state.Current_TouchSt = 4; % 切换到抖动处理
end
end
% 超时处理
if state.timer > MAX_TIMEOUT
state = resetTouchState(state);
end
end
function state = matchConfirm(state)
% MATCHCONFIRM - 触摸确认状态
state.is_touch_detected = true;
state.is_in_cooldown = true;
state = resetTouchState(state);
state.Current_TouchSt = 0; % 返回空闲状态
end
function state = jitterProcessing(state, LPF)
% JITTERPROCESSING - 抖动处理状态
state.timer = state.timer + 1;
% 重采样处理
if mod(state.timer, RESAMPLE_INTERVAL) == 0
state.resampled_value = state.current_value;
end
% 直接确认触摸 (简化实现)
state.Current_TouchSt = 3; % 切换到触摸确认
end
function state = resetTouchState(state)
% RESETTOUCHSTATE - 重置触摸状态
state.direction = 0;
state.peak_value = 0;
state.resampled_value = 0;
state.shake_count = 0;
state.timer = 0;
end
end
% 生成测试数据 (触摸事件+噪声)
t = 0:0.1:100;
rawData = 10*sin(0.5*t) + 20*(t>20 & t<40) + 8*randn(size(t));
% 运行触摸检测
[touchState, filtered] = touchDetectionC2MATLAB(rawData);
% 可视化结果
subplot(3,1,1);
plot(t, rawData, 'b');
title('原始电容数据');
xlabel('时间 (ms)');
ylabel('电容值');
subplot(3,1,2);
plot(t, filtered, 'r');
title('三级滤波输出');
xlabel('时间 (ms)');
ylabel('滤波值');
subplot(3,1,3);
stairs(t, touchState, 'g', 'LineWidth', 1.5);
title('触摸状态检测');
xlabel('时间 (ms)');
ylabel('触摸状态');
ylim([-0.1 1.1]);
最新发布