Toolchanger HAL Component project

03 Jan 2023 18:14 - 08 Jan 2023 18:33 #260861 by smc.collins
I am designing a new hal component dedicated specifically to control the carousel or belt style tool changers. My first draft is below, it will have significant modifications made to it shortly. 

Problems this is attempting to solve;

1. configuring toolchangers with current hal components, is a big pain in the ass
2. the configuration process is difficult and buggy, multiple places for failures and errors
3. the current solutions available all require a lot of hoop jumping, working in multiple languages and dealing with lots of hal pins and files

Goals and Solutions:

1. design a flexible block execution,  stair case logic motion control routine
2. include popular most popular position decoding needs
3. include jog function with forward and reverse
4. include homing feature
5. make design exestensible


1. the real time API is difficult to work with
2. I have to focus my efforts on making my machine work, but I can post my work here for others to contribute of make derivative work
3. community engagement is very low in hard projects for the most part, and this is one of the biggest obstacles to refits


having a generic flexible toolchanger component for carousel and belt tool changers will improve the acess to EMC2 in general. This will likely reduce people bailing out and also help reduce the support work load on the community forum and free up man power for solving other problems. Like redesigning the RTapi in a more sane multithreaded way that uses a watchdog execution system and allows for worker threads. So that the code complexity can be reduced by using while loops etc or brining halcompile to the world or rust or c++ or a million other things that could be getting done that aren't because many of the people who can do them are burnt out or tied up answering the same questions on the forums etc. 

Also reduce new user frustration greatly. This is not going to be a easy project, and I expect at least 40 days of really hard mid night oil burning to get a basic component program working. But I will start a github page and post a link tomorrow when I have a few hours to setup git.
What can you do, well, you can post up pictures and document how your toolchanger works mechanically and electrically. this is very important knowledge, the more info at the begging of this process, the easier it will be to create a more universal toolchanger component. It may end up that derivatives of this component will need to be made, but trying to cover 80% of machines first go is the broad goal but I will settle for my machine working and as many as I can make work in the meantime. 

Have a great weekend, and peace out   
Last edit: 08 Jan 2023 18:33 by smc.collins.

Please Log in or Create an account to join the conversation.

04 Jan 2023 22:38 - 08 Jan 2023 18:49 #260972 by smc.collins
could someone update the thread topic please !

Last edit: 08 Jan 2023 18:49 by smc.collins.
The following user(s) said Thank You: billykid

Please Log in or Create an account to join the conversation.

08 Jan 2023 21:09 #261305 by smc.collins
I hope a moderator renames this thread. if anyone is wondering I HATE underscores, they are awkward to type and I find them obnoxious to deal with later in the code particularly in the hal file pin naming, Camel Case Is More Natural To Type and you follow each instance with a Number it is easier to read and type. I will be using the Haiku Operating system coding guidelines for the most part, I find them functional and easy to read, but deviate where I feel it necassary or convenient for me. 

This VariableIsEasyToName1

Step 1. design a block of reusable code, that does 4 basic things 

1. read a input, compares values and commands an output, 
2. can error check itself in multiple ways
3. can be accurately sequenced 
4. is inexpensive to execute we have time deadlines to meet. 

here is that block 

1. need a timer to control the pac of the executions for some outputs 
param rw float FunctionTimer0 = 0.0 " variable for timer control";
pin in float FunctionTimer0Value = 1.00 in seconds;
2. we need a watchdog to ensure the execution doesn't take to long 
param rw float WatchDogTimer0 = 0.0 " variable for timer control";
3. we need a execution system to control code flow. as we enter the next block in Count2, we will set the True to False and clear the execution block from falling through as is SO problematic with execution loop. 
pin out bit Count1 = false;

then we end up with this code block here with the above control variables in the hal component, this is the turret unlock routine out of my Cincinnati Lathe turret component. The plan is to refactor this into a generic block that cane be configured in the hal file. The question I have is, what are the most common types of tool changer configurations ? how many steps are there in each direction to and from the storage magazine to the spindle and back ? I am thinking I might just set this up with 10 blocks in each direction ?? I think that should cover it and then make the variables for the block numbers accessible in the hal file. 

