Skip to content

Commit

Permalink
Changed workings of VFD code, added H2A VFD (#544)
Browse files Browse the repository at this point in the history
* Renamed Huanyang to VFD for H2A work

* Fixed Huanyang spindle implementation again.
Fixed includes in vcxproj generator

* Changed the VFD implementation. Implemented H2A along the way.
UNTESTED!

* Fixed retry loop in VFD. Added SettingsDefinition. Fixed name conflict within GRBL (`init()`).

* Added VFD_DEBUG_MODE.

* Fixed usability of VFD_DEBUG_MODE. Added a TODO in the H2ASpindle code.
Removed it from the test machine config

* Fixed bug in VFD spindle: the uart should be set up first, before running the rs485 task.

* Fixed bug in VFD_DEBUG_MODE output. Fixed bug in RX length of set_speed command for Huanyang VFD.

* Fixed a bug in the spindle code with states. Also, VFD didn't update state correctly.
Updated TODO/FIXME

* Added some more functionality to the Null spindle, to aid testing purposes.
Fixed report compatibility with vanilla grbl. Some values were reported in a slightly different format.

* Fixed commands.h

* Fixed review by Mitch

Co-authored-by: Stefan de Bruijn <stefan@nubilosoft.com>
  • Loading branch information
atlaste and Stefan de Bruijn committed Aug 16, 2020
1 parent 4c0edf9 commit a436ddf
Show file tree
Hide file tree
Showing 16 changed files with 1,073 additions and 413 deletions.
71 changes: 71 additions & 0 deletions Grbl_Esp32/src/Machines/3axis_rs485.h
@@ -0,0 +1,71 @@
#pragma once
// clang-format off

/*
3axis_xyx.h
Part of Grbl_ESP32
This is a general XYZ-axis RS-485 CNC machine. The schematic is quite
easy, you basically need a MAX485 wired through a logic level converter
for the VFD, and a few pins wired through an ULN2803A to the external
stepper drivers. It's common to have a dual gantry for the Y axis.
Optional limit pins are slightly more difficult, as these require a
Schmitt trigger and optocouplers.
2020 - Stefan de Bruijn
Grbl_ESP32 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl_ESP32. If not, see <http://www.gnu.org/licenses/>.
*/

#define MACHINE_NAME "ESP32_XYZ_RS485"
#define X_STEP_PIN GPIO_NUM_4 // labeled X
#define X_DIRECTION_PIN GPIO_NUM_16 // labeled X
#define Y_STEP_PIN GPIO_NUM_17 // labeled Y
#define Y_DIRECTION_PIN GPIO_NUM_18 // labeled Y
#define Y2_STEP_PIN GPIO_NUM_19 // labeled Y2
#define Y2_DIRECTION_PIN GPIO_NUM_21 // labeled Y2
#define Z_STEP_PIN GPIO_NUM_22 // labeled Z
#define Z_DIRECTION_PIN GPIO_NUM_23 // labeled Z

#define SPINDLE_TYPE SPINDLE_TYPE_H2A
#define VFD_RS485_TXD_PIN GPIO_NUM_13 // RS485 TX
#define VFD_RS485_RTS_PIN GPIO_NUM_15 // RS485 RTS
#define VFD_RS485_RXD_PIN GPIO_NUM_2 // RS485 RX

#define X_LIMIT_PIN GPIO_NUM_33
#define Y_LIMIT_PIN GPIO_NUM_32
#define Y2_LIMIT_PIN GPIO_NUM_35
#define Z_LIMIT_PIN GPIO_NUM_34

#ifdef HOMING_CYCLE_0
#undef HOMING_CYCLE_0
#endif
#define HOMING_CYCLE_0 bit(Z_AXIS) // Z first

#ifdef HOMING_CYCLE_1
#undef HOMING_CYCLE_1
#endif
#define HOMING_CYCLE_1 (bit(X_AXIS)|bit(Y_AXIS))

#ifdef HOMING_CYCLE_2
#undef HOMING_CYCLE_2
#endif

#define PROBE_PIN GPIO_NUM_14 // labeled Probe
#define CONTROL_RESET_PIN GPIO_NUM_27 // labeled Reset
#define CONTROL_FEED_HOLD_PIN GPIO_NUM_26 // labeled Hold
#define CONTROL_CYCLE_START_PIN GPIO_NUM_25 // labeled Start

// #define VFD_DEBUG_MODE
6 changes: 3 additions & 3 deletions Grbl_Esp32/src/Machines/4axis_external_driver.h
Expand Up @@ -51,9 +51,9 @@


#define SPINDLE_TYPE SPINDLE_TYPE_HUANYANG // only one spindle at a time
#define HUANYANG_TXD_PIN GPIO_NUM_17
#define HUANYANG_RXD_PIN GPIO_NUM_4
#define HUANYANG_RTS_PIN GPIO_NUM_16
#define VFD_RS485_TXD_PIN GPIO_NUM_17
#define VFD_RS485_RXD_PIN GPIO_NUM_4
#define VFD_RS485_RTS_PIN GPIO_NUM_16

#define X_LIMIT_PIN GPIO_NUM_34
#define Y_LIMIT_PIN GPIO_NUM_35
Expand Down
6 changes: 3 additions & 3 deletions Grbl_Esp32/src/Machines/6_pack_stepstick_v1.h
Expand Up @@ -123,9 +123,9 @@

// RS485 In socket #3
#define SPINDLE_TYPE SPINDLE_TYPE_HUANYANG // only one spindle at a time
#define HUANYANG_TXD_PIN GPIO_NUM_26
#define HUANYANG_RTS_PIN GPIO_NUM_4
#define HUANYANG_RXD_PIN GPIO_NUM_16
#define VFD_RS485_TXD_PIN GPIO_NUM_26
#define VFD_RS485_RTS_PIN GPIO_NUM_4
#define VFD_RS485_RXD_PIN GPIO_NUM_16



Expand Down
2 changes: 1 addition & 1 deletion Grbl_Esp32/src/Report.cpp
Expand Up @@ -386,7 +386,7 @@ void report_gcode_modes(uint8_t client) {
strcat(modes_rpt, temp);
sprintf(temp, report_inches->get() ? " F%.1f" : " F%.0f", gc_state.feed_rate);
strcat(modes_rpt, temp);
sprintf(temp, " S%4.3f", gc_state.spindle_speed);
sprintf(temp, " S%d", uint32_t(gc_state.spindle_speed));
strcat(modes_rpt, temp);
strcat(modes_rpt, "]\r\n");
grbl_send(client, modes_rpt);
Expand Down
1 change: 1 addition & 0 deletions Grbl_Esp32/src/SettingsDefinitions.cpp
Expand Up @@ -62,6 +62,7 @@ enum_opt_t spindleTypes = {
{ "HUANYANG", SPINDLE_TYPE_HUANYANG },
{ "BESC", SPINDLE_TYPE_BESC },
{ "10V", SPINDLE_TYPE_10V },
{ "H2A", SPINDLE_TYPE_H2A },
// clang-format on
};

Expand Down
148 changes: 148 additions & 0 deletions Grbl_Esp32/src/Spindles/H2ASpindle.cpp
@@ -0,0 +1,148 @@
#include "H2ASpindle.h"

/*
H2ASpindle.cpp
This is for the new H2A H2A VFD based spindle via RS485 Modbus.
Part of Grbl_ESP32
2020 - Stefan de Bruijn
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
WARNING!!!!
VFDs are very dangerous. They have high voltages and are very powerful
Remove power before changing bits.
The documentation is okay once you get how it works, but unfortunately
incomplete... See H2ASpindle.md for the remainder of the docs that I
managed to piece together.
*/

#include <driver/uart.h>

namespace Spindles {
void H2A::default_modbus_settings(uart_config_t& uart) {
// sets the uart to 19200 8E1
VFD::default_modbus_settings(uart);

uart.baud_rate = 19200;
uart.data_bits = UART_DATA_8_BITS;
uart.parity = UART_PARITY_EVEN;
uart.stop_bits = UART_STOP_BITS_1;
}

void H2A::direction_command(uint8_t mode, ModbusCommand& data) {
// NOTE: data length is excluding the CRC16 checksum.
data.tx_length = 6;
data.rx_length = 6;

data.msg[1] = 0x06; // WRITE
data.msg[2] = 0x20; // Command ID 0x2000
data.msg[3] = 0x00;
data.msg[4] = 0x00;
data.msg[5] = (mode == SPINDLE_ENABLE_CCW) ? 0x02 : (mode == SPINDLE_ENABLE_CW ? 0x01 : 0x06);
}

void H2A::set_speed_command(uint32_t rpm, ModbusCommand& data) {
// NOTE: data length is excluding the CRC16 checksum.
data.tx_length = 6;
data.rx_length = 6;

// We have to know the max RPM before we can set the current RPM:
auto max_rpm = this->_max_rpm;

// Speed is in [0..10'000] where 10'000 = 100%.
// We have to use a 32-bit integer here; typical values are 10k/24k rpm.
// I've never seen a 400K RPM spindle in my life, and they aren't supported
// by this modbus protocol anyways... So I guess this is OK.
uint16_t speed = (uint32_t(rpm) * 10000L) / uint32_t(max_rpm);
if (speed < 0) {
speed = 0;
}
if (speed > 10000) {
speed = 10000;
}

data.msg[1] = 0x06; // WRITE
data.msg[2] = 0x10; // Command ID 0x1000
data.msg[3] = 0x00;
data.msg[4] = uint8_t(speed >> 8); // RPM
data.msg[5] = uint8_t(speed & 0xFF);
}

H2A::response_parser H2A::get_max_rpm(ModbusCommand& data) {
// NOTE: data length is excluding the CRC16 checksum.
data.tx_length = 6;
data.rx_length = 8;

// Send: 01 03 B005 0002
data.msg[1] = 0x03; // READ
data.msg[2] = 0xB0; // B0.05 = Get RPM
data.msg[3] = 0x05;
data.msg[4] = 0x00; // Read 2 values
data.msg[5] = 0x02;

// Recv: 01 03 00 04 5D C0 03 F6
// -- -- = 24000 (val #1)
return [](const uint8_t* response, Spindles::VFD* vfd) -> bool {
uint16_t rpm = (uint16_t(response[4]) << 8) | uint16_t(response[5]);
vfd->_max_rpm = rpm;

grbl_msg_sendf(CLIENT_SERIAL, MSG_LEVEL_INFO, "H2A spindle is initialized at %d RPM", int(rpm));

return true;
};
}

H2A::response_parser H2A::get_current_rpm(ModbusCommand& data) {
// NOTE: data length is excluding the CRC16 checksum.
data.tx_length = 6;
data.rx_length = 8;

// Send: 01 03 700C 0002
data.msg[1] = 0x03; // READ
data.msg[2] = 0x70; // B0.05 = Get RPM
data.msg[3] = 0x0C;
data.msg[4] = 0x00; // Read 2 values
data.msg[5] = 0x02;

// Recv: 01 03 0004 095D 0000
// ---- = 2397 (val #1)

// TODO: What are we going to do with this? Update sys.spindle_speed? Update vfd state?
return [](const uint8_t* response, Spindles::VFD* vfd) -> bool {
uint16_t rpm = (uint16_t(response[4]) << 8) | uint16_t(response[5]);
// Set current RPM value? Somewhere?
return true;
};
}

H2A::response_parser H2A::get_current_direction(ModbusCommand& data) {
// NOTE: data length is excluding the CRC16 checksum.
data.tx_length = 6;
data.rx_length = 6;

// Send: 01 03 30 00 00 01
data.msg[1] = 0x03; // READ
data.msg[2] = 0x30; // Command group ID
data.msg[3] = 0x00;
data.msg[4] = 0x00; // Message ID
data.msg[5] = 0x01;

// Receive: 01 03 00 02 00 02
// ----- status

// TODO: What are we going to do with this? Update sys.spindle_speed? Update vfd state?
return [](const uint8_t* response, Spindles::VFD* vfd) -> bool { return true; };
}
}
37 changes: 37 additions & 0 deletions Grbl_Esp32/src/Spindles/H2ASpindle.h
@@ -0,0 +1,37 @@
#pragma once

#include "VFDSpindle.h"

/*
H2ASpindle.h
Part of Grbl_ESP32
2020 - Stefan de Bruijn
Grbl is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Grbl is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Grbl. If not, see <http://www.gnu.org/licenses/>.
*/

namespace Spindles {
class H2A : public VFD {
protected:
void default_modbus_settings(uart_config_t& uart) override;

void direction_command(uint8_t mode, ModbusCommand& data) override;
void set_speed_command(uint32_t rpm, ModbusCommand& data) override;

response_parser get_max_rpm(ModbusCommand& data) override;
response_parser get_current_rpm(ModbusCommand& data) override;
response_parser get_current_direction(ModbusCommand& data) override;
response_parser get_status_ok(ModbusCommand& data) override { return nullptr; }
};
}

0 comments on commit a436ddf

Please sign in to comment.