Am I doing this right? (component programming)

More
02 May 2022 12:10 #241843 by thewho
Hello

I'm writing my first own component to rotate the table/pallet in my machine.
So I'm looking for some guidance on formatting and syntax. And not really if my code will work as it's still under development and is untested.
  1. "function _ nofp;" I'm guessing this calls the "FUNCTION(_)" but what does the underscore do?
  2. " ;; " no idea what this is for??
  3. Line 41: Will this code show a popup in Axis?
  4. Line 42: How do I halt the code after an error occurred?
  5. General errors I've made?
component palletchange "Rotates pallets all day";
pin in bit tableIsUp;        //HW pin
pin in bit tableIsDown;        //HW pin
pin in bit tableIsCW;        //HW pin
pin in bit tableIsCCW;        //HW pin
pin in bit tableReady;        //SW pin
pin in bit tableRotate;        //SW pin
pin in bit enable;            //SW pin - Net to "machine-is-enabled"

pin out bit tableUp;
pin out bit tableDown;
pin out bit tableRotateCW;
pin out bit tableRotateCCW;
pin out bit tableAirblast;
pin out bit startHydPump;
pin out bit rotateDone;                            //1 if rotation completed successfully
pin out bit tableInMachine;                        //Return which  table is under the spindle

license "GPL";
author "D.E";


function _ nofp;
;;

bool tableIsReady;                                //Set 1 if tableReady button is pressed
FUNCTION(_) {
    if(enable){                                    
//-------------Check state of tableReady button-------------------------------
        if(tableReady && !tableIsReady){
            tableIsReady = 1;                    //Enable tableIsReady (physical buttonpress)
            while(tableReady){}                    //Halt program from continuing while button is pressed
        }
        else if(tableReady && tableIsReady){
            tableIsReady = 0;                    //Disable tableIsReady (physical button was pressed again)
            while(tableReady){}                    //Halt program from continuing while button is pressed
        }    
        
//-------------Send error message and halt program----------------------------    
        if(tableRotate && !tableReady){            //If a rotation is requested but table is not set to ready
            rtapi_print_msg(RTAPI_MSG_ERR, "Pallet not ready!");
            //exit program somehow?
        }
        
//-------------Everything is ok, rotate pallet--------------------------------            
        if(tableRotate){                        //Table rotate pin is high
            startHydPump =1;                    //Start hyd pump
            tableUp =1;                            //Lift table
            tableAirblast =1;                    //Turn on table airblast
            while(!tableIsUp){}                    //Do nothing while table is lifting (should have timeout..)
            if(tableIsCW){
                tableRotateCCW =1;                //Rotate table CCW
                while(!tableIsCCW){}            //Wait
                for(int i=0; i<1000; i++){}        //Wait 1 sec to let table reach rotation stop
                tableRotateCCW =0;                //Turn off output
                
            }
            else if{tableIsCCW){
                tableRotateCW =1;                //Rotate table CCW
                while(!tableIsCW){}                //Wait
                for(int i=0; i<1000; i++){}        //Wait 1 sec to let table reach rotation stop
                tableRotateCW =0;                //Turn off output    
            }
            tableUp =0;                            //Turn off output
            tableDown =1;                        //Lower table
            while(!tableIsDown){}                //Do nothing while table is lowering (should have timeout..)
            for(int i=0; i<1000; i++){}            //Wait 1 sec to let table settle
            tableDown =0;                        //Turn off output
            startHydPump =0;                    //Turn off output
            tableAirblast =0;                    //Turn off output
            tableIsReady = 0;                    //Set table to not ready
        }
    }
}

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

More
02 May 2022 12:37 #241846 by andypugh

"function _ nofp;" I'm guessing this calls the "FUNCTION(_)" but what does the underscore do?


The _ is used to indicate that the function does not have a name in HAL.
Often a component will have a read and a write (or some other multiple functions) and then you will see:
addf function.read servo-thread
addf function.make-pulses base-thread
etc.

In your case the function will just be called palletchange.

"nofp" means that the component does no floating-point calculations. Which is probably true in this case, but you can probably imit it for a component that runs in the servo thread.

Note that "addf" means that the component will be called every servo or base-thread period. More on that later.

" ;; " no idea what this is for??


It is used to split the bit of the file which is halcompile directives from the bit that is pure C-code.

Line 41: Will this code show a popup in Axis?


Yes

Line 42: How do I halt the code after an error occurred?
General errors I've made?


These are the same thing :-)

A realtime HAL component must never stop. It has to run through to completion in a very few microseconds or the entire system will lock up.

This also means "no while loops that depend on input" too. You have to be sure that loops will complete every time.

So, the normal way to code a HAL component is as a state machine. A variable (often set up as a HAL pin, so you can see what is happening) is used to tell the component what it was doing last time it was called.

See, as an example, the carousel.comp, specifically the main "switch" statement github.com/LinuxCNC/linuxcnc/blob/master...s/carousel.comp#L228
For example note that in state 0 (waiting) the system can move to states 1, 5 or 10. But that every state always runs straight through to completion.
The following user(s) said Thank You: thewho

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

More
02 May 2022 14:32 #241853 by thewho
Thank you Andy 
Ah, makes total sense that it needs to complete every time. I'll rewrite with switch instead.
So how do I do a "delay"? I did check the code for "timedelay.comp" but I can't really figure out how "fperiod" works? 
Am I on the right track with this?
variable double timer;
variable float on-delay = 1.0;
//--------------------------------

//--------------------------------
     timer += fperiod;

     if(timer >= on_delay) {
        //Do something now
        timer = 0.0;
    }

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

More
02 May 2022 18:16 #241862 by rodw
fperiod is a convenience macro that contains the time in seconds for this servo cycle.
Ref: linuxcnc.org/docs/devel/html/hal/comp.html#_convenience_macros
Do not use hyphens which are reserved for pin names. eg use time_delay.
time_delay could be a pin or parameter so it can be set in your hal file to be more universal.
Yes you are on the right track but I would ensure on_delay is initialised to 0.0 on declaration.
Why don't you make your timer example a complete component that turns a pin on and off every time_delay fperiods as a learning exercise? Something like this;
flash_pin |=1;
time_delay = 0.0;

Install it in your hal file and observe in halshow.
The following user(s) said Thank You: thewho

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

More
02 May 2022 20:20 #241877 by andypugh
The way to do a time delay in a switch is to have a "waiting@ state
switch (state){
...
case 11:
    if (something){
        state = 12; // waiting state
        timer = 10000; // how long to wait
    }
    break;
case 12:
    timer -= fperiod;
    if (timer > 0) break;
    // Here do things that are meant to happed when the timer expires. 
    // Should generally only be a change of state, just to keep things
    // obvious to future-you
The following user(s) said Thank You: thewho

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

Time to create page: 0.128 seconds
Powered by Kunena Forum