If anyone has a better alternative approach to this, lmk, I am open to idea and the code is kinda in a very amorphous state. 

There is a lot happening in this block of code, execution control flags, error flags, diagnostic timeouts and messages etc. This prototype will serve as the basis for constructing the Toolchanger.comp file and program. unless someone has a better idea. The parts of other components like carousel etc could be integrated into this to reduce more hal wiring, which IMHO is a good idea. Better to debug in one place then 100

if (count1 == true){ // unlock and count1 start this timer 
timer0  +=  fperiod; // timer is incremented by fperoid 
count2_5 = true; // start timer for turret watchdog

if (timer0 > unlockpause && toolchanger == true){ // 1 second unlock pause
   count2 = true; // move flow control forward
   count1 = false; // flow control rest at start of routine
   timer0 = 0; // clear timer to clean up 


// turret unlock time watchdog system  make sure turret unlocks in reasonable amount of time

if (count2_5 == true && unlock == true  ){ // unlock and count2 start this timer 
timer1  +=  fperiod; // timer is incremented by fperoid 

if (timer1 > unlocktimeout && unlock == true){ // if timer1 is greater then unlocktimeout setting and toolchange is true 
   count2_5 = true; // flow control rest at start of routine

if (timer1 < unlocktimeout && unlock == true){
count3 = true;

if (count2_5 == true && timer1 > unlocktimeout) { // just changing the timer name, becuase memory leaks
        unlock = false; // disable motor
        toolchanger = false; // top toolchange code flow 
    count100 = true; // set this error flag
        estop = true; // disable machine
        count2_5 = false;                          // cancel timer
        if (set_warn_flag12 == false){ // block repetitive error messages they are annoying and flood the system
            set_warn_flag12 = true; // set flag to block prinint excesive error messages
            counterT = 105; // diagnostic counter if the program hang use this in halscope to capture the value when it does, at least you got a shot 
}  // diagnosing the problem

Please Log in or Create an account to join the conversation.

09 Jan 2023 01:53 #261321 by tommylight

I hope a moderator renames this thread.

Gladly, to what? This:
Dedicated Hurco carousel component BMC SLV 80-90s vintage maybe others
The following user(s) said Thank You: smc.collins

Please Log in or Create an account to join the conversation.

09 Jan 2023 20:32 #261379 by smc.collins
Toolchanger HAL Component project, to more accurately reflect what the goal here is

Please Log in or Create an account to join the conversation.

10 Jan 2023 00:04 #261395 by tommylight
Thank you.
The following user(s) said Thank You: smc.collins

Please Log in or Create an account to join the conversation.

10 Jan 2023 02:06 - 10 Jan 2023 02:10 #261405 by smc.collins
So one of the problems, with hard switch logic that iterates every single loop, is switch input noise. working within the constraints of halcompile , the linuxcnc rtapi behavior I have observed and the compiler and the code that it generates, I devised this after some trial and error for input filtering.

I plan to implement all the variables as params and io but the current variable naming is essentially there for discussion.

If anyone see's any obvious ways to improve this I am open to the idea. As you can see the camel case naming makes spotting and reading variable names much easier !

bool SwitchUF = false; // unfiltered input
bool SwitchFT = false; // filtered output
bool TimerFlag = false; // to control buffer counter
int float FilterBuffer = 0; // default state of buffer
int float TimerBuffer = 0; // timer

if ( SwitchUF != SwitchFT ){
Buffer += feriod * 100;
TimerFlag = true;

If (TimerFlag = true){
Timer1 += fperiod *100;

If (SwitchUF == true && (buffer / 10 >= 1.2) && (buffer <= timer1)){
SwitchFT = True;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;
} else {
if (SwitchUF == true || false && (Buffer / 10) <= 0.7 && (Buffer < Timer1)) {
SwitchFT = false;
Timer1 = 0;
Buffer = 0;
TimerFlag = false;

Last edit: 10 Jan 2023 02:10 by smc.collins.

Please Log in or Create an account to join the conversation.

10 Jan 2023 22:17 - 12 Jan 2023 17:28 #261502 by smc.collins
I wrote a new filter algorythm, it is much simpler than my previous attempts and it acts as a debounce and rolling average filter. will post tommorow once I do a bit more debugging on it.

Got a little bit of coding done tonight. Long way to go still but I already flushed out a good bit of the needed code in the other file above. I will start merging these together soon.

I propose, Block, it can be copied and pasted relatively easily, uses a very flat construction idea and includes a error state and execution watch timer. More to come. It will be a part of the toolchanger, but it does a bunch of things. Creates the first way to adress logic steps, integrates 2 timers, and turns on a output based on inputs and conditional variables etc.
Last edit: 12 Jan 2023 17:28 by smc.collins.

Please Log in or Create an account to join the conversation.

11 Jan 2023 18:30 - 12 Jan 2023 17:28 #261605 by smc.collins
filtering pocket values, versus de-bouncing the switches, both have trade offs, if there is a machine with a lot of input switches, pocket filtering is probably a better solution. This little snippet is working well in my applications, it starts a debounce timer and then it uses a rolling average incremented  and decremented by the pocket boolean value  changing. this works well so far in testing, the variables are adjustable to.

in this configuration, the timer period is 10 msec, and if the switch is false it subtracts from the filter and if the switch is positive is increments the filter, the pocket number change can only be true if for 10 consecutive cycles the switch is either true or false. other wise the output will have to wait until one of them is true and as they can botr change the value from -10 to 0 to 10, it creates a weighted average based in input switch time. Think of it as duty cycle in 10% increments. once the duty cycle is -100% or +100%   and the timer is greater than10 fperiod loops, then it updates the pocket number or it doesn't. better than a simple timer, avoids crazy filtering algorithms and solves noisy input problems, needs a watchdog timeout added for the case where the primary timer is greater than 250msec or some  type of value , then fault out with a error for switch input noisy etc.  

if (PocketFilterFlag == true){ // is flag true to start comparison value count
PocketFilter += fperiod; // set in milliseconds

if (pocketunfiltered != pocket){ // set flags and start comparison operator for new pocket value
timer8 = 0;
timer8 += fperiod; // increment timer in milliseconds
PocketFilterFlag = true; // set the flag
if (pocketunfiltered == pocket){ // cancel if pocket and pockunfiltered are the same and supress timer
timer8 -= fperiod; // flush timer

if (PocketFilter >= timer8){ // set new pocket value if the pocket value is euqal to or greater than unfiltered for more than 10 milliseconds consecutively
pocket = pocketunfiltered; // set pocket value
PocketFilterFlag = false; // clear flag
timer8 = 0; // flush timer

Last edit: 12 Jan 2023 17:28 by smc.collins.

Please Log in or Create an account to join the conversation.

12 Jan 2023 19:01 - 13 Jan 2023 03:46 #261725 by smc.collins
Day3 of program build, I will need some folks to help debug and test code soon, if you know C or C or really any programming language, the help will be needed, this is going to be a 3000 line program most likely.  I am trying to reusue as much debugged logic as I can to prevent bugs. a good bit of boiler plate and variable naming modification. the main portion of the control logic is flushed out, and because most all of it is the same, debugging 1 blocks fixes ALL of the execution blocks. Next up, I need to think on how to get from the end of the block to the tool changer and back again. I can get to the carousel but I need to think about how I am going to get back from the carousel pocket to the logic blocks. Need a day or so to think on that one. Feedback wanted if available. I will get started on a hal file shortly so people can experiment if they want to. 
Last edit: 13 Jan 2023 03:46 by smc.collins.

Please Log in or Create an account to join the conversation.

Time to create page: 0.155 seconds
Powered by Kunena Forum