Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Changrong electric H100 spindle support #1598

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Grbl_Esp32/src/SettingsDefinitions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum_opt_t spindleTypes = {
{ "10V", int8_t(SpindleType::_10V) },
{ "H2A", int8_t(SpindleType::H2A) },
{ "YL620", int8_t(SpindleType::YL620) },
{ "H100", int8_t(SpindleType::H100) },
// clang-format on
};

Expand Down
145 changes: 145 additions & 0 deletions Grbl_Esp32/src/Spindles/H100Spindle.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
#include "H100Spindle.h"

/*
H100Spindle.cpp
This is for a Changrong Electric H100 VFD based spindle to be controlled via RS485 Modbus RTU.
Part of Grbl_ESP32
2024 - Jaka Kordez
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.
*/

namespace Spindles {
H100::H100() : VFD() {}

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

// data.msg[0] is omitted (modbus address is filled in later)
data.msg[1] = 0x06; // 06: write single holding register
data.msg[2] = 0x02; // 0x200: main control bit
data.msg[3] = 0x00;

switch (mode) {
case SpindleState::Cw:
data.msg[4] = 0x00;
data.msg[5] = 0x03;
break;
case SpindleState::Ccw:
data.msg[4] = 0x00;
data.msg[5] = 0x05;
break;
default: // SpindleState::Disable
data.msg[4] = 0x00;
data.msg[5] = 0x08;
break;
}
}

void H100::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;
auto max_frequency = this->_maxFrequency;

uint16_t freqFromRPM = (uint16_t(rpm) * uint16_t(max_frequency)) / uint16_t(max_rpm);

#ifdef VFD_DEBUG_MODE
grbl_msg_sendf(CLIENT_SERIAL, MsgLevel::Info, "For %d RPM the output frequency is set to %d Hz*10", int(rpm), int(freqFromRPM));
#endif

data.msg[1] = 0x06; // 06: write single holding register
data.msg[2] = 0x02; // 0x0201: given frequency
data.msg[3] = 0x01;
data.msg[4] = uint8_t(freqFromRPM >> 8);
data.msg[5] = uint8_t(freqFromRPM & 0xFF);
}

VFD::response_parser H100::initialization_sequence(int index, ModbusCommand& data) {
this->_min_rpm = 0;
this->_max_rpm = 24000;

return nullptr;
}

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

// Send: 01 04 0000 0001
data.msg[1] = 0x04; // 0x04: read input register
data.msg[2] = 0x00; // 0x0000: register address
data.msg[3] = 0x00;
data.msg[4] = 0x00; // 0x0001: read 1 byte
data.msg[5] = 0x01;

// Recv: 01 04 02 xx xx
// ---- = 1500
return [](const uint8_t* response, Spindles::VFD* vfd) -> bool {
uint16_t freq = (uint16_t(response[3]) << 8) | uint16_t(response[4]);

auto h100 = static_cast<H100*>(vfd);

uint16_t rpm = freq * uint16_t(vfd->_max_rpm) / uint16_t(h100->_maxFrequency);

// Set current RPM value? Somewhere?
vfd->_sync_rpm = rpm;
return true;
};
}

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

// Send: 01 03 0210 0001
data.msg[1] = 0x03; // 0x03: read holding register
data.msg[2] = 0x02; // 0x0210: in forward/reverse rotation
data.msg[3] = 0x10;
data.msg[4] = 0x00; // 0x0001: read 1 byte
data.msg[5] = 0x01;

// 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 {
uint8_t status = response[4];

if (status & 0x9) {
// Operation: ON
if (status & 0x2) {
// Direction: Reverse
}
else {
// Direction: Forward
}
}
else {
// Operation: OFF
}

return true;
};
}
}
44 changes: 44 additions & 0 deletions Grbl_Esp32/src/Spindles/H100Spindle.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include "VFDSpindle.h"

/*
H100Spindle.h
Part of Grbl_ESP32
2024 - Jaka Kordez
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 H100 : public VFD {
protected:
uint16_t _minFrequency = 0; // frequency lower limit. Factor 10 of actual frequency
uint16_t _maxFrequency = 4000; // max frequency the VFD will allow. Normally 400.0. Factor 10 of actual frequency

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

response_parser initialization_sequence(int index, 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; }

bool supports_actual_rpm() const override { return true; }
bool safety_polling() const override { return false; }

public:
H100();
};
}
5 changes: 5 additions & 0 deletions Grbl_Esp32/src/Spindles/Spindle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "BESCSpindle.h"
#include "10vSpindle.h"
#include "YL620Spindle.h"
#include "H100Spindle.h"
#include "TecoL510.h"

namespace Spindles {
Expand All @@ -55,6 +56,7 @@ namespace Spindles {
BESC besc;
_10v _10v;
YL620 yl620;
H100 h100;
L510 l510;

void Spindle::select() {
Expand Down Expand Up @@ -86,6 +88,9 @@ namespace Spindles {
case SpindleType::YL620:
spindle = &yl620;
break;
case SpindleType::H100:
spindle = &h100;
break;
case SpindleType::L510:
spindle = &l510;
break;
Expand Down
1 change: 1 addition & 0 deletions Grbl_Esp32/src/Spindles/Spindle.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum class SpindleType : int8_t {
_10V,
H2A,
YL620,
H100,
L510
};

Expand Down