Skip to content

Commit

Permalink
Merge pull request #318 from bdring/Devt
Browse files Browse the repository at this point in the history
Devt
  • Loading branch information
bdring authored Feb 28, 2022
2 parents fe62f64 + 2cd93d9 commit 078e38e
Show file tree
Hide file tree
Showing 20 changed files with 119 additions and 57 deletions.
Binary file modified FluidNC/data/index.html.gz
Binary file not shown.
4 changes: 3 additions & 1 deletion FluidNC/src/Configuration/ParserHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace Configuration {
#endif
if (_parser.token_.indent_ > thisIndent) {
log_error("Skipping key " << _parser.key().str() << " indent " << _parser.token_.indent_ << " thisIndent "
<< thisIndent);
<< thisIndent);
} else {
#ifdef DEBUG_VERBOSE_YAML_PARSER
log_debug("Parsing key " << _parser.key().str());
Expand Down Expand Up @@ -102,6 +102,7 @@ namespace Configuration {
void item(const char* name, int32_t& value, int32_t minValue, int32_t maxValue) override {
if (_parser.is(name)) {
value = _parser.intValue();
constrain_with_message(value, minValue, maxValue);
}
}

Expand All @@ -120,6 +121,7 @@ namespace Configuration {
void item(const char* name, float& value, float minValue, float maxValue) override {
if (_parser.is(name)) {
value = _parser.floatValue();
constrain_with_message(value, minValue, maxValue);
}
}

Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/Kinematics/CoreXY.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ namespace Kinematics {
}

if (cycle_mask != 0) {
if (bitnum_is_true(cycle_mask, X_AXIS) || bitnum_is_true(cycle_mask, X_AXIS)) {
if (bitnum_is_true(cycle_mask, X_AXIS) || bitnum_is_true(cycle_mask, Y_AXIS)) {
log_error("CoreXY cannot single axis home X or Y axes");
// TODO: Set some Kinematics error or alarm
return true;
Expand Down
7 changes: 7 additions & 0 deletions FluidNC/src/Machine/Axes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ namespace Machine {
_sharedStepperDisable.report("Shared stepper disable");
}

if (_sharedStepperReset.defined()) {
_sharedStepperReset.setAttr(Pin::Attr::Output | Pin::Attr::InitialOn);
_sharedStepperReset.on();
_sharedStepperReset.report("Shared stepper reset");
}

unlock_all_motors();

// certain motors need features to be turned on. Check them here
Expand Down Expand Up @@ -189,6 +195,7 @@ namespace Machine {

void Axes::group(Configuration::HandlerBase& handler) {
handler.item("shared_stepper_disable_pin", _sharedStepperDisable);
handler.item("shared_stepper_reset_pin", _sharedStepperReset);

// Handle axis names xyzabc. handler.section is inferred
// from a template.
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/Machine/Axes.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace Machine {
inline char axisName(int index) { return index < MAX_N_AXIS ? _names[index] : '?'; } // returns axis letter

Pin _sharedStepperDisable;
Pin _sharedStepperReset;

int _numberAxis = 0;
Axis* _axis[MAX_N_AXIS];
Expand Down
5 changes: 3 additions & 2 deletions FluidNC/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,9 @@ void setup() {
sys.state = State::ConfigAlarm;
}

WebUI::wifi_config.begin();
WebUI::bt_config.begin();
if (!WebUI::wifi_config.begin()) {
WebUI::bt_config.begin();
}
WebUI::inputBuffer.begin();
allChannels.deregistration(&startupLog);
}
Expand Down
3 changes: 0 additions & 3 deletions FluidNC/src/Motors/RcServo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ namespace MotorDrivers {
// RcServo::RcServo(Pin pwm_pin) : Servo(), _pwm_pin(pwm_pin) {}

void RcServo::init() {
constrain_with_message(_pwm_freq, SERVO_PWM_FREQ_MIN, SERVO_PWM_FREQ_MAX);
constrain_with_message(_min_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX);
constrain_with_message(_max_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX);
if (_output_pin.undefined()) {
log_warn(" RC Servo disabled: No output pin");
_has_errors = true;
Expand Down
6 changes: 3 additions & 3 deletions FluidNC/src/Motors/RcServo.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ namespace MotorDrivers {
// Configuration handlers:
void group(Configuration::HandlerBase& handler) override {
handler.item("output_pin", _output_pin);
handler.item("pwm_hz", _pwm_freq);
handler.item("min_pulse_us", _min_pulse_us);
handler.item("max_pulse_us", _max_pulse_us);
handler.item("pwm_hz", _pwm_freq, SERVO_PWM_FREQ_MIN, SERVO_PWM_FREQ_MAX);
handler.item("min_pulse_us", _min_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX);
handler.item("max_pulse_us", _max_pulse_us, SERVO_PULSE_US_MIN, SERVO_PULSE_US_MAX);
}

// Name of the configurable. Must match the name registered in the cpp file.
Expand Down
6 changes: 0 additions & 6 deletions FluidNC/src/Motors/Solenoid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,6 @@
namespace MotorDrivers {

void Solenoid::init() {
constrain_with_message(_pwm_freq, (uint32_t)1000, (uint32_t)10000);
constrain_with_message(_off_percent, 0.0f, 100.0f);
constrain_with_message(_pull_percent, 0.0f, 100.0f);
constrain_with_message(_hold_percent, 0.0f, 100.0f);
constrain_with_message(_pull_ms, (uint32_t)0, (uint32_t)3000);

if (_output_pin.undefined()) {
log_warn(" Solenoid disabled: No output pin");
_has_errors = true;
Expand Down
10 changes: 5 additions & 5 deletions FluidNC/src/Motors/Solenoid.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ namespace MotorDrivers {
// Configuration handlers:
void group(Configuration::HandlerBase& handler) override {
handler.item("output_pin", _output_pin);
handler.item("pwm_hz", _pwm_freq);
handler.item("off_percent", _off_percent);
handler.item("pull_percent", _pull_percent);
handler.item("hold_percent", _hold_percent);
handler.item("pull_ms", _pull_ms);
handler.item("pwm_hz", _pwm_freq, 1000, 100000);
handler.item("off_percent", _off_percent, 0.0f, 100.0f);
handler.item("pull_percent", _pull_percent, 0.0f, 100.0f);
handler.item("hold_percent", _hold_percent, 0.0f, 100.0f);
handler.item("pull_ms", _pull_ms, 0, 3000);
handler.item("direction_invert", _dir_invert);
}

Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/Pins/I2SOPinDetail.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ namespace Pins {
Assert(value.validateWith(this->_capabilities), "Requested attributes do not match the I2SO pin capabilities");
Assert(!_attributes.conflictsWith(value), "Attributes on this pin have been set before, and there's a conflict.");

_attributes = value;
_attributes = _attributes | value;

// I2S out pins cannot be configured, hence there
// is nothing to do here for them. We basically
Expand Down
32 changes: 19 additions & 13 deletions FluidNC/src/ProcessSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,33 +358,39 @@ static Error home_c(const char* value, WebUI::AuthenticationLevel auth_level, Ch
static void write_limit_set(uint32_t mask, Channel& out) {
const char* motor0AxisName = "xyzabc";
for (int i = 0; i < MAX_N_AXIS; i++) {
out.write(bitnum_is_true(mask, i) ? char(motor0AxisName[i]) : ' ');
out << (bitnum_is_true(mask, i) ? char(motor0AxisName[i]) : ' ');
}
const char* motor1AxisName = "XYZABC";
for (int i = 0; i < MAX_N_AXIS; i++) {
out.write(bitnum_is_true(mask, i + 16) ? char(motor1AxisName[i]) : ' ');
out << (bitnum_is_true(mask, i + 16) ? char(motor1AxisName[i]) : ' ');
}
}
static Error show_limits(const char* value, WebUI::AuthenticationLevel auth_level, Channel& out) {
out.print("Send ! to exit\n");
out.print("Homing Axes: ");
write_limit_set(Machine::Axes::homingMask, out);
out.write('\n');
out.print("Limit Axes: ");
out << '\n';
out << "Limit Axes: ";
write_limit_set(Machine::Axes::limitMask, out);
out.write('\n');
out.print(" PosLimitPins NegLimitPins\n");
out << '\n';
out << " PosLimitPins NegLimitPins\n";
const TickType_t interval = 500;
TickType_t limit = xTaskGetTickCount();
do {
out.print(": "); // Prevents WebUI from suppressing an empty line
write_limit_set(Machine::Axes::posLimitMask, out);
out.write(' ');
write_limit_set(Machine::Axes::negLimitMask, out);
out.print("\r\n");
vTaskDelay(500); // Delay for a reasonable repeat rate
TickType_t thisTime = xTaskGetTickCount();
if (((long)(thisTime - limit)) > 0) {
out << ": "; // Prevents WebUI from suppressing an empty line
write_limit_set(Machine::Axes::posLimitMask, out);
out << ' ';
write_limit_set(Machine::Axes::negLimitMask, out);
out << '\n';
limit = thisTime + interval;
}
vTaskDelay(1);
pollChannels();
} while (!rtFeedHold);
rtFeedHold = false;
out.write('\n');
out << '\n';
return Error::Ok;
}
static Error go_to_sleep(const char* value, WebUI::AuthenticationLevel auth_level, Channel& out) {
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ bool can_park() {

void protocol_reset() {
probeState = ProbeState::Off;
soft_limit = false;
rtStatusReport = false;
rtCycleStart = false;
rtFeedHold = false;
Expand Down
2 changes: 1 addition & 1 deletion FluidNC/src/SDCard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ SDCard::State SDCard::test_or_open(bool refresh) {
}

SDCard::State SDCard::begin(SDCard::State newState) {
if (newState != SDCard::State::Idle && _state > SDCard::State::Idle) {
if (_state >= SDCard::State::Busy) {
return _state;
}
SDCard::State oldState = test_or_open(true);
Expand Down
3 changes: 1 addition & 2 deletions FluidNC/src/Spindles/Laser.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ namespace Spindles {
// pwm_freq is the only item that the PWM class adds to OnOff
// We cannot call PWM::group() because that would pick up
// direction_pin, which we do not want in Laser
handler.item("pwm_hz", _pwm_freq);

handler.item("pwm_hz", _pwm_freq, 1000, 100000);
OnOff::groupCommon(handler);
}

Expand Down
34 changes: 16 additions & 18 deletions FluidNC/src/Spindles/PWMSpindle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@

namespace Spindles {
void PWM::init() {
if (_pwm_freq == 0) {
log_error(name() << " PWM frequency is 0.");
return;
}

get_pins_and_settings();
setupSpeeds(_pwm_freq);

Expand Down Expand Up @@ -129,24 +124,27 @@ namespace Spindles {
ledcSetDuty(_pwm_chan_num, duty);
}

/*
Calculate the highest precision of a PWM based on the frequency in bits
80,000,000 / freq = period
determine the highest precision where (1 << precision) < period
*/
// Calculate the highest PWM precision in bits for the desired frequency
// 80,000,000 (APB Clock) = freq * maxCount
// maxCount is a power of two between 2^1 and 2^20
// frequency is at most 80,000,000 / 2^1 = 40,000,000, limited elsewhere
// to 20,000,000 to give a period of at least 2^2 = 4 levels of control.
uint8_t PWM::calc_pwm_precision(uint32_t freq) {
uint8_t precision = 0;
if (freq == 0) {
return precision;
freq = 1; // Limited elsewhere but just to be safe...
}

// increase the precision (bits) until it exceeds allow by frequency the max or is 16
while ((1u << precision) < uint32_t(80000000 / freq) && precision <= 16) {
precision++;
// Increase the precision (bits) until it exceeds the frequency
// The hardware maximum precision is 20 bits
const uint8_t ledcMaxBits = 20;
const uint32_t apbFreq = 80000000;
const uint32_t maxCount = apbFreq / freq;
for (uint8_t bits = 2; bits <= ledcMaxBits; ++bits) {
if ((1u << bits) > maxCount) {
return bits - 1;
}
}

return precision - 1;
return ledcMaxBits;
}

void PWM::deinit() {
Expand Down
14 changes: 13 additions & 1 deletion FluidNC/src/Spindles/PWMSpindle.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,19 @@ namespace Spindles {
void validate() const override { Spindle::validate(); }

void group(Configuration::HandlerBase& handler) override {
handler.item("pwm_hz", _pwm_freq);
// The APB clock frequency is 80MHz and the maximum divisor
// is 2^10. The maximum precision is 2^20. 80MHz/2^(20+10)
// is 0.075 Hz, or one cycle in 13.4 seconds. We cannot
// represent that in an integer so we set the minimum
// frequency to 1 Hz. Frequencies of 76 Hz or less use
// the full 20 bit resolution, 77 to 152 Hz uses 19 bits,
// 153 to 305 uses 18 bits, ...
// At the other end, the minimum useful precision is 2^2
// or 4 levels of control, so the max is 80MHz/2^2 = 20MHz.
// Those might not be practical for many CNC applications,
// but the ESP32 hardware can handle them, so we let the
// user choose.
handler.item("pwm_hz", _pwm_freq, 1, 20000000);

OnOff::group(handler);
}
Expand Down
5 changes: 5 additions & 0 deletions fluidterm/README-FluidTerm.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ Changes
You can restart the ESP32 to see the boot messages with the FluidNC **$bye** command or you can toggle the DTR function to restart most ESP32 modules by doing Ctrl+T Ctrl+D twice.

<img src="https://github.com/bdring/fluidterm/blob/main/images/screenshot_01.png" width="800" >

### Source Code

The source code for fluidterm.py (the Python version) is in this directory. The source code for
fluidterm.exe (the Windows native version) is at https://github.com/MitchBradley/FluidTerm2 .
Binary file modified fluidterm/fluidterm.exe
Binary file not shown.
39 changes: 39 additions & 0 deletions install_scripts/win64/HOWTO-INSTALL.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ name as below).
To install the WiFi version: install-wifi.bat
To install the Bluetooth version: install-bt.bat
To replace the ESP32 local filesystem: install-fs.bat
To erase everything on the ESP32: erase.bat
To just run FluidTerm: fluidterm.bat

### Erasing the ESP32

If your ESP32 already has other software on it, installing FluidNC
on top of that other software might not work right. You can get
rid of that other software with:

erase.bat

Then you can install FluidNC with install-* commands mentioned above.

### Local Filesystem Considerations

Replacing the local filesystem is only useful for the wifi
version, since its default contents are only needed for
Expand All @@ -35,3 +49,28 @@ it via WebUI from wifi/index.html.gz herein.

A good approach is to use install-fs only on your first
FluidNC installation, or to start from a clean slate.

### Running FluidTerm

FluidTerm is a simple serial terminal emulator program with a few
features specific to FluidNC - it can upload files and reset the ESP32.

The FluidNC install scripts run FluidTerm automatically at the end,
but if you want to run it separately, you can type

fluidterm.bat

### Alternatives to FluidTerm

Most GCode sender programs have some way to send commands directly to
FluidNC, but it can sometimes be helpful to bypass the complexity of
a sender and use a more direct path. FluidTerm is one such direct
path, but there are others, typically called "serial terminals".

For Windows, there are many such programs, such as "PuTTY" and
"TeraTerm Pro". None are preinstalled by default, but you can
download one from the internet. Setting one up requires that
you know which COM port is for the ESP32, the baud rate (115200),
and some other settings - no hardware or software flow control,
accept linefeed as end-of-line on input, etc. FluidTerm tried
to make it easy for you by using all the correct defaults.

0 comments on commit 078e38e

Please sign in to comment.