1
0
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:
bdring
2021-03-30 08:42:15 -05:00
committed by GitHub
parent e8cf0bbfcc
commit 90ca0ac6e8
9 changed files with 251 additions and 194 deletions

View File

@@ -314,7 +314,7 @@ void forward_kinematics(float* position) {
// apply the forward kinemetics to the machine coordinates // apply the forward kinemetics to the machine coordinates
// https://corexy.com/theory.html // 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 / 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]); 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++) { for (int axis = 0; axis < n_axis; axis++) {

View File

@@ -38,12 +38,11 @@
Add this to your machine definition file Add this to your machine definition file
#define DISPLAY_CODE_FILENAME "Custom/oled_basic.cpp" #define DISPLAY_CODE_FILENAME "Custom/oled_basic.cpp"
*/ */
// Include the correct display library // Include the correct display library
#include "SSD1306Wire.h" // legacy: #include "SSD1306.h" #include "SSD1306Wire.h"
#include "../src/WebUI/WebSettings.h" #include "../src/WebUI/WebSettings.h"
#ifndef OLED_ADDRESS #ifndef OLED_ADDRESS
@@ -66,142 +65,129 @@ SSD1306Wire display(OLED_ADDRESS, OLED_SDA, OLED_SCL, OLED_GEOMETRY);
static TaskHandle_t displayUpdateTaskHandle = 0; 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 // This displays the status of the ESP32 Radios...BT, WiFi, etc
void displayRadioInfo() { void displayRadioInfo() {
String radio_info = ""; String radio_addr = "";
String radio_name = "";
const uint8_t row1 = 18; String radio_status = "";
const uint8_t row2 = 30;
const uint8_t row3 = 42;
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
#ifdef ENABLE_BLUETOOTH #ifdef ENABLE_BLUETOOTH
if (WebUI::wifi_radio_mode->get() == ESP_BT) { if (WebUI::wifi_radio_mode->get() == ESP_BT) {
radio_info = String("Bluetooth: ") + WebUI::bt_name->get(); radio_name = String("BT: ") + 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);
} }
#endif #endif
#ifdef ENABLE_WIFI #ifdef ENABLE_WIFI
if ((WiFi.getMode() == WIFI_MODE_STA) || (WiFi.getMode() == WIFI_MODE_APSTA)) { if ((WiFi.getMode() == WIFI_MODE_STA) || (WiFi.getMode() == WIFI_MODE_APSTA)) {
radio_info = "STA SSID: " + WiFi.SSID(); radio_name = "STA: " + WiFi.SSID();
display.drawString(0, row1, radio_info); radio_addr = WiFi.localIP().toString();
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);
//}
} else if ((WiFi.getMode() == WIFI_MODE_AP) || (WiFi.getMode() == WIFI_MODE_APSTA)) { } else if ((WiFi.getMode() == WIFI_MODE_AP) || (WiFi.getMode() == WIFI_MODE_APSTA)) {
radio_info = String("AP SSID: ") + WebUI::wifi_ap_ssid->get(); radio_name = String("AP:") + WebUI::wifi_ap_ssid->get();
radio_addr = WiFi.softAPIP().toString();
display.drawString(0, row1, radio_info);
radio_info = "IP: " + WiFi.softAPIP().toString();
display.drawString(0, row2, radio_info);
} }
#endif #endif
#ifdef WIFI_OR_BLUETOOTH #ifdef WIFI_OR_BLUETOOTH
if (WebUI::wifi_radio_mode->get() == ESP_RADIO_OFF) { if (WebUI::wifi_radio_mode->get() == ESP_RADIO_OFF) {
display.drawString(0, row1, "Radio Mode: None"); radio_name = "Radio Mode: None";
} }
#else #else
display.drawString(0, row1, "Wifi and Bluetooth Disabled"); radio_name = "Radio Mode:Disabled";
#endif #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() { 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]; char axisVal[20];
display.setFont(ArialMT_Plain_16); display.drawString(80, 14, "L"); // Limit switch
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 13, String('X') + ":");
display.drawString(0, 30, "Y:");
display.drawString(0, 47, "Z:");
display.setTextAlignment(TEXT_ALIGN_RIGHT); auto n_axis = number_axis->get();
snprintf(axisVal, 20 - 1, "%.3f", getPosition(X_AXIS, true)); AxisMask lim_pin_state = limits_get_state();
display.drawString(100, 13, axisVal); ControlPins ctrl_pin_state = system_control_get_state();
bool prb_pin_state = probe_get_state();
snprintf(axisVal, 20 - 1, "%.3f", getPosition(Y_AXIS, true)); if (bit_istrue(status_mask->get(), RtStatus::Position)) {
display.drawString(100, 30, axisVal); calc_mpos(print_position);
} else {
calc_wpos(print_position);
}
snprintf(axisVal, 20 - 1, "%.3f", getPosition(Z_AXIS, true)); for (uint8_t axis = X_AXIS; axis < n_axis; axis++) {
display.drawString(100, 47, axisVal); 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) { void displayUpdate(void* pvParameters) {
@@ -218,31 +204,33 @@ void displayUpdate(void* pvParameters) {
while (true) { while (true) {
display.clear(); display.clear();
String state_string = getStateText(); String state_string = "";
state_string.toUpperCase();
display.setTextAlignment(TEXT_ALIGN_LEFT); display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16); 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) { if (get_sd_state(false) == SDState::BusyPrinting) {
display.clear(); display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT); display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setFont(ArialMT_Plain_16); display.setFont(ArialMT_Plain_10);
state_string = "SD File"; state_string = "SD File";
for (int i = 0; i < sd_file_ticker % 10; i++) { for (int i = 0; i < sd_file_ticker % 10; i++) {
state_string += "."; state_string += ".";
} }
sd_file_ticker++; 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(); int progress = sd_report_perc_complete();
// draw the progress bar // draw the progress bar
display.drawProgressBar(0, 45, 120, 10, progress); display.drawProgressBar(0, 45, 120, 10, progress);
// draw the percentage as String // draw the percentage as String
display.setFont(ArialMT_Plain_16); display.setFont(ArialMT_Plain_10);
display.setTextAlignment(TEXT_ALIGN_CENTER); display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 25, String(progress) + "%"); display.drawString(64, 25, String(progress) + "%");
@@ -250,7 +238,9 @@ void displayUpdate(void* pvParameters) {
displayRadioInfo(); displayRadioInfo();
} else { } else {
displayDRO(); displayDRO();
displayRadioInfo();
} }
display.display(); display.display();
vTaskDelayUntil(&xLastWakeTime, xDisplayFrequency); vTaskDelayUntil(&xLastWakeTime, xDisplayFrequency);
@@ -260,20 +250,22 @@ void displayUpdate(void* pvParameters) {
void display_init() { void display_init() {
// Initialising the UI will init the display too. // 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)); grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Init Basic OLED SDA:%s SCL:%s", pinName(OLED_SDA), pinName(OLED_SCL));
display.init(); display.init();
display.flipScreenVertically(); display.flipScreenVertically();
display.clear(); display.clear();
display.setTextAlignment(TEXT_ALIGN_CENTER); display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setFont(ArialMT_Plain_16); display.setFont(ArialMT_Plain_10);
String mach_name = MACHINE_NAME; String mach_name = MACHINE_NAME;
// remove characters from the end until the string fits // remove characters from the end until the string fits
while (display.getStringWidth(mach_name) > 128) { while (display.getStringWidth(mach_name) > 128) {
mach_name = mach_name.substring(0, mach_name.length() - 1); mach_name = mach_name.substring(0, mach_name.length() - 1);
} }
display.drawString(63, 0, mach_name); display.drawString(63, 0, mach_name);
display.display(); display.display();
xTaskCreatePinnedToCore(displayUpdate, // task xTaskCreatePinnedToCore(displayUpdate, // task

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -22,7 +22,7 @@
// Grbl versioning system // Grbl versioning system
const char* const GRBL_VERSION = "1.3a"; 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 <sdkconfig.h>
#include <Arduino.h> #include <Arduino.h>

View File

@@ -406,6 +406,10 @@ bool limitsCheckTravel(float* target) {
return false; 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) { bool __attribute__((weak)) user_defined_homing(uint8_t cycle_mask) {
return false; return false;
} }

View File

@@ -54,3 +54,6 @@ float limitsMinPosition(uint8_t axis);
// Internal factor used by limits_soft_check // Internal factor used by limits_soft_check
bool limitsCheckTravel(float* target); bool limitsCheckTravel(float* target);
// check if a switch has been defined
bool limitsSwitchDefined(uint8_t axis, uint8_t gang_index);

View File

@@ -291,13 +291,13 @@ std::map<Message, const char*> MessageText = {
// NOTE: For interfaces, messages are always placed within brackets. And if silent mode // NOTE: For interfaces, messages are always placed within brackets. And if silent mode
// is installed, the message number codes are less than zero. // is installed, the message number codes are less than zero.
void report_feedback_message(Message message) { // ok to send to all clients 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) { if (message == Message::SdFileQuit) {
grbl_notifyf("SD print canceled", "Reset during SD file at line: %d", sd_get_current_line_number()); 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()); grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "Reset during SD file at line: %d", sd_get_current_line_number());
} else } else
#endif //ENABLE_SD_CARD #endif //ENABLE_SD_CARD
{ {
auto it = MessageText.find(message); auto it = MessageText.find(message);
if (it != MessageText.end()) { 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); 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 // 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 // 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 // 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, // 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). // especially during g-code programs with fast, short line segments and high frequency reports (5-20Hz).
void report_realtime_status(uint8_t client) { 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]; float print_position[MAX_N_AXIS];
char status[200]; char status[200];
char temp[MAX_N_AXIS * 20]; 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, "<"); strcpy(status, "<");
switch (sys.state) { strcat(status, report_state_text());
case State::Idle:
strcat(status, "Idle"); // Report position
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
if (bit_istrue(status_mask->get(), RtStatus::Position)) { if (bit_istrue(status_mask->get(), RtStatus::Position)) {
calc_mpos(print_position);
strcat(status, "|MPos:"); strcat(status, "|MPos:");
} else { } else {
calc_wpos(print_position);
strcat(status, "|WPos:"); strcat(status, "|WPos:");
} }
report_util_axis_values(print_position, temp); 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. sys.report_ovr_counter = 1; // Set override on next report.
} }
strcat(status, "|WCO:"); strcat(status, "|WCO:");
report_util_axis_values(wco, temp); report_util_axis_values(get_wco(), temp);
strcat(status, temp); strcat(status, temp);
} }
#endif #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); 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) { char report_get_axis_letter(uint8_t axis) {
switch (axis) { switch (axis) {
case X_AXIS: case X_AXIS:
@@ -960,4 +978,37 @@ void reportTaskStackSize(UBaseType_t& saved) {
#endif #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 void __attribute__((weak)) forward_kinematics(float* position) {} // This version does nothing. Make your own to do something with it

View File

@@ -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. // Prints an echo of the pre-parsed line received right before execution.
void report_echo_line_received(char* line, uint8_t client); 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 // Prints realtime status report
void report_realtime_status(uint8_t client); 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(char* buf, const char* prefix, int len);
void report_hex_msg(uint8_t* 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* reportAxisLimitsMsg(uint8_t axis);
char* reportAxisNameMsg(uint8_t axis); char* reportAxisNameMsg(uint8_t axis);
char* reportAxisNameMsg(uint8_t axis, uint8_t dual_axis); char* reportAxisNameMsg(uint8_t axis, uint8_t dual_axis);
void reportTaskStackSize(UBaseType_t& saved); void reportTaskStackSize(UBaseType_t& saved);
char* report_state_text();
float* get_wco();
void calc_mpos(float* print_position);
void calc_wpos(float* print_position);