Main Site Documentation

Change Stepper Motor Speed


#1

I’m certain this problem is because of my lack of understand of C#, not necessarily the stepper module. My goal is to be able to vary the speed of a stepper motor “on the fly” using the potentiometer module.

I first tried to put the code for updating the variable “Motor_Speed”, which I am passing to run, in “ProgramStarted” but the value from the potentiometer was only read when the unit first started. In order to get the potentiometer to constantly update, I put a while routine in place. I knew this wasn’t a good solution but just wanted to make sure the potentiometer was changing and my math for stepper speed was correct, it was. Now I can’t think of the proper way to do this, I’m certain it’s obvious but I’m used to PLC’s so I’ve hit a wall. Any help would be appreciated.

namespace GHI_Stepper_Test
{
    public partial class Program
    {
        public static GTM.GHIElectronics.Stepper_L6470 stepper;// = new GTM.GHIElectronics.Stepper_L6470(6);
        
        uint Motor_Speed;
  
       
        // This method is run when the mainboard is powered up or reset.  
        void ProgramStarted()
        {         
            button.ButtonPressed += new Button.ButtonEventHandler(button_ButtonPressed);
            button2.ButtonPressed += new Button.ButtonEventHandler(button2_ButtonPressed);

            stepper_L6470.Run(GTM.GHIElectronics.Stepper_L6470.Direction.FWD, Motor_Speed);
            while (button2.IsPressed == false)
            {
                runmotor();
            }
            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print("Program Started");
   
                
        }
        void button_ButtonPressed(Button sender, Button.ButtonState state)
        {
        
            stepper_L6470.Move(GTM.GHIElectronics.Stepper_L6470.Direction.FWD, 5000);
            Debug.Print("Jog");
        }
        void button2_ButtonPressed(Button sender, Button.ButtonState state)
        {
            stepper_L6470.HardStop();
         
            Debug.Print("Stop");
        }
        void runmotor()
        {
            double pot_speed = potentiometer.ReadPotentiometerPercentage();
            Motor_Speed = (uint)System.Math.Round(pot_speed * 100000);
            Debug.Print("Pot Value is:" + pot_speed);
            Debug.Print("Motor Speed is set to:" + Motor_Speed);
            
        }

     
       
    }
}

#2

Never put a loop or any other long running code in ProgramStarted(). Move your loop out into its own thread or Timer.


#3

I’d say as an approach, you may not want to change the speed every time a small amount of resistance change occurs, so using an arbitrary timer as Ian says, of say 1sec, will do two things, first fix up the never-ending ProgramStarted plus then it won’t give your steppers a heart attack when it changes more than a few times a second. In your timer set the speed based on reading the potentiometer.


#4

Yeah, I know not to put a loop there and I agree that delaying the change would be better. I thought of putting a timer in there as the solution but I’m not necessarily try to solve me problem here, I’m more trying to learn how the software flows. How would I monitor one value and pass that along to something in “real time” (not trying to be deterministic)?

My bigger question is how does the software flow? I think of things in terms of PLC, where once the bottom rung of code is completed then it all starts again at the top. ProgramStarted seems to function differently, code I put there only runs once, otherwise “Program Started” would stream into my debug window. Does Main() execute multiple times?

Any explanation…or direction to a good website that can explain some C# particulars.


#5

Here’s a little video I made a while back but have never made public. Enjoy.

(I still need to blur out the MAKE logos. Please don’t contact MAKE regarding use of this video.)


#6

So the one thing I’d say is that in PLC terms, you have a state machine. In Gadgeteer the common practice is to actually be event driven, not sequentially driven. The simple explanation is that Main() will always run once and once only (which is why in non-Gadgeteer apps you always see people telling you NEVER let Main() terminate, put it to sleep with thread.sleep(timeout.infinite) if you need, but don’t let it terminate). Gadgeteer manages it so you never need to know that.

So what that means for you is you can write your app into states and have a logic ladder that steps through your sequence of events. But if you think about the problem, and in terms of how you want to manage the application flow, you will find you can mostly convert this to an event based model. For example, you might have a global “state” that says if you should override motor movements, and when a limit switch is hit, you stop the motor and set that override. This way you don’t need to constantly be polling limit switches and confirming you haven’t hit anything :slight_smile: You can use the button press event of a Jog button to carry out a specific action with the motor - you might have another button that turns the actions in question in the opposite direction, and so you don’t necessarily have to code your detection logic in multiple places.