Dynomotion

Group: DynoMotion Message: 7795 From: yeamans115 Date: 6/27/2013
Subject: hey tom, reply from my dad
i tried twice to post this is my "trajectory planner" thread but it seemed to fail so here it is again......

Hi TK,

I am Matt's dad and help him with the computer side of his machines. I have programmed in C and x86 assembler professionally for over 30 years (YIKES!!). A lot of this has been low level work writing drivers and interrupt handlers as well as firmware that lives inside printers and the like. I also have a background in old time digital hardware engineering dating from the era of DOS. I was an IEEE member for about 20 years.

In the old days, the term "hack" meant to take an existing program or piece of code and "hack" it into shape so that it would fit a different API or data structure. It could also include modifying the function of the code. Whatever – the point was to get something that ran with minimal development effort and knowledge of the specific system.

This is a lot like what I have been trying to do here. I had never seen the hardware spec before last week and had no knowledge of the data structures and routines to manipulate those structures. This definitely called for an old time hack.

You were kind enough to comment on the small pieces of code that were thrown together to get my son going. I wanted to take this opportunity to answer some questions you had.

Thanks for the time and patience you have shown to assist us in getting "the machine" up and running.

Just to review, he is using the Gecko servo drives. These use stepper motor step/direction information to run brushed DC servo motors with no positional feedback to the Kanalog board or the software.


Hi Matt,

Regarding your C Programs: I would combine the enableMatt.c and shiz code.c programs together. Add the enableMatt stuff which services buttons and such to the end of the shiz code.c program. That way only one button push is needed to configure and enable everything and then continuously service your external buttons.

Regarding the enable Matt.c:

ClearStopImmediately(); // Clear all stop modes
ch0->Enable=1; // Enable Axis 0
ch1->Enable=1; // Enable Axis 1
ch2->Enable=1; // Enable Axis 2

These can be removed after the programs are combined. Also there are functions used to Enable the Axis like used in your other program that should be used for Enabling Axes.

Originally, we used the EnableAxis() routine. However, Matt disapproved of this as it reset the X, Y & Z axis indicators in the KmotionCNC program. So, we pulled together a few lines that seemed to re-enable the axes without resetting the KmotionCNC position values.

Regarding this code:

// Handle FeedHold/Resume
result = ReadBit(FEEDHOLD_BIT) ;
// result = Debounce(ReadBit(FEEDHOLD_BIT),);
if (result == 1)
{
if (CS0_StoppingState == 0){
StopCoordinatedMotion();ClearBit(FEEDHOLD_BIT);}
else {
ResumeCoordinatedMotion();ClearBit(FEEDHOLD_BIT);}
}


Not sure why you didn't use the debounce routine. But it looks like you were using the 3 required variables &ccount,&clast,&clastsolid rather than &fcount,&flast,&flastsolid. Also I don't understand how you are treating an IO bit as both an input and an output. You read it, but then you clear it??

I just respond to user requests. Matt wanted a KMotionCNC button/hotkey that would toggle feedhold. (i.e Hit it to turn on, then hit again to turn off.) It was easy to use the KMotionCNC button setup to assign a button/key to set a bit ("FEEDHOLD_BIT"). Whenever the button/key is pressed, the KMotionCNC program will set this bit in the hardware. This becomes the state of the bit and that state is available to be read back by software. [If not, its state would be what – undefined? That would be a poor design and the hardware seems very well thought out.] So the bit is set by KMotionCNC and read by the above code. When the bit is set, the above code reads it and based on CS0_StoppingState, either stops or resumes coordinated motion. Then the FEEDHOLD_BIT that indicates a toggle request is cleared.

Debounce should not be required as the bit is set by software and not by some twangy external switch.

As an aside, this is an example of a good old fashioned hack. I wrote almost none of this code because I found it in some other C program. I don't know who does what with CS0_StoppingState. And I have no idea what is going on inside ResumeCoordinatedMotion() or StopCoordinatedMotion(). But, on the whole, it seems to work. Empiricism at its finest.

This doesn't seem to be ever used

persist.UserData[WATCHDOG]=40; // Set watchdog count down


The WATCHDOG variable indicates that the enableMatt.c program is still running (i.e. the thread has not been killed by an estop.) The following c program runs in thread 1 and will shut off the spindle when estop is activated.

#include "KMotiondef.h"
#include "Matt.h"
// Program to shut down spindle if enableMatt.c stops running
// This watchdog program must be run in thread 1
// Each Program uses persist user variable WATCHDOG (86) to communicate
// Turns off LED 46 if enableMatt.c running, else turns on LED 46
// loop_delay is used to cut down on the number of redundant ClearBit()
// requests sent to the hardware
//
// watchdog.c June 15, 2013 JEY

void main ()

{
int loop_delay;
loop_delay=30; // Initialize loop delay

for (;;) // loop forever
{
WaitNextTimeSlice();

if ((persist.UserData[WATCHDOG]) > 0) // If watch dog timer GT 0
// then still counting down
{
persist.UserData[WATCHDOG]--; // Decrement watchdog counter
if ((loop_delay--)<=0 )
{
ClearBit(KFLOP_LED46); // Every 30 loops, make sure led is off
loop_delay=30; // Reset loop delay
}
}

if (persist.UserData[WATCHDOG] <= 0 && loop_delay != 1000) // Keep alive died
// and not already "Estopped"
{
SetBit(KFLOP_LED46); // Light Estop LED
ClearBit(CCW_BIT); // Reset spindle direction bits
ClearBit(CW_BIT);
DAC(SPINDLE_DAC,0); // Turn off spindle power
loop_delay=1000; // Use loop_delay as "Estopped" indicator

}
}
Group: DynoMotion Message: 7799 From: Tom Kerekes Date: 6/28/2013
Subject: Re: hey tom, reply from my dad
Hey Matt's Dad & fellow old timer :}

That all makes sense and sounds reasonable.  I made some comments below in bold for future reference: