-
Notifications
You must be signed in to change notification settings - Fork 65
Customizing the HAL file
# SOME FUNCTIONALITIES ARE STILL IN CONSTRUCTION AND SHOULD NOT BE USED AS REFERENCE
# VERSION 1.4 CARRIES SEVERAL MODIFICATIONS THAT CHANGED THE WAY MODULES ARE CONFIGURED AND THIS PAGE HAS NOT BEEN FULLY UPDATED
Jump to section
Most µCNC HAL configurations can be customized via the Web Config Tool and it's the easiest way to go. Most (not all features) can be customized via this tool. If you can't find it in the web UI please refer to the source code files to perform the needed changes (mainly cnc_config.h and cnc_hal_config.h).
µCNC supports up to 2 simultaneous dual drive axis. This allows to enable self squaring with machine homming if the kinematics allows it (like in cartesian machines).
As stated up to 2 axis can be enabled with this feature.
This is set by enabling the following settings in cnc_hal_config.h
//this allows dual axis mode on axis X for example
#define ENABLE_DUAL_DRIVE_AXIS
#ifdef ENABLE_DUAL_DRIVE_AXIS
// defines the first dual drive capable axis
#define DUAL_DRIVE0_AXIS X
// by default this will be rewired to STEPPER6 (if available on the board)
// this can be uncommented to re-wire to an available (unused stepper other then 6)
#define DUAL_DRIVE0_STEPPER 3
// defines the first second drive capable axis
// #define DUAL_DRIVE1_AXIS Y
// by default this will be rewired to STEPPER7 (if available on the board)
// this can be uncommented to re-wire to an available (unused stepper other then 7)
// #define DUAL_DRIVE1_STEPPER 7
#endif
For each dual drive axis the respective STEPPER pins must be configured. (STEPPER6 -> AXIS0 and STEPPER7 -> AXIS1 are the default). This must be set on each individual boardmap file.
For homing purposes the second axis limit switch (if not already defined in the boardmap) needs to be configured too. For example with dual drive X you may need to configure the X2 limit switch pinout.
By default M1 will behave like M0. But it is possible to define condition for the program stopping like defined in the RS274NGC standard. This condition can be any thing that evaluates to a true or false condition. It can be the state of an input or output, a threshold of an analog input, or any internal condition. This will make M1 pause if the condition is meet.
Here are a couple of examples by adding a line to cnc_hal_config.h
:
//pauses the program if an M1 command is given and input DIN11 is high
#define M1_CONDITION_ASSERT (io_get_pinvalue(DIN11)!=0)
or
//pauses the program if an M1 command is given and output DOUT5 is low
#define M1_CONDITION_ASSERT (io_get_pinvalue(DOUT5)==0)
or
//pauses the program if an M1 command is given and analog input ANALOG0 is above 65
#define M1_CONDITION_ASSERT (io_get_pinvalue(ANALOG0)>65)
The encoder module is the simplest of the available modules. It can work as an directional encoder or a simple counter. It supports up two 8 encoders/counters. Each encoder is defined by PULSE pin and a DIR pin.
First you must make sure you have available pins on your board and they are configured properly. For each encoder you will need at least an ISR capable DIN pin (PIN0-7) and a directional PIN (preferably a non ISR pin line DIN8-15) if the encoder needs to work has a directional encoder. Go to your board file and map the pins you need. To configure your boardmap file read the customization page page. Depending on your board/MCU specific definitions may be needed.
To define 1 encoder open cnc_hal_config.h
first set the number of encoders to 1.
#define ENCODERS 1
This will enable ENC0
. If you set ENCODERS
to 2 you will enable ENC0
and ENC1
, and so on.
Next you need to set the PULSE and DIR pins by connecting them to a pair of DIN pins in the HAL.
Note: PULSE pin should be connected to a ISR capable DIN(0-7) pin and the ISR must be active for that pin
Note2: DIR pin should be connected to a non ISR capable DIN(8-16) pin
Note3: Both pins must be defined in the respective boardmap for your board file
Let's say you defined and ISR input pin with the name DIN7 and a non ISR input pin DIN 10. To assign them to them to encoder 0 insert the following lines
#define ENC0_PULSE DIN7
#define ENC0_DIR DIN10
That's it. Every time PULSE pin rises from low-high it will trigger the ISR and count up or down depending on the input value of the DIR pin. If this encoder keeping track of the STEPx motors that move the machine there is only one configuration to add. That is to link the encoder to the respective STEPx. Let's say ENC0 (encoder 0) keeps track of STEP1 position. Then add this line:
#define STEP1_ENCODER ENC0
This is needed so that the correspondent encoder is also reset along with the interpolator variable (for example during homing motions).
If you only need a direction independent counter you just need the ISR capable pin. You can assign both PULSE and DIR pins to the same board pin like this.
#define ENC0_PULSE DIN7
#define ENC0_DIR DIN7
This will make use of the encoder to count always in the same direction.
UNDER DEVELOPMENT
The PID module works by setting a definition for the DELTA (difference error between the expected value and the current value of the given PID system), the OUTPUT code to execute that receives a value (9bit- -255 to 255) to adjust the respective the system output and the STOP code that is executed if any failsafe detection triggers the machine to stop.
It supports up two 7 (of 8) PID controllers. When enabling PID controllers PID0 is always hardwired to the current tool PID callback. Each PID runs every log2(Total number of PID controllers)/1000 milliseconds PID_SAMP_FREQ
. Lower sampling frequencies can be defined also with a FREQ_DIV definition for each PID controller that can range from 1 (default value) to PID_SAMP_FREQ
milliseconds (that is the same as a sample rate of 1Hz).
Both PID OUTPUT, STOP and DELTA can be defined has a variable or function depending on the needs.
First you must make sure you have available pins on your board and they are configured properly for your setup (PWM, ANALOG, INPUTS, or even other modules like the encoder module).
To define 1 PID controller open cnc_hal_config.h
first set the number of PID controllers to 1.
#define PID_CONTROLLERS 1
This will enable PID0
. Remember PID0
is hardwired to the tool PID callback. If you set PID_CONTROLLERS
to 2 you will enable PID0
and PID1
, and so on. To effectively use additional PID controllers a PID_CONTROLLERS
with a value of 2 or more must be set.
This will also enable Kp, Kd and Ki settings. For PID0
they will be available via commands $200
, $201
and $202
. For ENC1
$210
, $211
and $212
, and so on.
Next you need to set the DELTA, OUTPUT and STOP to each PID controller in the HAL.
Let's look at some examples:
Example 1: A spindle PWM output (PWM0) with a closed loop feedback read from and ANALOG input (ANALOG0)
//compares the read spindle value to the programmed value
#define PID1_DELTA (io_get_analog(0) - itp_get_rt_spindle_pwm())
//readjusts the output value of the PWM with the PID adjust value (limited between 0 a 255)
#define PID1_OUTPUT(X) (io_set_pwm(PWM0, CLAMP(io_get_pwm(PWM0) + X, 0, 255));
//stops the spindle
#define PID1_STOP() (io_set_pwm(PWM0, 0));
//if not defined PID0_FREQ_DIV will be defined as 1 by default
//this will make the PID run every 5/PID_SAMP_FREQ seconds
#define PID1_FREQ_DIV 5
Example 2: A spindle PWM output (PWM0) with a closed loop feedback read from and encoder counter (ENC0)
//compares the read spindle rpm detected with ENC0 to the programmed value
//this the way to define a multiline macro (like a block of code)
#define PID1_DELTA ({ \
/* get's de encoder count absolute value and multiplies by 125Hz to convert to RPM*/ \
float rpm = (float)ABS(encoder_get_pos(0) * PID_SAMP_FREQ); \
/* resets the ENC0*/ \
encoder_reset_pos(0); \
/* returns the error between the actual RPM and the programmed RPM*/ \
(rpm - itp_get_rt_spindle()); \
})
//readjusts the output value of the PWM with the PID adjust value (limited between 0 a 255)
#define PID1_OUTPUT(X) (io_set_pwm(PWM0, CLAMP(io_get_pwm(PWM0) + X, 0, 255));
//stops the spindle
#define PID1_STOP() (io_set_pwm(PWM0, 0));
Example 3: STEP0 is not a stepper but a servo motor with encoder. The motor is controlled by 2 PWM (PWM0-foward and PWM1-backward) and a closed loop feedback read from and encoder position (ENC0) sampling @ 125Hz.
//compares the actual servo position with STEP0 position from the interpolator
#define PID1_DELTA (encoder_get_pos(0) - itp_get_rt_position_index(0))
//readjusts the output value of the servo motor
//this is the way to define a multiline macro
#define PID1_OUTPUT(X) ({\
if(X > 0) {io_set_pwm(PWM0, (uint8_t)X);io_set_pwm(PWM1, 0);/*moves forward*/} \
else if(X < 0) {io_set_pwm(PWM0, 0);io_set_pwm(PWM1, ((uint8_t)-X));/*moves backward*/} \
else {io_set_pwm(PWM0, 0);io_set_pwm(PWM1, 0);/*breaks*/} \
});
//stops the spindle
#define PID1_STOP() ({io_set_output(DOUT0, false);io_set_pwm(PWM0, 0);/*breaks*/});
Example 4: STEP0 is not a stepper but a servo motor with encoder. The motor is controlled by 1 PWM (PWM0) a DIR (DOUT0) and a closed loop feedback read from and encoder position (ENC0).
//compares the actual servo position with STEP0 position from the interpolator
#define PID2_DELTA (encoder_get_pos(0) - itp_get_rt_position_index(0))
//readjusts the output value of the servo motor
//this is the way to define a multiline macro
#define PID2_OUTPUT(X) ({\
if(X > 0) {io_set_output(DOUT0, false); io_set_pwm(PWM0, (uint8_t)X);/*moves forward*/} \
else if(X < 0) {io_set_output(DOUT0, true);io_set_pwm(PWM0, (uint8_t)(255-X));/*moves backward*/} \
else {io_set_output(DOUT0, false);io_set_pwm(PWM0, 0);/*breaks*/} \
});
//stops the spindle
#define PID1_STOP() ({io_set_output(DOUT0, false);io_set_pwm(PWM0, 0);/*breaks*/});
µCNC is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. µCNC is distributed WITHOUT ANY WARRANTY.
Also without the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
µCNC Wiki
- Home
- Basic user guide
- Porting µCNC and adding custom HAL
- Customizing the HAL file
- Adding custom Tools and Modules to µCNC
- FAQ
µCNC for ALL MCU
µCNC for AVR
µCNC for STM32F1 and STM32F4
µCNC for SAMD21
µCNC for ESP8266
µCNC for ESP32
µCNC for NXP LPC176x
µCNC for NXP RP2040