COG and object questions
idbruce
Posts: 6,197
Hello Everyone
Due to a recent question pertaining to my stepper drivers, I have been trying to create a new variable speed stepper driver.
The new driver that I am trying to create is within a seperate object file and it starts a new cog. After initializing several values, it goes into a loop to wait for value changes. This object also has a "set" method for setting the values of which the watchdog loop is waiting for change. The "set" method has several parameters that it receives from the parent object, and I am attempting to assign these parameters to local variables within the child object. Of course this is all experimental and of course the code is not working
So now I wonder is it not functioning due to the fact that the child object is in an endless loop, or is it something else? I am sure there are a lot of mistakes and problems with the following code, but I am still experimenting.
Here is some code from the parent object:
And here is the child object file:
Any input?
Bruce
Due to a recent question pertaining to my stepper drivers, I have been trying to create a new variable speed stepper driver.
The new driver that I am trying to create is within a seperate object file and it starts a new cog. After initializing several values, it goes into a loop to wait for value changes. This object also has a "set" method for setting the values of which the watchdog loop is waiting for change. The "set" method has several parameters that it receives from the parent object, and I am attempting to assign these parameters to local variables within the child object. Of course this is all experimental and of course the code is not working
So now I wonder is it not functioning due to the fact that the child object is in an endless loop, or is it something else? I am sure there are a lot of mistakes and problems with the following code, but I am still experimenting.
Here is some code from the parent object:
OBJ Stepper1 : "VariableStepperDriver" PUB Main Stepper1.Start(3, 4, 5, CLK_FREQ / 1_000_000) WAITCNT(CLKFREQ * 2 + CNT) Stepper1.SetSpeedDir(CLKFREQ / 13_000, CLK_FREQ / 1_600, CLK_FREQ / 3_200_000, 0, FALSE, FALSE)
And here is the child object file:
VAR LONG lDirectionPin LONG lStepPin LONG lDisablePin LONG lDirection LONG lNewDirection LONG lStopMotor LONG lDisableMotor 'Variable for cog ID LONG lCog LONG lUpdateSpeed LONG lHighPulseWidth LONG lCounter LONG lNewMaxExeMotorSpeed LONG lNewStartStopSpeed LONG lNewRampIncDec LONG lNewRampingSteps LONG lMaxExeMotorSpeed LONG lStartStopSpeed LONG lRampIncDec LONG lRampingSteps 'Stack for running seperate cog LONG StepperStack[100] PUB Start(DirectionPin, StepPin, DisablePin, HighPulseWidth) : Success Stop Success := (lCog := COGNEW(Initialize(DirectionPin, StepPin, DisablePin, HighPulseWidth), @StepperStack) + 1) PUB Stop IF lCog COGSTOP(lCog~ - 1) PUB Initialize(DirectionPin, StepPin, DisablePin, HighPulseWidth) lDirectionPin := DirectionPin lStepPin := StepPin lDisablePin := DisablePin DIRA[lStepPin] := 1 DIRA[lDirectionPin] := 1 DIRA[lDisablePin] := 1 lHighPulseWidth := HighPulseWidth lUpdateSpeed := FALSE SetupCounter MonitorSpeedChange PUB SetupCounter 'Set up the CTRMODE of Counter A for NCO/PWM single-ended. CTRA[30..26] := %00100 'Set the output pin for Counter A. CTRA[5..0] := lStepPin 'Set the value to be added to PHSA with every clock cycle. FRQA := 1 'Set APIN as an output. DIRA[lStepPin] := 1 'Get the current System Counter value and initialize the lCounter 'global variable. lCounter := CNT PUB RampUpMotorSpeed OUTA[lDirectionPin] := lDirection 'Ramp up motor speed REPEAT lRampingSteps 'Send out a high pulse on the step pin for the desired duration. PHSA := -lHighPulseWidth 'Wait for a specified period of time before send sending another 'high pulse to the step pin. WAITCNT(lCounter += lStartStopSpeed -= lRampIncDec) MaintainCurrentMotorSpeed PUB MaintainCurrentMotorSpeed 'Run the motor at full speed until we get contrary input and then 'stop this iteration. REPEAT WHILE lUpdateSpeed == FALSE 'Send out a high pulse on the step pin for the desired duration. PHSA := -lHighPulseWidth 'Wait for a specified period of time before send sending another 'high pulse to the step pin. WAITCNT(lCounter += lStartStopSpeed) PUB RampDownMotorSpeed OUTA[lDirectionPin] := lDirection 'Ramp down the motor. REPEAT lRampingSteps 'Send out a high pulse on the step pin for the desired duration. PHSA := -lHighPulseWidth 'Wait for a specified period of time before send sending another 'high pulse to the step pin. WAITCNT(lCounter += lStartStopSpeed += lRampIncDec) IF lStopMotor <> TRUE MaintainCurrentMotorSpeed ELSE IF lDisableMotor == TRUE 'Disable the motor. OUTA[lDisablePin] := 0 MonitorSpeedChange PUB MonitorSpeedChange REPEAT WHILE lUpdateSpeed == FALSE IF lNewStartStopSpeed > lStartStopSpeed UpdateSpeedChange OUTA[lDisablePin] := 1 RampDownMotorSpeed ELSE UpdateSpeedChange OUTA[lDisablePin] := 1 RampUpMotorSpeed PUB SetSpeedDir(MaxExeMotorSpeed, StartStopSpeed, RampIncDec, Direction, StopMotor, DisableMotor) | RampingSteps RampingSteps := (StartStopSpeed - MaxExeMotorSpeed) / RampIncDec lNewMaxExeMotorSpeed := MaxExeMotorSpeed lNewStartStopSpeed := StartStopSpeed lNewRampIncDec := RampIncDec lNewDirection := Direction lNewRampingSteps := RampingSteps IF StopMotor == TRUE lStopMotor := TRUE ELSE lStopMotor := FALSE IF DisableMotor == TRUE lDisableMotor := TRUE ELSE lDisableMotor := FALSE lUpdateSpeed := TRUE PUB UpdateSpeedChange lMaxExeMotorSpeed := lNewMaxExeMotorSpeed lStartStopSpeed := lNewStartStopSpeed lRampIncDec := lNewRampIncDec lRampingSteps := lNewRampingSteps lDirection := lNewDirection lUpdateSpeed := FALSE
Any input?
Bruce
Comments
I don't see the endless loop in the child object?
Edit: Or was your concern there is an endless loop you didn't intend to occur?
Edit again: I suspect "MoinitorSpeedChange" doesn't have the proper indentation to loop the way you are expecting. My guess is everything after "REPEAT WHILE lUpdateSpeed == FALSE" should be indented (within that method).
Edit: Duane the way he is using repeat in that instance it is a one line instruction.
The final instruction of Initialize is a call to MonitorSpeedChange, and I believe REPEAT WHILE lUpdateSpeed == FALSE is an endless loop, because I don't believe the call to SetSpeedDir from the parent updates the lUpdateSpeed variable. As far as the indentation goes, my intention was to just keep looping there until lUpdateSpeed equaled TRUE and then execute the remainder of the method, so indentation was not desired. The call from the parent to SetSpeedDir is intended to initialize some variables and then change lUpdateSpeed to TRUE, which would then allow MonitorSpeedChange to exit the REPEAT WHILE lUpdateSpeed == FALSE loop and continue on in that method.
@ratronic
Thanks I will try that.
All indentation is as intended.
As long as lUpdateSpeed == FALSE, it will just sit there and loop, but when lUpdateSpeed == TRUE, the remainder of the method should excute.
You are overlooking the obvious
That is what PUB SetSpeedDir(MaxExeMotorSpeed, StartStopSpeed, RampIncDec, Direction, StopMotor, DisableMotor) is intended for.
Why would I need to do that?
In the child object, the SetSpeedDir method needs values for it's parameters. From the parent method I pass that method values to it's parameters. As stated above and shown below.
I understand that... Look at the last instruction of the SetSpeedDir method, this is where that value is updated and it is not running in that cog.
Edit2: but if that variable is to be used in a REPEAT WHILE statement it will have to be changed from another cog to get out of that loop.
You're treating methods as goto statements. You'll soon run out of stack space doing it this way.
hmmmmmm
I want to thank you guys for your input, so thank you. I will try to modify my code a little later and see what happens.
Bruce