Skip to content

Commit

Permalink
Merge pull request #948 from bdring/WebSocketsNoStall
Browse files Browse the repository at this point in the history
Web sockets no stall
  • Loading branch information
MitchBradley authored Jul 12, 2023
2 parents 6121cc7 + 6fb359a commit 4704b8c
Show file tree
Hide file tree
Showing 20 changed files with 187 additions and 124 deletions.
Binary file modified FluidNC/data/index.html.gz
Binary file not shown.
2 changes: 2 additions & 0 deletions FluidNC/include/Driver/delay_usecs.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <cstdint>

extern uint32_t ticks_per_us;

void timing_init();
void spinUntil(int32_t endTicks);
void delay_us(int32_t us);
Expand Down
20 changes: 15 additions & 5 deletions FluidNC/src/Channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,20 +75,30 @@ uint32_t Channel::setReportInterval(uint32_t ms) {
_lastTool = 255; // Force GCodeState report
return actual;
}
static bool motionState() {
return sys.state == State::Cycle || sys.state == State::Homing || sys.state == State::Jog;
}

void Channel::autoReportGCodeState() {
// When moving, we suppress $G reports in which the only change is the motion mode
// (e.g. G0/G1/G2/G3 changes) because rapid-fire motion mode changes are fairly common.
// We would rather not issue a $G report after every GCode line.
// Similarly, F and S values can change rapidly, especially in laser programs.
// F and S values are also reported in ? status reports, so they will show up
// at the chosen periodic rate there.
if (motionState()) {
// Force the compare to succeed if the only change is the motion mode
_lastModal.motion = gc_state.modal.motion;
}
if (memcmp(&_lastModal, &gc_state.modal, sizeof(_lastModal)) || _lastTool != gc_state.tool ||
_lastSpindleSpeed != gc_state.spindle_speed || _lastFeedRate != gc_state.feed_rate) {
(!motionState() && (_lastSpindleSpeed != gc_state.spindle_speed || _lastFeedRate != gc_state.feed_rate))) {
report_gcode_modes(*this);
memcpy(&_lastModal, &gc_state.modal, sizeof(_lastModal));
_lastTool = gc_state.tool;
_lastSpindleSpeed = gc_state.spindle_speed;
_lastFeedRate = gc_state.feed_rate;
}
}
static bool motionState() {
return sys.state == State::Cycle || sys.state == State::Homing || sys.state == State::Jog;
}

