1
0
mirror of https://github.com/bdring/Grbl_Esp32.git synced 2025-09-09 13:50:51 +02:00

Changed RPM from float to unit32_t

- This removes a lot of realtime float math
- Do we want an offset so 100.5 is OK? What about 0.5?
This commit is contained in:
bdring
2020-05-04 07:32:24 -05:00
parent a5b0eb2c76
commit 44baed18c4
8 changed files with 83 additions and 72 deletions

View File

@@ -84,14 +84,15 @@ void BESCSpindle :: config_message() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "BESC spindle on Pin:%d", _output_pin);
}
float BESCSpindle::set_rpm(float rpm) {
uint32_t BESCSpindle::set_rpm(uint32_t rpm) {
uint32_t pwm_value;
if (_output_pin == UNDEFINED_PIN)
return rpm;
// apply speed overrides
rpm *= (0.010 * sys.spindle_speed_ovr); // Scale by spindle speed override value (percent)
//rpm *= (0.010 * sys.spindle_speed_ovr); // Scale by spindle speed override value (percent)
rpm = rpm * sys.spindle_speed_ovr / 100; // Scale by spindle->speed override value (percent)
// apply limits limits
if ((_min_rpm >= _max_rpm) || (rpm >= _max_rpm)) {
@@ -106,7 +107,7 @@ float BESCSpindle::set_rpm(float rpm) {
if (rpm == 0.0) {
pwm_value = _pwm_off_value;
} else {
pwm_value = (uint16_t)map_float(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
pwm_value = map_uint32_t(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
}
#ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED

View File

@@ -56,7 +56,7 @@ void DacSpindle :: config_message() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "DAC spindle on Pin:%d", _output_pin);
}
float DacSpindle::set_rpm(float rpm) {
uint32_t DacSpindle::set_rpm(uint32_t rpm) {
if (_output_pin == UNDEFINED_PIN)
return rpm;
@@ -65,7 +65,8 @@ float DacSpindle::set_rpm(float rpm) {
//grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Set RPM %5.1f", rpm);
// apply overrides and limits
rpm *= (0.010 * sys.spindle_speed_ovr); // Scale by spindle speed override value (percent)
//rpm *= (0.010 * sys.spindle_speed_ovr); // Scale by spindle speed override value (percent)
rpm *= rpm * sys.spindle_speed_ovr / 100; // Scale by spindle->speed override value (percent)
// Calculate PWM register value based on rpm max/min settings and programmed rpm.
if ((_min_rpm >= _max_rpm) || (rpm >= _max_rpm)) {
@@ -87,7 +88,7 @@ float DacSpindle::set_rpm(float rpm) {
// NOTE: A nonlinear model could be installed here, if required, but keep it VERY light-weight.
sys.spindle_speed = rpm;
pwm_value = (uint32_t)map_float(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
pwm_value = map_uint32_t(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
}
#ifdef SPINDLE_ENABLE_OFF_WITH_ZERO_SPEED

View File

@@ -134,7 +134,7 @@ void HuanyangSpindle :: config_message() {
0x01 0x03 0x01 0x08 0xF1 0x8E Stop spindle
0x01 0x03 0x01 0x11 0x30 0x44 Start spindle counter-clockwise
*/
void HuanyangSpindle :: set_state(uint8_t state, float rpm) {
void HuanyangSpindle :: set_state(uint8_t state, uint32_t rpm) {
if (sys.abort)
return; // Block during abort.
@@ -192,14 +192,15 @@ bool HuanyangSpindle :: get_response(uint16_t length) {
ADDR CMD LEN DATA CRC
0x01 0x05 0x02 0x09 0xC4 0xBF 0x0F Write Frequency (0x9C4 = 2500 = 25.00HZ)
*/
float HuanyangSpindle :: set_rpm(float rpm) {
uint32_t HuanyangSpindle :: set_rpm(uint32_t rpm) {
// TODO add in all the speed modifiers, like override and linearization
char msg[7] = {HUANYANG_ADDR, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00};
// add data (rpm) bytes
uint16_t data = uint16_t(rpm / 60.0 * 100.0); // send Hz * 10 (Ex:1500 RPM = 25Hz .... Send 2500)
//uint16_t data = uint16_t(rpm / 60.0 * 100.0); // send Hz * 10 (Ex:1500 RPM = 25Hz .... Send 2500)
uint16_t data = uint16_t(rpm * 100 / 60); // send Hz * 10 (Ex:1500 RPM = 25Hz .... Send 2500)
msg[3] = (data & 0xFF00) >> 8;
msg[4] = (data & 0xFF);

View File

@@ -1,7 +1,7 @@
/*
NullSpindle.cpp
This is used when you don't want to use a spindle. No I/O will be used
This is used when you don't want to use a spindle-> No I/O will be used
and most methods don't do anything
Part of Grbl_ESP32
@@ -26,10 +26,10 @@ void NullSpindle :: init() {
is_reversable = false;
config_message();
}
float NullSpindle :: set_rpm(float rpm) {
uint32_t NullSpindle :: set_rpm(uint32_t rpm) {
return rpm;
}
void NullSpindle :: set_state(uint8_t state, float rpm) {}
void NullSpindle :: set_state(uint8_t state, uint32_t rpm) {}
uint8_t NullSpindle :: get_state() {
return (SPINDLE_STATE_DISABLE);
}

View File

@@ -1,7 +1,7 @@
/*
PWMSpindle.cpp
This is a full featured TTL PWM spindle. This does not include speed/power
This is a full featured TTL PWM spindle-> This does not include speed/power
compensation. Use the Laser class for that.
Part of Grbl_ESP32
@@ -22,11 +22,11 @@
// ======================= PWMSpindle ==============================
/*
This gets called at startup or whenever a spindle setting changes
If the spindle is running it will stop and need to be restarted with M3Snnnn
This gets called at startup or whenever a spindle->setting changes
If the spindle->is running it will stop and need to be restarted with M3Snnnn
*/
void PWMSpindle::init() {
void PWMSpindle :: init() {
get_pins_and_settings();
if (_output_pin == UNDEFINED_PIN) {
@@ -69,7 +69,7 @@ void PWMSpindle :: get_pins_and_settings() {
#endif
is_reversable = (_direction_pin != UNDEFINED_PIN);
_pwm_freq = settings.spindle_pwm_freq;
_pwm_freq = (uint32_t)settings.spindle_pwm_freq;
_pwm_precision = calc_pwm_precision(_pwm_freq); // detewrmine the best precision
_pwm_period = (1 << _pwm_precision);
@@ -77,51 +77,52 @@ void PWMSpindle :: get_pins_and_settings() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Warning: Spindle min pwm is greater than max. Check $35 and $36");
// pre-caculate some PWM count values
_pwm_off_value = (_pwm_period * settings.spindle_pwm_off_value / 100.0);
_pwm_min_value = (_pwm_period * settings.spindle_pwm_min_value / 100.0);
_pwm_max_value = (_pwm_period * settings.spindle_pwm_max_value / 100.0);
_pwm_off_value = (_pwm_period * (uint32_t)settings.spindle_pwm_off_value / 100.0);
_pwm_min_value = (_pwm_period * (uint32_t)settings.spindle_pwm_min_value / 100.0);
_pwm_max_value = (_pwm_period * (uint32_t)settings.spindle_pwm_max_value / 100.0);
#ifdef ENABLE_PIECEWISE_LINEAR_SPINDLE
_min_rpm = RPM_MIN;
_max_rpm = RPM_MAX;
#else
_min_rpm = settings.rpm_min;
_max_rpm = settings.rpm_max;
_min_rpm = (uint32_t)settings.rpm_min;
_max_rpm = (uint32_t)settings.rpm_max;
#endif
// The pwm_gradient is the pwm duty cycle units per rpm
_pwm_gradient = (_pwm_max_value - _pwm_min_value) / (_max_rpm - _min_rpm);
// _pwm_gradient = (_pwm_max_value - _pwm_min_value) / (_max_rpm - _min_rpm);
_spindle_pwm_chan_num = 0; // Channel 0 is reserved for spindle use
_spindle_pwm_chan_num = 0; // Channel 0 is reserved for spindle->use
}
float PWMSpindle::set_rpm(float rpm) {
uint32_t PWMSpindle::set_rpm(uint32_t rpm) {
uint32_t pwm_value;
if (_output_pin == UNDEFINED_PIN)
return rpm;
// apply override
rpm *= (0.010 * sys.spindle_speed_ovr); // Scale by spindle speed override value (percent)
//rpm *= (0.010 * sys.spindle->speed_ovr); // Scale by spindle->speed override value (percent)
rpm = rpm * sys.spindle_speed_ovr / 100; // Scale by spindle->speed override value (percent)
// apply limits
if ((_min_rpm >= _max_rpm) || (rpm >= _max_rpm)) {
rpm = _max_rpm;
} else if (rpm != 0.0 && rpm <= _min_rpm) {
} else if (rpm != 0 && rpm <= _min_rpm) {
rpm = _min_rpm;
}
sys.spindle_speed = rpm;
sys.spindle_speed = (float)rpm;
#ifdef ENABLE_PIECEWISE_LINEAR_SPINDLE
pwm_value = piecewise_linear_fit(rpm);
#else
// Calculate PWM register value based on rpm max/min settings and programmed rpm.
if (rpm == 0.0) {
if (rpm == 0) {
pwm_value = _pwm_off_value;
} else {
pwm_value = (uint16_t)map_float(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
pwm_value = map_uint32_t(rpm, _min_rpm, _max_rpm, _pwm_min_value, _pwm_max_value);
}
#endif
@@ -134,11 +135,11 @@ float PWMSpindle::set_rpm(float rpm) {
return rpm;
}
void PWMSpindle::set_state(uint8_t state, float rpm) {
void PWMSpindle::set_state(uint8_t state, uint32_t rpm) {
if (sys.abort)
return; // Block during abort.
if (state == SPINDLE_DISABLE) { // Halt or set spindle direction and rpm.
if (state == SPINDLE_DISABLE) { // Halt or set spindle->direction and rpm.
sys.spindle_speed = 0.0;
stop();
} else {
@@ -171,14 +172,16 @@ void PWMSpindle::stop() {
set_output(_pwm_off_value);
}
// prints the startup message of the spindle config
// prints the startup message of the spindle->config
void PWMSpindle :: config_message() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "PWM spindle on Pin:%d, Freq:%.2fHz, Res:%dbits", _output_pin, _pwm_freq, _pwm_precision);
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "PWM spindle on Pin:%d, Freq:%dHz, Res:%dbits", _output_pin, _pwm_freq, _pwm_precision);
}
void PWMSpindle::set_output(uint32_t duty) {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Duty %d", duty);
if (_output_pin == UNDEFINED_PIN)
return;
@@ -189,7 +192,7 @@ void PWMSpindle::set_output(uint32_t duty) {
_current_pwm_duty = duty;
#ifdef INVERT_SPINDLE_PWM
duty = (1 << settings.spindle_pwm_precision_bits) - duty;
duty = (1 << settings.spindle->pwm_precision_bits) - duty;
#endif
ledcWrite(_spindle_pwm_chan_num, duty);
}
@@ -216,10 +219,10 @@ void PWMSpindle::set_spindle_dir_pin(bool Clockwise) {
80,000,000 / freq = period
determine the highest precision where (1 << precision) < period
*/
uint8_t PWMSpindle :: calc_pwm_precision(float freq) {
uint8_t PWMSpindle :: calc_pwm_precision(uint32_t freq) {
uint8_t precision = 0;
while ((1 << precision) < (uint32_t)(80000000.0 / freq) && precision <= 16)
while ((1 << precision) < (uint32_t)(80000000 / freq) && precision <= 16)
precision++;
return precision - 1;

View File

@@ -1,8 +1,8 @@
/*
RelaySpindle.cpp
This is used for a basic on/off spindle. All S Values about 1
will turn the spindle on.
This is used for a basic on/off spindle-> All S Values about 1
will turn the spindle->on.
Part of Grbl_ESP32
2020 - Bart Dring
@@ -22,7 +22,7 @@
// ========================= RelaySpindle ==================================
/*
This is the same as a PWM spindle, but is a digital rather than PWM output
This is the same as a PWM spindle-> but is a digital rather than PWM output
*/
void RelaySpindle::init() {
get_pins_and_settings();
@@ -43,12 +43,12 @@ void RelaySpindle::init() {
config_message();
}
// prints the startup message of the spindle config
// prints the startup message of the spindle->config
void RelaySpindle :: config_message() {
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Relay spindle on Pin:%d", _output_pin);
grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "Relay spindle->on Pin:%d", _output_pin);
}
float RelaySpindle::set_rpm(float rpm) {
uint32_t RelaySpindle::set_rpm(uint32_t rpm) {
if (_output_pin == UNDEFINED_PIN)
return rpm;

View File

@@ -3,7 +3,7 @@
A Spindle Class
Spindle - A base class. Do not use
PWMSpindle - A spindle with a PWM output
PWMSpindle - A spindle->with a PWM output
RelaySpindle - An on/off only spindle
Laser - Output is PWM, but the M4 laser power mode can be used
DacSpindle - Uses the DAC to output a 0-3.3V output
@@ -40,6 +40,7 @@
#include "HuanyangSpindle.cpp"
#include "BESCSpindle.cpp"
NullSpindle null_spindle;
PWMSpindle pwm_spindle;
RelaySpindle relay_spindle;
@@ -48,8 +49,9 @@ DacSpindle dac_spindle;
HuanyangSpindle huanyang_spindle;
BESCSpindle besc_spindle;
void spindle_select(uint8_t spindle_type) {
void spindle_select(uint8_t spindle_type) {
switch (spindle_type) {
case SPINDLE_TYPE_PWM:
spindle = &pwm_spindle;
@@ -74,9 +76,11 @@ void spindle_select(uint8_t spindle_type) {
spindle = &null_spindle;
break;
}
spindle->init();
}
void spindle_read_prefs(Preferences& prefs) {
uint8_t foo = prefs.getUChar("SPIN_TYPE", SPINDLE_TYPE_PWM);
}
@@ -84,12 +88,12 @@ void spindle_read_prefs(Preferences& prefs) {
bool Spindle::isRateAdjusted() {
return false; // default for basic spindles is false
return false; // default for basic spindle-> is false
}
void Spindle :: spindle_sync(uint8_t state, float rpm) {
void Spindle :: spindle_sync(uint8_t state, uint32_t rpm) {
if (sys.state == STATE_CHECK_MODE)
return;
protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle is set when programmed.
protocol_buffer_synchronize(); // Empty planner buffer to ensure spindle->is set when programmed.
set_state(state, rpm);
}

View File

@@ -48,24 +48,24 @@
class Spindle {
public:
virtual void init(); // not in constructor because this also gets called when $$ settings change
virtual float set_rpm(float rpm);
virtual void set_state(uint8_t state, float rpm);
virtual uint32_t set_rpm(uint32_t rpm);
virtual void set_state(uint8_t state, uint32_t rpm);
virtual uint8_t get_state();
virtual void stop();
virtual void config_message();
virtual bool isRateAdjusted();
virtual void spindle_sync(uint8_t state, float rpm);
virtual void spindle_sync(uint8_t state, uint32_t rpm);
bool is_reversable;
};
// This is a dummy spindle that has no I/O.
// It is used to ignore spindle commands when no spinde is desired
// This is a dummy spindle->that has no I/O.
// It is used to ignore spindle->commands when no spinde is desired
class NullSpindle : public Spindle {
public:
void init();
float set_rpm(float rpm);
void set_state(uint8_t state, float rpm);
uint32_t set_rpm(uint32_t rpm);
void set_state(uint8_t state, uint32_t rpm);
uint8_t get_state();
void stop();
void config_message();
@@ -75,8 +75,8 @@ class NullSpindle : public Spindle {
class PWMSpindle : public Spindle {
public:
void init();
virtual float set_rpm(float rpm);
void set_state(uint8_t state, float rpm);
virtual uint32_t set_rpm(uint32_t rpm);
void set_state(uint8_t state, uint32_t rpm);
uint8_t get_state();
void stop();
void config_message();
@@ -87,8 +87,8 @@ class PWMSpindle : public Spindle {
void set_spindle_dir_pin(bool Clockwise);
protected:
float _min_rpm;
float _max_rpm;
uint32_t _min_rpm;
uint32_t _max_rpm;
uint32_t _pwm_off_value;
uint32_t _pwm_min_value;
uint32_t _pwm_max_value;
@@ -96,28 +96,28 @@ class PWMSpindle : public Spindle {
uint8_t _enable_pin;
uint8_t _direction_pin;
int8_t _spindle_pwm_chan_num;
float _pwm_freq;
uint32_t _pwm_freq;
uint32_t _pwm_period; // how many counts in 1 period
uint8_t _pwm_precision;
float _pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
//uint32_t _pwm_gradient; // Precalulated value to speed up rpm to PWM conversions.
virtual void set_output(uint32_t duty);
void set_enable_pin(bool enable_pin);
void get_pins_and_settings();
uint8_t calc_pwm_precision(float freq);
uint8_t calc_pwm_precision(uint32_t freq);
};
// This is for an on/off spindle all RPMs above 0 are on
// This is for an on/off spindle->all RPMs above 0 are on
class RelaySpindle : public PWMSpindle {
public:
void init();
void config_message();
float set_rpm(float rpm);
uint32_t set_rpm(uint32_t rpm);
protected:
void set_output(uint32_t duty);
};
// this is the same as a PWM spindle, but the M4 compensation is supported.
// this is the same as a PWM spindle-> but the M4 compensation is supported.
class Laser : public PWMSpindle {
public:
bool isRateAdjusted();
@@ -129,7 +129,7 @@ class DacSpindle : public PWMSpindle {
public:
void init();
void config_message();
float set_rpm(float rpm);
uint32_t set_rpm(uint32_t rpm);
private:
bool _gpio_ok; // DAC is on a valid pin
protected:
@@ -140,9 +140,9 @@ class HuanyangSpindle : public Spindle {
public:
void init();
void config_message();
virtual void set_state(uint8_t state, float rpm);
void set_state(uint8_t state, uint32_t rpm);
uint8_t get_state();
float set_rpm(float rpm);
uint32_t set_rpm(uint32_t rpm);
void stop();
private:
@@ -162,10 +162,11 @@ class BESCSpindle : public PWMSpindle {
public:
void init();
void config_message();
float set_rpm(float rpm);
uint32_t set_rpm(uint32_t rpm);
};
extern Spindle* spindle;
extern Spindle *spindle;
extern NullSpindle null_spindle;
extern PWMSpindle pwm_spindle;
@@ -175,7 +176,7 @@ extern DacSpindle dac_spindle;
extern HuanyangSpindle huanyang_spindle;
extern BESCSpindle besc_spindle;
void spindle_select(uint8_t spindle_type);
void spindle_select(uint8_t spindletype);
void spindle_read_prefs(Preferences& prefs);
#endif