Duet3D Logo Duet3D
    • Tags
    • Documentation
    • Order
    • Register
    • Login

    Pressured air cooling controlled with servo and ball valve

    Scheduled Pinned Locked Moved
    General Discussion
    11
    61
    3.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • MaxGyverundefined
      MaxGyver
      last edited by MaxGyver

      @o_lampe

      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

      o_lampeundefined OwenDundefined 3 Replies Last reply Reply Quote 0
      • o_lampeundefined
        o_lampe @MaxGyver
        last edited by o_lampe

        @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.

        1 Reply Last reply Reply Quote 0
        • OwenDundefined
          OwenD @MaxGyver
          last edited by OwenD

          @maxgyver

          @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.

          1 Reply Last reply Reply Quote 0
          • OwenDundefined
            OwenD @MaxGyver
            last edited by OwenD

            @maxgyver said in Pressured air cooling controlled with servo and ball valve:

            @o_lampe

            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.

            1 Reply Last reply Reply Quote 0
            • OwenDundefined
              OwenD
              last edited by

              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. 
              
              o_lampeundefined MaxGyverundefined 2 Replies Last reply Reply Quote 2
              • o_lampeundefined
                o_lampe @OwenD
                last edited by

                @owend
                Thank you for chiming in!
                Can you confirm that in math formulas no waved brackets are necessary, but when I call eg. M280 the parameter has to be wrapped in {}?
                How do I know, I have enough free memory to write longer meta-code? (AI for TicTacToe can get quite voluminous)

                OwenDundefined 1 Reply Last reply Reply Quote 0
                • OwenDundefined
                  OwenD @o_lampe
                  last edited by

                  @o_lampe said in Pressured air cooling controlled with servo and ball valve:

                  @owend
                  Thank you for chiming in!
                  Can you confirm that in math formulas no waved brackets are necessary, but when I call eg. M280 the parameter has to be wrapped in {}?

                  Correct on both counts

                  How do I know, I have enough free memory to write longer meta-code? (AI for TicTacToe can get quite voluminous)

                  You can use M122 to see how much of the heap is used.
                  See here

                  o_lampeundefined 1 Reply Last reply Reply Quote 0
                  • o_lampeundefined
                    o_lampe @OwenD
                    last edited by

                    @owend
                    I just found this thread, please see my reply there

                    1 Reply Last reply Reply Quote 0
                    • o_lampeundefined
                      o_lampe
                      last edited by o_lampe

                      @OwenD and @MaxGyver
                      Thinking further and having pity with the servo, it would be better to add a 'hysteresis' in the code, such as

                      [pseudo code]
                      If (abs(new_fan_value - old_fan_value) > hysteresis)
                         go on
                      else
                        break
                      
                      

                      That's not necessarily a problem with fan-values changing in big numbers, but a Servo also has a'deadband' which you have to keep in mind. (and for further reference, if someone wants to reuse the code for something else)

                      1 Reply Last reply Reply Quote 0
                      • MaxGyverundefined
                        MaxGyver @OwenD
                        last edited by

                        @owend

                        I am getting the following error after inserting your code in my config.g

                        "Error: Failed to read code from macro config.g: Failed to parse major G-code number (lobal) in line 85"

                        To me, it looks like the global variable are not recognized by the firmware:

                        I am using firmware version 3.3-b2.

                        screen.PNG

                        1 Reply Last reply Reply Quote 0
                        • o_lampeundefined
                          o_lampe
                          last edited by

                          You have written servoout and also servo_out.

                          MaxGyverundefined OwenDundefined 2 Replies Last reply Reply Quote 0
                          • MaxGyverundefined
                            MaxGyver @o_lampe
                            last edited by

                            @o_lampe said in Pressured air cooling controlled with servo and ball valve:

                            You have written servoout and also servo_out.

                            Nope, this did not cause the error... 😕

                            "Error: Failed to read code from macro config.g: Failed to parse major G-code number (lobal) in line 4"

                            ;Valve Control
                            ; Set up scaling variables {(output_end - output_start) / (input_end - input_start)}
                            M950 S1 C"io4.out"  ; 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.ServoOut} ; adjust valve position to reflect fan speed.
                            
                            OwenDundefined o_lampeundefined 2 Replies Last reply Reply Quote 0
                            • OwenDundefined
                              OwenD @MaxGyver
                              last edited by

                              @maxgyver
                              @maxgyver
                              I'm assuming you are running the correct versions on DWC, etc etc
                              We are both running RRF3.3b2 and it works for me.
                              I'm on a Duet 2 wifi.
                              I don't have a duet 3, but I suspect it's actually coming from your M950 command on the previous line.
                              Either that are it's one of this SBC specific issues.

                              What happens when you run those commands individually from the console command line?

                              MaxGyverundefined 1 Reply Last reply Reply Quote 0
                              • OwenDundefined
                                OwenD @o_lampe
                                last edited by

                                @o_lampe
                                That was actually my error in the original.

                                1 Reply Last reply Reply Quote 0
                                • o_lampeundefined
                                  o_lampe @MaxGyver
                                  last edited by

                                  @maxgyver said in Pressured air cooling controlled with servo and ball valve:

                                  G-code number (lobal)

                                  Your parser believes global is the beginning of a move command and it can't parse "lobal" as number (0,1,2,3,4 expected)
                                  I'm with @OwenD it might be related to SBC issues.

                                  1 Reply Last reply Reply Quote 0
                                  • MaxGyverundefined
                                    MaxGyver @OwenD
                                    last edited by

                                    @owend said in Pressured air cooling controlled with servo and ball valve:

                                    (...)I suspect it's actually coming from your M950 command on the previous line.
                                    Either that are it's one of this SBC specific issues.

                                    It's not the M950 command (I have checked by commenting out this line)

                                    @owend said in Pressured air cooling controlled with servo and ball valve:

                                    What happens when you run those commands individually from the console command line?

                                    I get the same error message.

                                    -Max

                                    MaxGyverundefined 1 Reply Last reply Reply Quote 0
                                    • MaxGyverundefined
                                      MaxGyver @MaxGyver
                                      last edited by

                                      @maxgyver

                                      After upgrading to Beta3.3 the error message has changed to the following:

                                      Error.PNG

                                      the code in config.g:

                                      ;Valve Control
                                      ; Set up scaling variables {(output_end - output_start) / (input_end - input_start)}
                                      M950 S1 C"io4.out"  ; 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.ServoOut} ; adjust valve position to reflect fan speed.
                                      

                                      and deamon.g

                                      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. 
                                      

                                      -Max

                                      OwenDundefined 1 Reply Last reply Reply Quote 0
                                      • OwenDundefined
                                        OwenD @MaxGyver
                                        last edited by OwenD

                                        @maxgyver
                                        Try removing all the spaces around the variable names and in the equations
                                        I'm pretty sure I read another post where that was an issue on SBC
                                        There is also a 3.3RC1+2 binary you might try.

                                        Also note that daemon.g only runs once every 10 seconds now, so there's going to be a delay between setting the fan and the servo reacting.
                                        Moot until you get it working again of course.

                                        MaxGyverundefined 1 Reply Last reply Reply Quote 0
                                        • MaxGyverundefined
                                          MaxGyver @OwenD
                                          last edited by

                                          @owend said in Pressured air cooling controlled with servo and ball valve:

                                          Also note that daemon.g only runs once every 10 seconds now, so there's going to be a delay between setting the fan and the servo reacting.

                                          I recon this would make this solution almost useless considering the motion of the servo itself introduces another small delay.

                                          I will submit a Firmware Feature request to add Stepper/RC-Servo Support for M106

                                          -Max

                                          1 Reply Last reply Reply Quote 0
                                          • dc42undefined
                                            dc42 administrators @jay_s_uk
                                            last edited by

                                            @jay_s_uk said in Pressured air cooling controlled with servo and ball valve:

                                            @MaxGyver can you not use the L and X commands of M106 to do that?

                                            Lnnn Set the minimum fan speed (0 to 255 or 0.0 to 1.0) when a non-zero fan speed is requested.
                                            Xnnn Set the maximum fan speed (0 to 255 or 0.0 to 1.0) when a non-zero fan speed is requested. (supported in RRF >= 2.02)
                                            

                                            Yes that should work.

                                            Duet WiFi hardware designer and firmware engineer
                                            Please do not ask me for Duet support via PM or email, use the forum
                                            http://www.escher3d.com, https://miscsolutions.wordpress.com

                                            MaxGyverundefined 1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Unless otherwise noted, all forum content is licensed under CC-BY-SA