void Channel::autoReport() {
if (_reportInterval) {
auto limitState = limits_get_state();
Expand Down
14 changes: 8 additions & 6 deletions FluidNC/src/Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class Channel : public Stream {
// a reception buffer, even if the system is busy. Channels that can handle external
// input via an interrupt or other background mechanism should override it to return
// the remaining space that mechanism has available.
virtual int rx_buffer_available() { return 0; };
// The queue can handle more than 256 characters but we don't want it to get too
// large, so we report a limited size.
virtual int rx_buffer_available() { return std::max(0, 256 - int(_queue.size())); }

// flushRx() discards any characters that have already been received. It is used
// after a reset, so that anything already sent will not be processed.
Expand Down Expand Up @@ -100,10 +102,10 @@ class Channel : public Stream {

int peek() override { return -1; }
int read() override { return -1; }
int available() override { return 0; }
int available() override { return _queue.size(); }

uint32_t setReportInterval(uint32_t ms);
uint32_t getReportInterval() { return _reportInterval; }
void autoReport();
void autoReportGCodeState();
uint32_t setReportInterval(uint32_t ms);
uint32_t getReportInterval() { return _reportInterval; }
virtual void autoReport();
void autoReportGCodeState();
};
6 changes: 4 additions & 2 deletions FluidNC/src/Configuration/Tokenizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,12 @@ namespace Configuration {

// Remove indentation and record the level
_token._indent = _line.find_first_not_of(' ');
_line.remove_prefix(_token._indent);
if (_line.empty()) {
if (_token._indent == std::string_view::npos) {
// Line containing only spaces
_line.remove_prefix(_line.size());
continue;
}
_line.remove_prefix(_token._indent);

// Disallow inital tabs
if (_line.front() == '\t') {
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/Error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ std::map<Error, const char*> ErrorNames = {
{ Error::FsFailedBusy, "Device is busy" },
{ Error::FsFailedDelDir, "Failed to delete directory" },
{ Error::FsFailedDelFile, "Failed to delete file" },
{ Error::FsFailedRenameFile, "Failed to rename file" },
{ Error::FsFailedCreateFile, "Failed to create file" },
{ Error::FsFailedFormat, "Failed to format filesystem" },
{ Error::NumberRange, "Number out of range for setting" },
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ enum class Error : uint8_t {
FsFailedBusy = 67, // Filesystem is busy
FsFailedDelDir = 68,
FsFailedDelFile = 69,
FsFailedRenameFile = 70,
NumberRange = 80, // Setting number range problem
InvalidValue = 81, // Setting string problem
FsFailedCreateFile = 82,
Expand Down
19 changes: 5 additions & 14 deletions FluidNC/src/GCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1366,16 +1366,11 @@ Error gc_execute_line(char* line) {
if (!blockIsFeedrateMotion) {
// If the new mode is not a feedrate move (G1/2/3) we want the laser off
disableLaser = true;
// If we are changing from a feedrate move to a non-feedrate move,
// we must sync the planner and then update the laser state
if (stateIsFeedrateMotion) {
syncLaser = true;
}
}
// Any motion mode with axis words is allowed to be passed from a spindle speed update.
// NOTE: G1 and G0 without axis words sets axis_command to none. G28/30 are intentionally omitted.
// TODO: Check sync conditions for M3 enabled motions that don't enter the planner. (zero length).
if (blockIsFeedrateMotion && axis_words && (axis_command == AxisCommand::MotionMode)) {
if (axis_words && (axis_command == AxisCommand::MotionMode)) {
laserIsMotion = true;
} else {
// M3 constant power laser requires planner syncs to update the laser when changing between
Expand Down Expand Up @@ -1410,14 +1405,10 @@ Error gc_execute_line(char* line) {
pl_data->feed_rate = gc_state.feed_rate; // Record data for planner use.
// [4. Set spindle speed ]:
if ((gc_state.spindle_speed != gc_block.values.s) || syncLaser) {
if (gc_state.modal.spindle != SpindleState::Disable) {
if (!laserIsMotion) {
if (sys.state != State::CheckMode) {
protocol_buffer_synchronize();
spindle->setState(gc_state.modal.spindle, disableLaser ? 0 : (uint32_t)gc_block.values.s);
report_ovr_counter = 0; // Set to report change immediately
}
}
if (gc_state.modal.spindle != SpindleState::Disable && !laserIsMotion && sys.state != State::CheckMode) {
protocol_buffer_synchronize();
spindle->setState(gc_state.modal.spindle, disableLaser ? 0 : (uint32_t)gc_block.values.s);
report_ovr_counter = 0; // Set to report change immediately
}
gc_state.spindle_speed = gc_block.values.s; // Update spindle speed state.
}
Expand Down
6 changes: 4 additions & 2 deletions FluidNC/src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,11 @@ void setup() {
sys.state = State::ConfigAlarm;
}

if (!WebUI::wifi_config.begin()) {
WebUI::bt_config.begin();
// Try Bluetooth first so its memory can be released if it is disabled
if (!WebUI::bt_config.begin()) {
WebUI::wifi_config.begin();
}

allChannels.deregistration(&startupLog);
}

Expand Down
11 changes: 2 additions & 9 deletions FluidNC/src/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,19 +243,12 @@ static void check_startup_state() {
}
if (config->_control->startup_check()) {
rtAlarm = ExecAlarm::ControlPin;
}

if (sys.state == State::Alarm || sys.state == State::Sleep) {
} else if (sys.state == State::Alarm || sys.state == State::Sleep) {
report_feedback_message(Message::AlarmLock);
sys.state = State::Alarm; // Ensure alarm state is set.
} else {
// Check if the safety door is open.
sys.state = State::Idle;
while (config->_control->safety_door_ajar()) {
request_safety_door();
protocol_execute_realtime(); // Enter safety door mode. Should return as IDLE state.
}
// All systems go!
sys.state = State::Idle;
settings_execute_startup(); // Execute startup script.
}
}
Expand Down
24 changes: 16 additions & 8 deletions FluidNC/src/WebUI/BTConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
# include "Commands.h" // COMMANDS
# include "WebSettings.h"

# include "esp_bt.h"
# include "esp_bt_main.h"

# include <cstdint>

// SerialBT sends the data over Bluetooth
Expand Down Expand Up @@ -148,6 +151,13 @@ namespace WebUI {
return Channel::pollLine(line);
}

void BTConfig::releaseMem() {
log_debug("Releasing Bluetooth memory");
esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
esp_bt_mem_release(ESP_BT_MODE_BLE);
log_debug("Heap: " << xPortGetFreeHeapSize());
}

/**
* begin WiFi setup
*/
Expand All @@ -158,25 +168,23 @@ namespace WebUI {
//stop active services
end();

if (!bt_enable->get()) {
log_info("Bluetooth not enabled");
return false;
}

log_debug("Heap: " << xPortGetFreeHeapSize());
_btname = bt_name->getStringValue();

if (_btname.length()) {
if (bt_enable->get() && _btname.length()) {
esp_bt_mem_release(ESP_BT_MODE_BLE);
log_debug("Heap: " << xPortGetFreeHeapSize());
if (!SerialBT.begin(_btname.c_str())) {
log_error("Bluetooth failed to start");
return false;
}

SerialBT.register_callback(&my_spp_cb);
log_info("BT Started with " << _btname);
allChannels.registration(&btChannel);
return true;
}
releaseMem();
log_info("BT is not enabled");
end();
return false;
}

Expand Down
2 changes: 2 additions & 0 deletions FluidNC/src/WebUI/BTConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace WebUI {
static bool begin() { return false; };
static void end() {};
static void handle() {}
static void releaseMem() {}
static bool isOn() { return false; }
};
extern BTConfig bt_config;
Expand Down Expand Up @@ -85,6 +86,7 @@ namespace WebUI {
void handle();
void reset_settings();
bool isOn() const;
void releaseMem();

~BTConfig();
};
Expand Down
38 changes: 17 additions & 21 deletions FluidNC/src/WebUI/JSONEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,13 @@
namespace WebUI {
// Constructor. If _pretty is true, newlines are
// inserted into the JSON string for easy reading.
JSONencoder::JSONencoder(bool pretty, Channel* channel) : pretty(pretty), level(0), _channel(channel), category("nvs") {
JSONencoder::JSONencoder(bool pretty, Channel* channel) : pretty(pretty), level(0), _str(&linebuf), _channel(channel), category("nvs") {
count[level] = 0;
}

JSONencoder::JSONencoder(bool pretty, std::string* str) : pretty(pretty), level(0), _str(str), category("nvs") { count[level] = 0; }

void JSONencoder::add(char c) {
if (_str) {
(*_str) += c;
} else {
linebuf += c;
}
}
void JSONencoder::add(char c) { (*_str) += c; }

// Private function to add commas between
// elements as needed, omitting the comma
Expand Down Expand Up @@ -100,23 +94,25 @@ namespace WebUI {
// Private function to increment the nesting level.
void JSONencoder::dec_level() { --level; }

void JSONencoder::indent() {
for (int i = 0; i < 2 * level; i++) {
add(' ');
}
}

// Private function to implement pretty-printing
void JSONencoder::line() {
if (_str) {
if (pretty) {
add('\n');
linebuf = "";
for (int i = 0; i < 2 * level; i++) {
add(' ');
}
}
} else {
if (_channel) {
// Always pretty print to a channel, because channels
// cannot necessary handle really long lines.
log_to(*_channel, linebuf);
linebuf = "";
for (int i = 0; i < 2 * level; i++) {
add(' ');
add('\n');
log_to(*_channel, *_str);
*_str = "";
indent();
} else {
if (pretty) {
add('\n');
indent();
}
}
}
Expand Down
1 change: 1 addition & 0 deletions FluidNC/src/WebUI/JSONEncoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ namespace WebUI {
void quoted(const char* s);
void inc_level();
void dec_level();
void indent();
void line();

std::string linebuf;
Expand Down
Loading

0 comments on commit 4704b8c

Please sign in to comment.