View Full Version : Some code help please

T Chap
10-10-2006, 11:57 AM
Over the past week I built a 3 axis cnc 6 wire uni stepper controller using one Propeller. I have borrowed code from here and there and have things really close to what I want for the basics of this stepper motor driver. There is one thing I cannot solve after many hours of experimenting.

There is a waitpne for A Step pin to go high, then it checks for the direction and calls a routine to move the motor either forward or backward one step, updating an index each iteration depending on direction. That part works great. Wherever the last index seqeunce was is what the motor stays at indefinitely, i.e. %1010 keeps coil 1A high and 2A high, so the motor is on constantly whether braked or moving when stepped. I want to cause the motor to not brake after X ms, for example, a repeating code block checks to see if the motor has moved, and times how long it has not moved. If it has not moved for X ms, change the outputs to %0000, so no more braking plus pwm noise. The motor is running from a cog, and I can send the motor random sequences from another cog as well that clearly disturbs the motor, so I know that it is getting the info. The problem is, I cannot cause the motor to reset to %0000 after any amount of time by checking for movement, pausing, sending 0000 to reset. The code to run the motor does not repeat, it is one iteration per step. Why is it that it still has some affect on the motor although it is not repeating a position sequence? My guess is, that even though one cog can send an outout state of %xxxx, any other cog sending its own state to the same pins does not negate the state that is held by any other cog, so they battle it out between clock cycles. Ok assuming that is correct, I attempted to put some lines at the end of each move iteration that said that if a variable was X, send out %0000, The problem there was getting some variable to interact in the very short time between the top of the move iteration and the end query of the variable to release it

Pub Start
outa[24..27] := %0000 ' does not affect the cog that has the motor pins at any state whether braked or moving

IF pauseMotor == 1 ' at the end of each move iteration, doesn't work
outa[24..27] := %0000

The work in progress is attached, if anyone can suggest a method that would allow me to test for a move, if no more movement for x time, turn off motor WITHOUT affect the index, that would be very helpful. What I intend to do is have the encoder always checking itself against the step count, so even if stopped with no holding torque, the motor can position itself back to where it should be if it moves out. On the cnc the current limiting noise is no big deal, but on other applications I have to kill the noise somehow. There are no more pins to mult to AND gates to control things externally, so this has to happen in code.

Thanks in advance

Post Edited (originator99) : 10/10/2006 5:16:44 AM GMT

James Long
10-11-2006, 12:04 AM
Could you archive the entire file (under the file menu) and send the zip for all files included.

I'll take a look and see if I can help.

James L

T Chap
10-11-2006, 02:21 AM
Thanks James. I commented out the PWM object it really isn't needed, since the "PWM" out is really driving a shift register to establish a fixed time off(clock/8), I just set a loop toggling the pin instead. The only other req'd object is alreay in the folder, but I included it here again(Rotary Encoder).

I worked on this tll 4am, here is the latest unsuccessful attempt. I decided to abandone getting the cog holding the motor to released it's latch for a second cog to act on the pins. Now, I am trying to get the "PWM" offtime to = 0, which which would accomplish the same thing. If the offtime of the pwm = 0, the motor is off. The pwm is used in current regulation set at 2300 ticks on, and any amount off, as it is just a clock driving the shift registers>turning on and off AND gates>running the motor.

Looking at the code, it appreats that it would work, but I think there are timing issues that are not obvious. WhenI have done is set a clock to run the pwm pin, then another counter to start counting if the STEP pin is low. If low for X amount of time, change the PWM's OFFTIME to "0", effectived shutting off the motor. Then, wait till the STEP is high again, and return the OFFTIME to 1000, turning on the motors. So far it will turn off, but will not turn back on.

I'd rather not burn the extra cogs to do this if possible.

Graham Stabler
10-11-2006, 02:32 AM
I don't think you should try turn the motors on and off with outa or dira, instead why not define a variable for each axis that must be 1 for the motor to turn and make the loop that does the turning conditional. If the variable is in main ram all cogs can see it.

If you try to make them fight the one sending ones will win, you can make a mess of the output waveform but not force it low. I suppose you could add inverters to your outputs and then force it high to turn off but there is no need.


T Chap
10-11-2006, 03:54 AM
Graham Thanks a million! 10 minutes with your idea solved it. Now, no more pwm noise in the motors after they stop. I looped the variable := outa[24..27] like you said and now can control the pins from the loop easily.


Graham Stabler
10-11-2006, 04:11 AM
Well it goes to show that sometimes the blind led by the blind stand in something other than poop.

Glad to have been of help.


James Long
10-11-2006, 08:06 AM
Glad you got it fixed.....

James L

T Chap
10-11-2006, 10:33 AM
There is a mystery that I can't get to the bottom of. Using the Rotary Encoder object found in the Examples folder, there is an array specified in the object called POS. The example code showed something like this:

if pos[0] == x
do whatever

So that the pos[0] is the first encoders location. I can run tests to see that this location is in fact what is being updated from encoder 1, for example if pos[0] == 400 turn on an led.

On boot up there is a motor initialize to get the sequence synced up with the last physical location the motor was at, otherwise there is always a missed pulsed on the first few pulses since the sequence is not locked with the motor. So the motor is told to move 32 steps to get itself in sync, THEN pos[0] is told to equal 0, and reset the STEP pusles back to 0 as well so there is a clean slate, the encoder counter and Step pulses are all at 0. BUT, the pos[0] will not reset, it retains its original value from the intiliaze move of 32 steps. Since the motor is halfstepping at 400 per rev, and the quadrature encoders are putting out 800 per rev, the pos[0] value is always x2 the Step moves. So even though the command pos[0] := 0 follows the init moves, the value will not change. The Rotary Encoder is running it's own cog.

Why can't the array value be changed from the main program?

T Chap
10-11-2006, 12:40 PM
Update: Never heard of this, but the longs for pos in the rotary object are read only! There is some documentation in the object that state that they are read only. I guess that explains it.