Pressured air cooling controlled with servo and ball valve
-
@lael I can control the flow from 0% to 100%. The problem is that this range corresponds to the area of 80-100% fan speed on the duet. My workaround is to set the minimum fanspeed in my slicer to just over 80%.
Since I am also cooling my hotend with the air pump, I have set up the relay to trigger when the hotend reaches a certain temperature.
-
I can see how that would create some frustrations with slicing. Do you have any photos of your hotend cooling setup - that sounds neat!
-
@MaxGyver I wonder if the control restriction you are seeing is related to the lack of air pressure running through the valve. If you take a look at a similar, but different valve here: https://docs.rs-online.com/02fd/A700000006738966.pdf (SMC, amperage controlled, not PWM), you can see that the operating pressure has a direct correlation to the operating range of the valve, and that with too low an air pressure, the total flow (lpm) will be reduced.
It also seems that a larger bore is more effective with a lower pressure. (What bore size is the model you got?) I would guess, without doing the math in the burkett data sheet, that their valves would have similar / identical properties.
So for the SMC model at a bore size of 4mm and pressure of 0.04Mpa / ~5psi you would expect to see the total range of flow starting at 230mA and wide open at 320mA/330mA, and with a flow of 0-30Lpm. I wonder if that behaviour is why you are seeing the PWM control in such a narrow band?
-
I wonder if you were to hook it up to a compressor supply at a higher pressure, then run a pressure regulator after the differential valve whether that would give a greater range of adjustment. Then you could use a flowmeter similar to: https://www.aliexpress.com/item/32905397665.html (assuming they also work consistently at such a low pressure...) to measure and control the flow that is released to part cooling.
-
@lael The SMC Proportional valve will not work on the Duet since it is not possible to control the amperage properly. According to the data sheet the buerkert valve can be controlled applying a PWM frequency of 300-400 Hz. My guess is that this corresponds to 80-100% fanspeed. In this area I can control the flow very precisely so pressure is not the issue.
Cheers Max
-
Hey, I am sorry to reheat this topic.
I have been using magnetic proportional valves for some time with limited success.
They are hard to control with the duet right now. Furthermore, they tend to heat up during longer use which makes them even harder to control. Since they are also very expensive I switched back to RC-servos and ball valves.Can a demon.g be used to translate the M106 Fan speed into a Servo position?
In my case I need 0%-100% fan speed to equal 0°-90° Servo position. (Or stepper position as an alternative? )@lael What solution are you using right now?
-Max
-
@maxgyver said in Pressured air cooling controlled with servo and ball valve:
Can a demon.g be used to translate the M106 Fan speed into a Servo position?
In my case I need 0%-100% fan speed to equal 0°-90° Servo position. (Or stepper position as an alternative? )It would be nice if we could write a macro called 'M106' and put all the math required there. When gcode contains a M106 command, the macro is called instead of the fan definition in config.g
I'm currently in a similar position, where I want to change retract/unretract behaviour and use a servo or solenoid for Z-hop. -
@o_lampe said in Pressured air cooling controlled with servo and ball valve:
It would be nice if we could write a macro called 'M106' and put all the math required there. When gcode contains a M106 command, the macro is called instead of the fan definition in config.g
I've suggested that before. while it's currently possible to add a macro to create a new gcode, it's a bit harder to do for an existing gcode function that the firmware expects to behave a certain way.
In this specific case it's been requested to allow M106 to function with things other than fans and it's on the wishlist for now.
-
@phaedrux said in Pressured air cooling controlled with servo and ball valve:
it's a bit harder to do for an existing gcode function that the firmware expects to behave a certain way.
I see, it would be necessary to find the original M106 code snipped in the source and process the same odds and ends in a custom macro.
-
@phaedrux
Can you please post the link to the wishlist post? I would like to follow the thread.-Max
-
@maxgyver The main wishlist forum is here: https://forum.duet3d.com/category/8/firmware-wishlist
I'm not sure where the thread in question was though. It may not have been a request there. But if you want to make it more official you can create a thread there about it.
-
i did this with limited success for a servo on out7 with ballvalve,
i created a macro called airservovalve with the below
; AirValveServo
if fans[0].actualValue = 0
M280 P1 S0 ; Close the valve
elif fans[0].actualValue >= 0.01 && fans[0].actualValue <= 0.10
M280 P1 S18 ; Open valve 10%
elif fans[0].actualValue >= 0.11 && fans[0].actualValue <= 0.20
M280 P1 S36 ; Open valve 20%
elif fans[0].actualValue >= 0.21 && fans[0].actualValue <= 0.30
M280 P1 S54 ; Open valve 30%
elif fans[0].actualValue >= 0.31 && fans[0].actualValue <= 0.40
M280 P1 S72 ; Open valve 40%
elif fans[0].actualValue >= 0.41 && fans[0].actualValue <= 0.50
M280 P1 S90 ; Open valve 50%
elif fans[0].actualValue >= 0.51 && fans[0].actualValue <= 0.60
M280 P1 S108 ; Open valve 60%
elif fans[0].actualValue >= 0.61 && fans[0].actualValue <= 0.70
M280 P1 S126 ; Open valve 70%
elif fans[0].actualValue >= 0.71 && fans[0].actualValue <= 0.80
M280 P1 S144 ; Open valve 80%
elif fans[0].actualValue >= 0.81 && fans[0].actualValue <= 0.90
M280 P1 S162 ; Open valve 90%
elif fans[0].actualValue >= 0.91 && fans[0].actualValue <= 1.0
M280 P1 S180 ; Open valve 100%Then in Daemon.g added this
M98 P"0:/macros/Special Scripts/AirValveServo"The only issue was it was a bit slow responding to fan speed changes
-
-
@mikedc
Isn't it better to 'scale' the incoming PWM value to the required servo-angle?
You need to know: min_in, max_in, min_out, max_out.[**pseudo** code] var scale_factor = {(max_out - min_out) / (max_in - min_in)} var servo_out = {scale_factor * (fans[0].actualValue - min_in) + min_out}
There's a standard formula to scale variables, but I couldn't write it down from memory.. Have to google it..
//edit This should work, just have to put it in clean gcode-meta -
@o_lampe maybe yes, but when i was trying this it was the only way i could get it working
-
So just to recap, these are my values:
- min_in = 0 (M106 S0 ->Fan off)
- max_in = 255 (M106 S255 -> Fan full on)
- min_out = 0 (M280 P0 S0 -> Servo at 0° -> valve closed)
- max_out =90 (M280 P0 S90 -> Servo at 90° -> valve fully open)
So my code should look like this ?
[**pseudo** code] var scale_factor = {(90 - 0) / (255 - 0)} var servo_out = {scale_factor * (fans[0].actualValue - 0) + 90} M280 P0 S{var.servo_out}
I have not used G-Code meta commands before, so I would need a little help here to put this in clean meta code and make this work.
-Max
-
@maxgyver
I haven't written anything in Meta-code yet, but I read a little.
E.g. the waved brackets {} are mandatory for the outmost math-expressions.
If you want to test it, you can replace M280...with a harmless echo P"var.servo_out"I believe, there is a way to call daemon.g more often to get a faster response, maybe the experts can chime in here?
For later editing it could be useful to put the min/max values in variables too, otherwise you can cut a few corners, where a value is zero.
-
@maxgyver
You would probably be better off declaring global variables in config.g then updating the value in your macro ( or daemon.g)
If you're running in daemon.g it just seems counter productive to be declaring and freeing variables constantly.Config.g
; create variables - must be after servo is created global scale_factor = {(90 - 0) / (1 - 0)} ; no need for the math in this instance but it makes it clear how you arrive at the value. global servo_out = 0 ; set to zero initially M280 P0 S{global.servo_out} ; start with valve closed
Daemon.g
set global.servo_out = {global.scale_factor * (fans[0].actualValue - 0) + 0} ; calculate position required M280 P0 S{global.servo_out} ; adjust valve position.
You could optionally use an IF statement to only adjust when required, which I suppose would reduce the traffic and cpu time by a tiny amount.
-
@maxgyver said in Pressured air cooling controlled with servo and ball valve:
So just to recap, these are my values:
- min_in = 0 (M106 S0 ->Fan off)
- max_in = 255 (M106 S255 -> Fan full on)
- min_out = 0 (M280 P0 S0 -> Servo at 0° -> valve closed)
- max_out =90 (M280 P0 S90 -> Servo at 90° -> valve fully open)
Actually , thinking about this, the value you get back from fans[0].actualValue will be in the range 0-1, not 0-255
You will need to change your code accordingly. -
It's a rainy day here, so for something to do I decided to fully test this.
Using a YM2763 13kg/cm hobby servo (externally powered so as to not risk damaging the duet).
This has an input range of 0-180 which corresponds to the angle.Please refer to the notes for M280 as other servos may require different values
It's not really necessary to create variables for all settings, but it makes adjustment and readability easier.
in config.g
;Valve Control ; Set up scaling variables {(output_end - output_start) / (input_end - input_start)} M950 S1 C"exp.heater4" ; assign GPIO port 1 to heater4 on expansion connector, servo mode global InputStart = 0 global InputEnd = 1 global OutputStart = 0 global OutputEnd = 90 global ScaleFactor = (global.OutputEnd - global.OutputStart) / (global.InputEnd - global.InputStart) ; no need for the math in this instance but it makes it clear how you arrive at the value. global ServoOut = floor(global.ScaleFactor * (fans[0].actualValue - global.InputStart) + 0.5) + global.OutputStart ; calculate position required on sevo - use floor() to apply rounding M280 P1 S{global.servo_out} ; adjust valve position to reflect fan speed.
in daemon.g or macro
set global.ServoOut = floor((global.ScaleFactor * (fans[0].actualValue - global.InputStart)) + 0.5) + global.OutputStart ; calculate position required - use floor() to apply rounding to nearest whole number ;echo {global.ServoOut} M280 P1 S{global.ServoOut} ; adjust valve attached to servo on P1 to reflect scaled fan speed.