Am I doing this right? (component programming)

More
4 years 5 months ago #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?
Code:
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 to join the conversation.

More
4 years 5 months ago #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.

Please Log in to join the conversation.

More
4 years 5 months ago #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?
Code:
variable double timer; variable float on-delay = 1.0; //-------------------------------- //--------------------------------      timer += fperiod;      if(timer >= on_delay) {         //Do something now         timer = 0.0;     }

Please Log in to join the conversation.

More
4 years 5 months ago #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.

Please Log in to join the conversation.

More
4 years 5 months ago #241877 by andypugh
The way to do a time delay in a switch is to have a "waiting@ state
Code:
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

Please Log in to join the conversation.

Time to create page: 0.092 seconds
Powered by Kunena Forum