@@ -25,8 +25,10 @@ local RELAY_NUM = 0
2525
2626-- add new param POI_DIST_MAX
2727local PARAM_TABLE_KEY = 94
28- assert (param :add_table (PARAM_TABLE_KEY , " FAN_" , 1 ), " could not add param table" )
28+ assert (param :add_table (PARAM_TABLE_KEY , " FAN_" , 3 ), " could not add param table" )
2929assert (param :add_param (PARAM_TABLE_KEY , 1 , " ENABLE" , 1 ), " could not add FAN_ENABLE param" )
30+ assert (param :add_param (PARAM_TABLE_KEY , 2 , " FILT_TC" , 0.1 ), " could not add FAN_FILT_TC param" )
31+ assert (param :add_param (PARAM_TABLE_KEY , 3 , " DEBUG" , 0 ), " could not add FAN_DEBUG param" )
3032
3133--[[
3234 // @Param: FAN_ENABLE
@@ -37,11 +39,31 @@ assert(param:add_param(PARAM_TABLE_KEY, 1, "ENABLE", 1), "could not add FAN_ENAB
3739--]]
3840local FAN_ENABLE = Parameter (" FAN_ENABLE" )
3941
42+ --[[
43+ // @Param: FAN_FILT_TC
44+ // @DisplayName: Fan Control Filter Time Constant
45+ // @Description: Time constant for filtering fan control input (smaller = faster response, larger = smoother)
46+ // @Range: 0.01 2.0
47+ // @Units: s
48+ // @User: Standard
49+ --]]
50+ local FAN_FILT_TC = Parameter (" FAN_FILT_TC" )
51+
52+ --[[
53+ // @Param: FAN_DEBUG
54+ // @DisplayName: Fan Control Debug
55+ // @Description: Enable debug output for fan control
56+ // @Values: 0:Disable, 1:Enable
57+ // @User: Standard
58+ --]]
59+ local FAN_DEBUG = Parameter (" FAN_DEBUG" )
60+
4061-- local variables and definitions
4162local last_send_text_ms = 0 -- system time of last message to user (used to prevent spamming)
42- local relay_output_total = 0 -- total number of relay outputs (including both low and high)
43- local relay_output_high = 0 -- number of high relay outputs (never more than relay_output_total)
4463local relay_output_last = 0 -- last output to relay (used to avoid unnecessarily changing relay output)
64+ local relay_output_filtered = 0 -- filtered output
65+ local pwm_accumulator = 0 -- accumulator for PWM generation
66+ local last_debug_text_ms = 0 -- system time of last debug output to user
4567
4668-- send text message to user at no more than 1hz
4769function send_text (priority , warning_msg )
@@ -81,14 +103,20 @@ function update()
81103 end
82104 rc_fan_control_norm = (rc_fan_control_norm + 1.0 ) / 2.0
83105
84- -- determine if relay output should be moved high or low
85- local relay_output_average = 0
86- if relay_output_total > 0 then
87- relay_output_average = relay_output_high / relay_output_total
88- end
106+ -- apply low-pass filter to the desired output
107+ -- filter equation: filtered = filtered + (dt/tc) * (input - filtered)
108+ local dt = UPDATE_INTERVAL_MS / 1000.0 -- convert ms to seconds
109+ local filter_tc = FAN_FILT_TC :get () -- get time constant from parameter
110+ local alpha = dt / (filter_tc + dt )
111+ relay_output_filtered = relay_output_filtered + alpha * (rc_fan_control_norm - relay_output_filtered )
112+
113+ -- generate PWM output using filtered value
114+ -- accumulate the filtered value and output high when accumulator >= 1
115+ pwm_accumulator = pwm_accumulator + relay_output_filtered
89116 local relay_output_new = 0
90- if relay_output_average < rc_fan_control_norm then
117+ if pwm_accumulator >= 1.0 then
91118 relay_output_new = 1
119+ pwm_accumulator = pwm_accumulator - 1.0 -- subtract 1 but keep remainder
92120 end
93121
94122 -- set relay to high or low
@@ -101,18 +129,13 @@ function update()
101129 end
102130 relay_output_last = relay_output_new
103131
104- -- update totals
105- relay_output_total = relay_output_total + 1
106- if relay_output_new > 0 then
107- relay_output_high = relay_output_high + 1
108- end
109-
110- -- reset totals each 1000 updates
111- if relay_output_total >= 1000 then
112- -- debug output to user
113- gcs :send_text (MAV_SEVERITY .DEBUG , string.format (" Fan control: %.2f outputs, %.2f high" , rc_fan_control_norm , relay_output_average ))
114- relay_output_total = 0
115- relay_output_high = 0
132+ -- debug output to user (every 1000 updates = 1 second)
133+ if FAN_DEBUG :get () == 1 then
134+ local now_ms = millis ()
135+ if (now_ms - last_debug_text_ms ) > 1000 then
136+ gcs :send_text (MAV_SEVERITY .DEBUG , string.format (" Fan control: input=%.2f, filtered=%.2f, output=%d" , rc_fan_control_norm , relay_output_filtered , relay_output_new ))
137+ last_debug_text_ms = now_ms
138+ end
116139 end
117140
118141 return update , UPDATE_INTERVAL_MS
0 commit comments