mirror of
https://github.com/bdring/Grbl_Esp32.git
synced 2025-08-18 12:21:39 +02:00
OLED and Other Updates (#844)
* publish * Updates - CoreXY and OLED - Moved position calculation out of report_realtime_status(...) so other functions can access it. - Added a function to check if a limit switch is defined - CoreXY fixed bug in forward kinematics when midtbot is used. - Modified OLED display. * Cleanup for PR * Delete midtbot_x2.h * Incorporated PR 846 - Some OLED cleanup - verified correct forward kinematics on MidTbot
This commit is contained in:
@@ -314,7 +314,7 @@ void forward_kinematics(float* position) {
|
||||
// apply the forward kinemetics to the machine coordinates
|
||||
// https://corexy.com/theory.html
|
||||
//calc_fwd[X_AXIS] = 0.5 / geometry_factor * (position[X_AXIS] + position[Y_AXIS]);
|
||||
calc_fwd[X_AXIS] = ((0.5 * (print_position[X_AXIS] + print_position[Y_AXIS]) * geometry_factor) - wco[X_AXIS]);
|
||||
calc_fwd[X_AXIS] = ((0.5 * (print_position[X_AXIS] + print_position[Y_AXIS]) / geometry_factor) - wco[X_AXIS]);
|
||||
calc_fwd[Y_AXIS] = ((0.5 * (print_position[X_AXIS] - print_position[Y_AXIS])) - wco[Y_AXIS]);
|
||||
|
||||
for (int axis = 0; axis < n_axis; axis++) {
|
||||
|
@@ -38,12 +38,11 @@
|
||||
|
||||
Add this to your machine definition file
|
||||
#define DISPLAY_CODE_FILENAME "Custom/oled_basic.cpp"
|
||||
|
||||
*/
|
||||
|
||||
// Include the correct display library
|
||||
|
||||
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h"
|
||||
#include "SSD1306Wire.h"
|
||||
#include "../src/WebUI/WebSettings.h"
|
||||
|
||||
#ifndef OLED_ADDRESS
|
||||
@@ -66,142 +65,129 @@ SSD1306Wire display(OLED_ADDRESS, OLED_SDA, OLED_SCL, OLED_GEOMETRY);
|
||||
|
||||
static TaskHandle_t displayUpdateTaskHandle = 0;
|
||||
|
||||
// returns the position of a machine axis
|
||||
// wpos =true for corrected work postion
|
||||
float getPosition(uint8_t axis, bool wpos = true) {
|
||||
float wco; // work coordinate system offset
|
||||
|
||||
float current_position = sys_position[axis] / axis_settings[axis]->steps_per_mm->get();
|
||||
|
||||
if (wpos) {
|
||||
// Apply work coordinate offsets and tool length offset to current position.
|
||||
wco = gc_state.coord_system[axis] + gc_state.coord_offset[axis];
|
||||
if (axis == TOOL_LENGTH_OFFSET_AXIS) {
|
||||
wco += gc_state.tool_length_offset;
|
||||
}
|
||||
|
||||
current_position -= wco;
|
||||
}
|
||||
return current_position;
|
||||
}
|
||||
|
||||
String getStateText() {
|
||||
String str = "";
|
||||
|
||||
switch (sys.state) {
|
||||
case State::Idle:
|
||||
str = "Idle";
|
||||
break;
|
||||
case State::Cycle:
|
||||
str = "Run";
|
||||
break;
|
||||
case State::Hold:
|
||||
if (!(sys.suspend.bit.jogCancel)) {
|
||||
str = "Hold:";
|
||||
sys.suspend.bit.holdComplete ? str += "0" : str += "1"; // Ready to resume
|
||||
break;
|
||||
} // Continues to print jog state during jog cancel.
|
||||
case State::Jog:
|
||||
str = "Jog";
|
||||
break;
|
||||
case State::Homing:
|
||||
str = "Homing";
|
||||
break;
|
||||
case State::Alarm:
|
||||
str = "Alarm";
|
||||
break;
|
||||
case State::CheckMode:
|
||||
str = "Check";
|
||||
break;
|
||||
case State::SafetyDoor:
|
||||
str = "Door:";
|
||||
if (sys.suspend.bit.initiateRestore) {
|
||||
str += "3"; // Restoring
|
||||
} else {
|
||||
if (sys.suspend.bit.retractComplete) {
|
||||
sys.suspend.bit.safetyDoorAjar ? str += "1" : str += "0"; // Door ajar
|
||||
// Door closed and ready to resume
|
||||
} else {
|
||||
str += "2"; // Retracting
|
||||
}
|
||||
}
|
||||
break;
|
||||
case State::Sleep:
|
||||
str = "Sleep";
|
||||
break;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
// This displays the status of the ESP32 Radios...BT, WiFi, etc
|
||||
void displayRadioInfo() {
|
||||
String radio_info = "";
|
||||
|
||||
const uint8_t row1 = 18;
|
||||
const uint8_t row2 = 30;
|
||||
const uint8_t row3 = 42;
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
String radio_addr = "";
|
||||
String radio_name = "";
|
||||
String radio_status = "";
|
||||
|
||||
#ifdef ENABLE_BLUETOOTH
|
||||
if (WebUI::wifi_radio_mode->get() == ESP_BT) {
|
||||
radio_info = String("Bluetooth: ") + WebUI::bt_name->get();
|
||||
display.drawString(0, row1, radio_info);
|
||||
radio_info = String("Status: ") + String(WebUI::SerialBT.hasClient() ? "Connected" : "Not connected");
|
||||
display.drawString(0, row2, radio_info);
|
||||
radio_name = String("BT: ") + WebUI::bt_name->get();
|
||||
}
|
||||
#endif
|
||||
#ifdef ENABLE_WIFI
|
||||
if ((WiFi.getMode() == WIFI_MODE_STA) || (WiFi.getMode() == WIFI_MODE_APSTA)) {
|
||||
radio_info = "STA SSID: " + WiFi.SSID();
|
||||
display.drawString(0, row1, radio_info);
|
||||
|
||||
radio_info = "IP: " + WiFi.localIP().toString();
|
||||
display.drawString(0, row2, radio_info);
|
||||
|
||||
radio_info = "Status: ";
|
||||
(WiFi.status() == WL_CONNECTED) ? radio_info += "Connected" : radio_info += "Not connected";
|
||||
display.drawString(0, row3, radio_info);
|
||||
//}
|
||||
radio_name = "STA: " + WiFi.SSID();
|
||||
radio_addr = WiFi.localIP().toString();
|
||||
} else if ((WiFi.getMode() == WIFI_MODE_AP) || (WiFi.getMode() == WIFI_MODE_APSTA)) {
|
||||
radio_info = String("AP SSID: ") + WebUI::wifi_ap_ssid->get();
|
||||
|
||||
display.drawString(0, row1, radio_info);
|
||||
|
||||
radio_info = "IP: " + WiFi.softAPIP().toString();
|
||||
display.drawString(0, row2, radio_info);
|
||||
radio_name = String("AP:") + WebUI::wifi_ap_ssid->get();
|
||||
radio_addr = WiFi.softAPIP().toString();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WIFI_OR_BLUETOOTH
|
||||
if (WebUI::wifi_radio_mode->get() == ESP_RADIO_OFF) {
|
||||
display.drawString(0, row1, "Radio Mode: None");
|
||||
radio_name = "Radio Mode: None";
|
||||
}
|
||||
#else
|
||||
display.drawString(0, row1, "Wifi and Bluetooth Disabled");
|
||||
radio_name = "Radio Mode:Disabled";
|
||||
#endif
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
|
||||
if (sys.state == State::Alarm) { // print below Alarm:
|
||||
display.drawString(0, 18, radio_name);
|
||||
display.drawString(0, 30, radio_addr);
|
||||
|
||||
} else { // print next to status
|
||||
if (WebUI::wifi_radio_mode->get() == ESP_BT) {
|
||||
display.drawString(55, 2, radio_name);
|
||||
} else {
|
||||
display.drawString(55, 2, radio_addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Here changes begin Here changes begin Here changes begin Here changes begin Here changes begin
|
||||
|
||||
void draw_checkbox(int16_t x, int16_t y, int16_t width, int16_t height, bool checked) {
|
||||
if (checked)
|
||||
display.fillRect(x, y, width, height); // If log.0
|
||||
else
|
||||
display.drawRect(x, y, width, height); // If log.1
|
||||
}
|
||||
|
||||
void displayDRO() {
|
||||
uint8_t oled_y_pos;
|
||||
float print_position[MAX_N_AXIS];
|
||||
//float wco[MAX_N_AXIS];
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
|
||||
char axisVal[20];
|
||||
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, 13, String('X') + ":");
|
||||
display.drawString(0, 30, "Y:");
|
||||
display.drawString(0, 47, "Z:");
|
||||
display.drawString(80, 14, "L"); // Limit switch
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
snprintf(axisVal, 20 - 1, "%.3f", getPosition(X_AXIS, true));
|
||||
display.drawString(100, 13, axisVal);
|
||||
auto n_axis = number_axis->get();
|
||||
AxisMask lim_pin_state = limits_get_state();
|
||||
ControlPins ctrl_pin_state = system_control_get_state();
|
||||
bool prb_pin_state = probe_get_state();
|
||||
|
||||
snprintf(axisVal, 20 - 1, "%.3f", getPosition(Y_AXIS, true));
|
||||
display.drawString(100, 30, axisVal);
|
||||
if (bit_istrue(status_mask->get(), RtStatus::Position)) {
|
||||
calc_mpos(print_position);
|
||||
} else {
|
||||
calc_wpos(print_position);
|
||||
}
|
||||
|
||||
snprintf(axisVal, 20 - 1, "%.3f", getPosition(Z_AXIS, true));
|
||||
display.drawString(100, 47, axisVal);
|
||||
for (uint8_t axis = X_AXIS; axis < n_axis; axis++) {
|
||||
oled_y_pos = 24 + (axis * 10);
|
||||
|
||||
String axis_letter = String(report_get_axis_letter(axis));
|
||||
axis_letter += ":";
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.drawString(0, oled_y_pos, axis_letter); // String('X') + ":");
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_RIGHT);
|
||||
snprintf(axisVal, 20 - 1, "%.3f", print_position[axis]);
|
||||
display.drawString(60, oled_y_pos, axisVal);
|
||||
|
||||
if (limitsSwitchDefined(axis, 0)) { // olny draw the box if a switch has been defined
|
||||
draw_checkbox(80, 27 + (axis * 10), 7, 7, bit_istrue(lim_pin_state, bit(axis)));
|
||||
}
|
||||
}
|
||||
|
||||
oled_y_pos = 14;
|
||||
|
||||
if (PROBE_PIN != UNDEFINED_PIN) {
|
||||
display.drawString(110, oled_y_pos, "P");
|
||||
draw_checkbox(120, oled_y_pos + 3, 7, 7, prb_pin_state);
|
||||
oled_y_pos += 10;
|
||||
}
|
||||
|
||||
#ifdef CONTROL_FEED_HOLD_PIN
|
||||
display.drawString(110, oled_y_pos, "H");
|
||||
draw_checkbox(120, oled_y_pos + 3, 7, 7, ctrl_pin_state.bit.feedHold);
|
||||
oled_y_pos += 10;
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_CYCLE_START_PIN
|
||||
display.drawString(110, oled_y_pos, "S");
|
||||
draw_checkbox(120, oled_y_pos + 3, 7, 7, ctrl_pin_state.bit.cycleStart);
|
||||
oled_y_pos += 10;
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_RESET_PIN
|
||||
display.drawString(110, oled_y_pos, "R");
|
||||
draw_checkbox(120, oled_y_pos + 3, 7, 7, ctrl_pin_state.bit.reset);
|
||||
oled_y_pos += 10;
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_SAFETY_DOOR_PIN
|
||||
display.drawString(110, oled_y_pos, "D");
|
||||
draw_checkbox(120, oled_y_pos + 3, 7, 7, ctrl_pin_state.bit.safetyDoor);
|
||||
#endif
|
||||
}
|
||||
|
||||
void displayUpdate(void* pvParameters) {
|
||||
@@ -218,31 +204,33 @@ void displayUpdate(void* pvParameters) {
|
||||
while (true) {
|
||||
display.clear();
|
||||
|
||||
String state_string = getStateText();
|
||||
|
||||
state_string.toUpperCase();
|
||||
String state_string = "";
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.drawString(0, 0, state_string);
|
||||
display.drawString(0, 0, report_state_text());
|
||||
|
||||
if (get_sd_state(false) == SDState::BusyPrinting) {
|
||||
display.clear();
|
||||
display.setTextAlignment(TEXT_ALIGN_LEFT);
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
state_string = "SD File";
|
||||
for (int i = 0; i < sd_file_ticker % 10; i++) {
|
||||
state_string += ".";
|
||||
}
|
||||
sd_file_ticker++;
|
||||
display.drawString(25, 0, state_string);
|
||||
display.drawString(63, 0, state_string);
|
||||
|
||||
char path[50];
|
||||
sd_get_current_filename(path);
|
||||
display.drawString(63, 12, path);
|
||||
|
||||
int progress = sd_report_perc_complete();
|
||||
// draw the progress bar
|
||||
display.drawProgressBar(0, 45, 120, 10, progress);
|
||||
|
||||
// draw the percentage as String
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.drawString(64, 25, String(progress) + "%");
|
||||
|
||||
@@ -250,7 +238,9 @@ void displayUpdate(void* pvParameters) {
|
||||
displayRadioInfo();
|
||||
} else {
|
||||
displayDRO();
|
||||
displayRadioInfo();
|
||||
}
|
||||
|
||||
display.display();
|
||||
|
||||
vTaskDelayUntil(&xLastWakeTime, xDisplayFrequency);
|
||||
@@ -260,20 +250,22 @@ void displayUpdate(void* pvParameters) {
|
||||
void display_init() {
|
||||
// Initialising the UI will init the display too.
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Init Basic OLED SDA:%s SCL:%s", pinName(OLED_SDA), pinName(OLED_SCL));
|
||||
|
||||
display.init();
|
||||
|
||||
display.flipScreenVertically();
|
||||
|
||||
display.clear();
|
||||
|
||||
display.setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display.setFont(ArialMT_Plain_16);
|
||||
display.setFont(ArialMT_Plain_10);
|
||||
|
||||
String mach_name = MACHINE_NAME;
|
||||
// remove characters from the end until the string fits
|
||||
while (display.getStringWidth(mach_name) > 128) {
|
||||
mach_name = mach_name.substring(0, mach_name.length() - 1);
|
||||
}
|
||||
|
||||
display.drawString(63, 0, mach_name);
|
||||
|
||||
display.display();
|
||||
|
||||
xTaskCreatePinnedToCore(displayUpdate, // task
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -22,7 +22,7 @@
|
||||
|
||||
// Grbl versioning system
|
||||
const char* const GRBL_VERSION = "1.3a";
|
||||
const char* const GRBL_VERSION_BUILD = "20210320";
|
||||
const char* const GRBL_VERSION_BUILD = "20210329";
|
||||
|
||||
//#include <sdkconfig.h>
|
||||
#include <Arduino.h>
|
||||
|
@@ -406,6 +406,10 @@ bool limitsCheckTravel(float* target) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool limitsSwitchDefined(uint8_t axis, uint8_t gang_index) {
|
||||
return (limit_pins[axis][gang_index] != UNDEFINED_PIN);
|
||||
}
|
||||
|
||||
bool __attribute__((weak)) user_defined_homing(uint8_t cycle_mask) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -54,3 +54,6 @@ float limitsMinPosition(uint8_t axis);
|
||||
|
||||
// Internal factor used by limits_soft_check
|
||||
bool limitsCheckTravel(float* target);
|
||||
|
||||
// check if a switch has been defined
|
||||
bool limitsSwitchDefined(uint8_t axis, uint8_t gang_index);
|
||||
|
@@ -291,13 +291,13 @@ std::map<Message, const char*> MessageText = {
|
||||
// NOTE: For interfaces, messages are always placed within brackets. And if silent mode
|
||||
// is installed, the message number codes are less than zero.
|
||||
void report_feedback_message(Message message) { // ok to send to all clients
|
||||
#if defined (ENABLE_SD_CARD)
|
||||
#if defined(ENABLE_SD_CARD)
|
||||
if (message == Message::SdFileQuit) {
|
||||
grbl_notifyf("SD print canceled", "Reset during SD file at line: %d", sd_get_current_line_number());
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Reset during SD file at line: %d", sd_get_current_line_number());
|
||||
|
||||
} else
|
||||
#endif //ENABLE_SD_CARD
|
||||
#endif //ENABLE_SD_CARD
|
||||
{
|
||||
auto it = MessageText.find(message);
|
||||
if (it != MessageText.end()) {
|
||||
@@ -592,82 +592,52 @@ void report_echo_line_received(char* line, uint8_t client) {
|
||||
grbl_sendf(client, "[echo: %s]\r\n", line);
|
||||
}
|
||||
|
||||
// Calculate the position for status reports.
|
||||
// float print_position = returned position
|
||||
// float wco = returns the work coordinate offset
|
||||
// bool wpos = true for work position compensation
|
||||
void report_calc_status_position(float* print_position, float* wco, bool wpos) {
|
||||
int32_t current_position[MAX_N_AXIS]; // Copy current state of the system position variable
|
||||
memcpy(current_position, sys_position, sizeof(sys_position));
|
||||
system_convert_array_steps_to_mpos(print_position, current_position);
|
||||
|
||||
//float wco[MAX_N_AXIS];
|
||||
if (wpos || (sys.report_wco_counter == 0)) {
|
||||
auto n_axis = number_axis->get();
|
||||
for (uint8_t idx = 0; idx < n_axis; idx++) {
|
||||
// Apply work coordinate offsets and tool length offset to current position.
|
||||
wco[idx] = gc_state.coord_system[idx] + gc_state.coord_offset[idx];
|
||||
if (idx == TOOL_LENGTH_OFFSET_AXIS) {
|
||||
wco[idx] += gc_state.tool_length_offset;
|
||||
}
|
||||
if (wpos) {
|
||||
print_position[idx] -= wco[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
forward_kinematics(print_position); // a weak definition does nothing. Users can provide strong version
|
||||
}
|
||||
|
||||
// Prints real-time data. This function grabs a real-time snapshot of the stepper subprogram
|
||||
// and the actual location of the CNC machine. Users may change the following function to their
|
||||
// specific needs, but the desired real-time data report must be as short as possible. This is
|
||||
// requires as it minimizes the computational overhead and allows grbl to keep running smoothly,
|
||||
// especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
|
||||
void report_realtime_status(uint8_t client) {
|
||||
uint8_t idx;
|
||||
int32_t current_position[MAX_N_AXIS]; // Copy current state of the system position variable
|
||||
memcpy(current_position, sys_position, sizeof(sys_position));
|
||||
float print_position[MAX_N_AXIS];
|
||||
char status[200];
|
||||
char temp[MAX_N_AXIS * 20];
|
||||
system_convert_array_steps_to_mpos(print_position, current_position);
|
||||
// Report current machine state and sub-states
|
||||
|
||||
strcpy(status, "<");
|
||||
switch (sys.state) {
|
||||
case State::Idle:
|
||||
strcat(status, "Idle");
|
||||
break;
|
||||
case State::Cycle:
|
||||
strcat(status, "Run");
|
||||
break;
|
||||
case State::Hold:
|
||||
if (!(sys.suspend.bit.jogCancel)) {
|
||||
strcat(status, "Hold:");
|
||||
strcat(status, sys.suspend.bit.holdComplete ? "0" : "1"); // Ready to resume
|
||||
break;
|
||||
} // Continues to print jog state during jog cancel.
|
||||
case State::Jog:
|
||||
strcat(status, "Jog");
|
||||
break;
|
||||
case State::Homing:
|
||||
strcat(status, "Home");
|
||||
break;
|
||||
case State::Alarm:
|
||||
strcat(status, "Alarm");
|
||||
break;
|
||||
case State::CheckMode:
|
||||
strcat(status, "Check");
|
||||
break;
|
||||
case State::SafetyDoor:
|
||||
strcat(status, "Door:");
|
||||
if (sys.suspend.bit.initiateRestore) {
|
||||
strcat(status, "3"); // Restoring
|
||||
} else {
|
||||
if (sys.suspend.bit.retractComplete) {
|
||||
strcat(status, sys.suspend.bit.safetyDoorAjar ? "1" : "0"); // Door ajar
|
||||
// Door closed and ready to resume
|
||||
} else {
|
||||
strcat(status, "2"); // Retracting
|
||||
}
|
||||
}
|
||||
break;
|
||||
case State::Sleep:
|
||||
strcat(status, "Sleep");
|
||||
break;
|
||||
}
|
||||
float wco[MAX_N_AXIS];
|
||||
if (bit_isfalse(status_mask->get(), RtStatus::Position) || (sys.report_wco_counter == 0)) {
|
||||
auto n_axis = number_axis->get();
|
||||
for (idx = 0; idx < n_axis; idx++) {
|
||||
// Apply work coordinate offsets and tool length offset to current position.
|
||||
wco[idx] = gc_state.coord_system[idx] + gc_state.coord_offset[idx];
|
||||
if (idx == TOOL_LENGTH_OFFSET_AXIS) {
|
||||
wco[idx] += gc_state.tool_length_offset;
|
||||
}
|
||||
if (bit_isfalse(status_mask->get(), RtStatus::Position)) {
|
||||
print_position[idx] -= wco[idx];
|
||||
}
|
||||
}
|
||||
}
|
||||
forward_kinematics(print_position); // a weak definition does nothing. Users can provide strong version
|
||||
// Report machine position
|
||||
strcat(status, report_state_text());
|
||||
|
||||
// Report position
|
||||
if (bit_istrue(status_mask->get(), RtStatus::Position)) {
|
||||
calc_mpos(print_position);
|
||||
strcat(status, "|MPos:");
|
||||
} else {
|
||||
calc_wpos(print_position);
|
||||
strcat(status, "|WPos:");
|
||||
}
|
||||
report_util_axis_values(print_position, temp);
|
||||
@@ -793,7 +763,7 @@ void report_realtime_status(uint8_t client) {
|
||||
sys.report_ovr_counter = 1; // Set override on next report.
|
||||
}
|
||||
strcat(status, "|WCO:");
|
||||
report_util_axis_values(wco, temp);
|
||||
report_util_axis_values(get_wco(), temp);
|
||||
strcat(status, temp);
|
||||
}
|
||||
#endif
|
||||
@@ -913,6 +883,54 @@ void report_hex_msg(uint8_t* buf, const char* prefix, int len) {
|
||||
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "%s", report);
|
||||
}
|
||||
|
||||
char* report_state_text() {
|
||||
static char state[10];
|
||||
|
||||
switch (sys.state) {
|
||||
case State::Idle:
|
||||
strcpy(state, "Idle");
|
||||
break;
|
||||
case State::Cycle:
|
||||
strcpy(state, "Run");
|
||||
break;
|
||||
case State::Hold:
|
||||
if (!(sys.suspend.bit.jogCancel)) {
|
||||
sys.suspend.bit.holdComplete ? strcpy(state, "Hold:0") : strcpy(state, "Hold:1");
|
||||
break;
|
||||
} // Continues to print jog state during jog cancel.
|
||||
case State::Jog:
|
||||
strcpy(state, "Jog");
|
||||
break;
|
||||
case State::Homing:
|
||||
strcpy(state, "Home");
|
||||
break;
|
||||
case State::Alarm:
|
||||
strcpy(state, "Alarm");
|
||||
break;
|
||||
case State::CheckMode:
|
||||
strcpy(state, "Check");
|
||||
break;
|
||||
case State::SafetyDoor:
|
||||
strcpy(state, "Door:");
|
||||
if (sys.suspend.bit.initiateRestore) {
|
||||
strcat(state, "3"); // Restoring
|
||||
} else {
|
||||
if (sys.suspend.bit.retractComplete) {
|
||||
sys.suspend.bit.safetyDoorAjar ? strcat(state, "1") : strcat(state, "0");
|
||||
; // Door ajar
|
||||
// Door closed and ready to resume
|
||||
} else {
|
||||
strcat(state, "2"); // Retracting
|
||||
}
|
||||
}
|
||||
break;
|
||||
case State::Sleep:
|
||||
strcpy(state, "Sleep");
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
char report_get_axis_letter(uint8_t axis) {
|
||||
switch (axis) {
|
||||
case X_AXIS:
|
||||
@@ -960,4 +978,37 @@ void reportTaskStackSize(UBaseType_t& saved) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void calc_mpos(float* print_position) {
|
||||
int32_t current_position[MAX_N_AXIS]; // Copy current state of the system position variable
|
||||
memcpy(current_position, sys_position, sizeof(sys_position));
|
||||
system_convert_array_steps_to_mpos(print_position, current_position);
|
||||
forward_kinematics(print_position); // a weak definition does nothing. Users can provide strong version
|
||||
}
|
||||
|
||||
void calc_wpos(float* print_position) {
|
||||
int32_t current_position[MAX_N_AXIS]; // Copy current state of the system position variable
|
||||
memcpy(current_position, sys_position, sizeof(sys_position));
|
||||
system_convert_array_steps_to_mpos(print_position, current_position);
|
||||
|
||||
float* wco = get_wco();
|
||||
auto n_axis = number_axis->get();
|
||||
for (int idx = 0; idx < n_axis; idx++) {
|
||||
print_position[idx] -= wco[idx];
|
||||
}
|
||||
|
||||
forward_kinematics(print_position); // a weak definition does nothing. Users can provide strong version
|
||||
}
|
||||
float* get_wco() {
|
||||
static float wco[MAX_N_AXIS];
|
||||
auto n_axis = number_axis->get();
|
||||
for (int idx = 0; idx < n_axis; idx++) {
|
||||
// Apply work coordinate offsets and tool length offset to current position.
|
||||
wco[idx] = gc_state.coord_system[idx] + gc_state.coord_offset[idx];
|
||||
if (idx == TOOL_LENGTH_OFFSET_AXIS) {
|
||||
wco[idx] += gc_state.tool_length_offset;
|
||||
}
|
||||
}
|
||||
return wco;
|
||||
}
|
||||
|
||||
void __attribute__((weak)) forward_kinematics(float* position) {} // This version does nothing. Make your own to do something with it
|
||||
|
@@ -92,6 +92,9 @@ void report_grbl_settings(uint8_t client, uint8_t show_extended);
|
||||
// Prints an echo of the pre-parsed line received right before execution.
|
||||
void report_echo_line_received(char* line, uint8_t client);
|
||||
|
||||
// calculate the postion for status reports
|
||||
void report_calc_status_position(float* print_position, float* wco, bool wpos);
|
||||
|
||||
// Prints realtime status report
|
||||
void report_realtime_status(uint8_t client);
|
||||
|
||||
@@ -122,10 +125,14 @@ void report_machine_type(uint8_t client);
|
||||
void report_hex_msg(char* buf, const char* prefix, int len);
|
||||
void report_hex_msg(uint8_t* buf, const char* prefix, int len);
|
||||
|
||||
char report_get_axis_letter(uint8_t axis);
|
||||
|
||||
char report_get_axis_letter(uint8_t axis);
|
||||
char* reportAxisLimitsMsg(uint8_t axis);
|
||||
char* reportAxisNameMsg(uint8_t axis);
|
||||
char* reportAxisNameMsg(uint8_t axis, uint8_t dual_axis);
|
||||
|
||||
void reportTaskStackSize(UBaseType_t& saved);
|
||||
|
||||
char* report_state_text();
|
||||
float* get_wco();
|
||||
void calc_mpos(float* print_position);
|
||||
void calc_wpos(float* print_position);
|
||||
|
Reference in New Issue
Block a user