{
"name": "bbctrl",
- "version": "0.3.25",
+ "version": "0.3.26",
"homepage": "http://buildbotics.com/",
"repository": "https://github.com/buildbotics/bbctrl-firmware",
"license": "GPL-3.0+",
//(CODE, NAME, SYNC)
CMD('$', var, 0) // Set or get variable
CMD('#', sync_var, 1) // Set variable synchronous
-CMD('m', modbus_read, 1) // [addr]
-CMD('M', modbus_write, 1) // [addr][value]
CMD('s', seek, 1) // [switch][flags:active|error]
CMD('a', set_axis, 1) // [axis][position] Set axis position
CMD('l', line, 1) // [targetVel][maxJerk][axes][times]
state.last_write = 0;
if (cfg.debug && state.bytes) {
- const uint8_t buf_len = 8 * 2 + 1;
- char sent[buf_len];
- char received[buf_len];
+ char sent[state.command_length * 2 + 1];
+ char received[state.bytes * 2 + 1];
format_hex_buf(sent, state.command, state.command_length);
format_hex_buf(received, state.response, state.bytes);
#include "pwm_spindle.h"
#include "huanyang.h"
#include "vfd_spindle.h"
-#include "vfd_test.h"
#include "config.h"
#include "pgmspace.h"
case SPINDLE_TYPE_DISABLED: break;
case SPINDLE_TYPE_PWM: pwm_spindle_set(speed); break;
case SPINDLE_TYPE_HUANYANG: huanyang_set(speed); break;
- case SPINDLE_TYPE_TEST: vfd_test_set(speed); break;
default: vfd_spindle_set(speed); break;
}
}
case SPINDLE_TYPE_DISABLED: break;
case SPINDLE_TYPE_PWM: speed = pwm_spindle_get(); break;
case SPINDLE_TYPE_HUANYANG: speed = huanyang_get(); break;
- case SPINDLE_TYPE_TEST: speed = vfd_test_get(); break;
default: speed = vfd_spindle_get(); break;
}
case SPINDLE_TYPE_DISABLED: break;
case SPINDLE_TYPE_PWM: pwm_spindle_stop(); break;
case SPINDLE_TYPE_HUANYANG: huanyang_stop(); break;
- case SPINDLE_TYPE_TEST: vfd_test_stop(); break;
default: vfd_spindle_stop(); break;
}
}
case SPINDLE_TYPE_DISABLED: break;
case SPINDLE_TYPE_PWM: pwm_spindle_init(); break;
case SPINDLE_TYPE_HUANYANG: huanyang_init(); break;
- case SPINDLE_TYPE_TEST: vfd_test_init(); break;
default: vfd_spindle_init(); break;
}
case SPINDLE_TYPE_DISABLED: _deinit_cb(); break;
case SPINDLE_TYPE_PWM: pwm_spindle_deinit(_deinit_cb); break;
case SPINDLE_TYPE_HUANYANG: huanyang_deinit(_deinit_cb); break;
- case SPINDLE_TYPE_TEST: vfd_test_deinit(_deinit_cb); break;
default: vfd_spindle_deinit(_deinit_cb); break;
}
}
SPINDLE_TYPE_DISABLED,
SPINDLE_TYPE_PWM,
SPINDLE_TYPE_HUANYANG,
- SPINDLE_TYPE_TEST,
SPINDLE_TYPE_CUSTOM,
- SPINDLE_TYPE_YL600,
SPINDLE_TYPE_AC_TECH,
+ SPINDLE_TYPE_DELTA_VFD015M21A,
+ SPINDLE_TYPE_YL600,
SPINDLE_TYPE_FR_D700,
} spindle_type_t;
VAR(modbus_baud, mb, u8, 0, 1, 1) // Modbus BAUD rate
VAR(modbus_parity, ma, u8, 0, 1, 1) // Modbus parity
VAR(modbus_status, mx, u8, 0, 0, 1) // Modbus status
-VAR(modbus_response, mr, u16, 0, 0, 1) // Modbus read response
// VFD spindle
VAR(vfd_max_freq, vf, u16, 0, 1, 1) // VFD maximum frequency
+VAR(vfd_status, vs, u16, 0, 0, 1) // VFD status
VAR(vfd_reg_type, vt, u8, VFDREG, 1, 1) // VFD register type
VAR(vfd_reg_addr, va, u16, VFDREG, 1, 1) // VFD register address
VAR(vfd_reg_val, vv, u16, VFDREG, 1, 1) // VFD register value
+VAR(vfd_reg_fails, vr, u8, VFDREG, 0, 1) // VFD register fail count
// Huanyang spindle
VAR(hy_freq, hz, f32, 0, 0, 1) // Huanyang actual freq
REG_FREQ_SIGN_READ,
REG_FREQ_ACTECH_READ,
+ REG_STATUS_READ,
+
REG_DISCONNECT_WRITE,
} vfd_reg_type_t;
vfd_reg_type_t type;
uint16_t addr;
uint16_t value;
+ uint8_t fails;
} vfd_reg_t;
#define P(H, L) ((H) << 8 | (L))
-const vfd_reg_t yl600_regs[] PROGMEM = {
- {REG_CONNECT_WRITE, P(7, 8), 1}, // P07_08_FREQ_SOURCE_1
- {REG_CONNECT_WRITE, P(0, 1), 1}, // P00_01_START_STOP_SOURCE
- {REG_MAX_FREQ_READ, P(0, 4), 0}, // P00_04_HIGEST_OUTPUT_FREQ
- {REG_FREQ_SET, P(7, 0), 0}, // P07_00_FREQ_1
-// {REG_STOP_WRITE, P(?, ?), ?}, //
-// {REG_FWD_WRITE, P(1, 0), ?}, // P01_00_DIRECTION
-// {REG_REV_WRITE, P(?, ?), ?}, //
- {REG_FREQ_READ, P(0, 0), 0}, // P00_00_MAIN_FREQ
- {REG_DISCONNECT_WRITE, P(0, 1), 0}, // P00_01_START_STOP_SOURCE
- {REG_DISCONNECT_WRITE, P(7, 8), 0}, // P07_08_FREQ_SOURCE_1
- {REG_DISABLED},
-};
-
-
// NOTE, Modbus reg = AC Tech reg + 1
const vfd_reg_t ac_tech_regs[] PROGMEM = {
{REG_CONNECT_WRITE, 48, 19}, // Password unlock
};
+const vfd_reg_t delta_vfd015m21a_regs[] PROGMEM = {
+ {REG_CONNECT_WRITE, 0x2002, 2}, // Reset fault
+ {REG_MAX_FREQ_READ, 3, 0}, // Max frequency
+ {REG_FREQ_SET, 0x2001, 0}, // Frequency
+ {REG_STOP_WRITE, 0x2000, 1}, // Stop drive
+ {REG_FWD_WRITE, 0x2000, 18}, // Forward
+ {REG_REV_WRITE, 0x2000, 34}, // Reverse
+ {REG_FREQ_READ, 0x2103, 0}, // Output freq
+ {REG_STATUS_READ, 0x2100, 0}, // Status
+ {REG_DISABLED},
+};
+
+
+const vfd_reg_t yl600_regs[] PROGMEM = {
+ {REG_CONNECT_WRITE, P(7, 8), 1}, // P07_08_FREQ_SOURCE_1
+ {REG_CONNECT_WRITE, P(0, 1), 1}, // P00_01_START_STOP_SOURCE
+ {REG_MAX_FREQ_READ, P(0, 4), 0}, // P00_04_HIGEST_OUTPUT_FREQ
+ {REG_FREQ_SET, P(7, 0), 0}, // P07_00_FREQ_1
+// {REG_STOP_WRITE, P(?, ?), ?}, //
+// {REG_FWD_WRITE, P(1, 0), ?}, // P01_00_DIRECTION
+// {REG_REV_WRITE, P(?, ?), ?}, //
+ {REG_FREQ_READ, P(0, 0), 0}, // P00_00_MAIN_FREQ
+ {REG_DISCONNECT_WRITE, P(0, 1), 0}, // P00_01_START_STOP_SOURCE
+ {REG_DISCONNECT_WRITE, P(7, 8), 0}, // P07_08_FREQ_SOURCE_1
+ {REG_DISABLED},
+};
+
+
const vfd_reg_t fr_d700_regs[] PROGMEM = {
{REG_MAX_FREQ_READ, 1000, 0}, // Max frequency
{REG_FREQ_SET, 13, 0}, // Frequency
float speed;
uint16_t max_freq;
float actual_speed;
+ uint16_t status;
uint32_t wait;
deinit_cb_t deinit_cb;
vfd.state = REG_FREQ_READ;
break;
- case REG_FREQ_ACTECH_READ:
+ case REG_STATUS_READ:
if (vfd.shutdown || estop_triggered()) vfd.state = REG_DISCONNECT_WRITE;
else if (vfd.changed) {
static void _modbus_cb(bool ok, uint16_t addr, uint16_t value) {
// Handle error
if (!ok) {
+ if (regs[vfd.reg].fails < 255) regs[vfd.reg].fails++;
if (vfd.shutdown || estop_triggered()) _disconnected();
else _connect();
return;
if (vfd.read_count < 6) return;
break;
+ case REG_STATUS_READ: vfd.status = value; break;
+
default: break;
}
case REG_FREQ_READ:
case REG_FREQ_SIGN_READ:
case REG_MAX_FREQ_READ:
+ case REG_STATUS_READ:
read = true;
break;
}
switch (spindle_get_type()) {
case SPINDLE_TYPE_CUSTOM: memcpy(regs, custom_regs, sizeof(regs)); break;
- case SPINDLE_TYPE_YL600: _load(yl600_regs); break;
- case SPINDLE_TYPE_AC_TECH: _load(ac_tech_regs); break;
- case SPINDLE_TYPE_FR_D700: _load(fr_d700_regs); break;
+ case SPINDLE_TYPE_AC_TECH: _load(ac_tech_regs); break;
+ case SPINDLE_TYPE_DELTA_VFD015M21A: _load(delta_vfd015m21a_regs); break;
+ case SPINDLE_TYPE_YL600: _load(yl600_regs); break;
+ case SPINDLE_TYPE_FR_D700: _load(fr_d700_regs); break;
default: break;
}
// Variable callbacks
uint16_t get_vfd_max_freq() {return vfd.max_freq;}
void set_vfd_max_freq(uint16_t max_freq) {vfd.max_freq = max_freq;}
+uint16_t get_vfd_status() {return vfd.status;}
uint8_t get_vfd_reg_type(int reg) {return regs[reg].type;}
regs[reg].value = custom_regs[reg].value;
vfd.changed = true;
}
+
+
+uint8_t get_vfd_reg_fails(int reg) {return regs[reg].fails;}
+++ /dev/null
-/******************************************************************************\
-
- This file is part of the Buildbotics firmware.
-
- Copyright (c) 2015 - 2018, Buildbotics LLC
- All rights reserved.
-
- This file ("the software") is free software: you can redistribute it
- and/or modify it under the terms of the GNU General Public License,
- version 2 as published by the Free Software Foundation. You should
- have received a copy of the GNU General Public License, version 2
- along with the software. If not, see <http://www.gnu.org/licenses/>.
-
- The software 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the software. If not, see
- <http://www.gnu.org/licenses/>.
-
- For information regarding this software email:
- "Joseph Coffland" <joseph@buildbotics.com>
-
-\******************************************************************************/
-
-#include "vfd_test.h"
-#include "modbus.h"
-#include "status.h"
-#include "command.h"
-#include "type.h"
-#include "exec.h"
-
-#include <string.h>
-
-
-static struct {
- bool enabled;
- bool waiting;
- uint16_t read_response;
- deinit_cb_t deinit_cb;
-} vt;
-
-
-static void _shutdown() {
- if (vt.waiting || vt.enabled) return;
- modbus_deinit();
- if (vt.deinit_cb) vt.deinit_cb();
-}
-
-
-void vfd_test_init() {
- modbus_init();
- vt.enabled = true;
- vt.waiting = false;
-}
-
-
-void vfd_test_deinit(deinit_cb_t cb) {
- vt.enabled = false;
- vt.deinit_cb = cb;
- _shutdown();
-}
-
-
-void vfd_test_set(float speed) {}
-float vfd_test_get() {return 0;}
-void vfd_test_stop() {}
-
-
-// Variable callbacks
-uint16_t get_modbus_response() {return vt.read_response;}
-
-
-// Command callbacks
-static stat_t _modbus_cmd_exec() {
- if (vt.waiting) return STAT_NOP;
- exec_set_cb(0);
- return STAT_AGAIN;
-}
-
-
-static void _modbus_rw_cb(bool ok, uint16_t addr, uint16_t value) {
- vt.read_response = value; // Always zero on error
- vt.waiting = false;
- _shutdown();
-}
-
-
-stat_t command_modbus_read(char *cmd) {
- stat_t status = STAT_OK;
- uint16_t addr = type_parse_u16(cmd + 1, &status);
- if (status == STAT_OK) command_push(*cmd, &addr);
-
- return status;
-}
-
-
-unsigned command_modbus_read_size() {return sizeof(uint16_t);}
-
-
-void command_modbus_read_exec(void *data) {
- if (!vt.enabled) return;
-
- uint16_t addr = *(uint16_t *)data;
-
- vt.waiting = true;
- modbus_read(addr, 1, _modbus_rw_cb);
- exec_set_cb(_modbus_cmd_exec);
-}
-
-
-
-stat_t command_modbus_write(char *cmd) {
- // Get value
- char *value = strchr(cmd + 1, '=');
- if (!value) return STAT_INVALID_COMMAND;
- *value++ = 0;
-
- stat_t status = STAT_OK;
- uint16_t buffer[2];
- buffer[0] = type_parse_u16(cmd + 1, &status);
- if (status == STAT_OK) buffer[1] = type_parse_u16(value, &status);
-
- if (status == STAT_OK) command_push(*cmd, buffer);
-
- return status;
-}
-
-
-unsigned command_modbus_write_size() {return 2 * sizeof(uint16_t);}
-
-
-void command_modbus_write_exec(void *data) {
- if (!vt.enabled) return;
-
- uint16_t addr = ((uint16_t *)data)[0];
- uint16_t value = ((uint16_t *)data)[1];
-
- vt.waiting = true;
- modbus_write(addr, value, _modbus_rw_cb);
- exec_set_cb(_modbus_cmd_exec);
-}
+++ /dev/null
-/******************************************************************************\
-
- This file is part of the Buildbotics firmware.
-
- Copyright (c) 2015 - 2018, Buildbotics LLC
- All rights reserved.
-
- This file ("the software") is free software: you can redistribute it
- and/or modify it under the terms of the GNU General Public License,
- version 2 as published by the Free Software Foundation. You should
- have received a copy of the GNU General Public License, version 2
- along with the software. If not, see <http://www.gnu.org/licenses/>.
-
- The software 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the software. If not, see
- <http://www.gnu.org/licenses/>.
-
- For information regarding this software email:
- "Joseph Coffland" <joseph@buildbotics.com>
-
-\******************************************************************************/
-
-#pragma once
-
-#include "spindle.h"
-
-
-void vfd_test_init();
-void vfd_test_deinit(deinit_cb_t cb);
-void vfd_test_set(float speed);
-float vfd_test_get();
-void vfd_test_stop();
fieldset(v-if="is_modbus")
h2 Modbus Configuration
+ .pure-control-group
+ label status
+ tt {{modbus_status}}
templated-input(v-for="templ in template['modbus-spindle']",
:name="$key", :model.sync="config['modbus-spindle'][$key]",
:template="templ", v-if="$key != 'regs'")
- fieldset(v-if="tool_type == 'VFD TEST'")
- h2 Modbus Test
- table.modbus-regs
- tr
- th Address
- th Value
- th Action
- th Status
- tr
- td: input(name="address", type="text", v-model="address", number)
- td: input(name="value", type="text", v-model="value", number)
- td
- button.pure-button(@click="read") Read
- button.pure-button(@click="write") Write
- td.modbus-status {{modbus_status}}
-
fieldset.modbus-program(
v-if="is_modbus && this.tool_type != 'HUANYANG VFD'")
h2 Active Modbus Program
+ p
+ | (Click <tt class="save">Save</tt> to activate the selected
+ | <b>tool-type</b>.)
table.modbus-regs.fixed-regs
tr
th Index
th Command
th Address
th Value
+ th Failures
- tr(v-for="(index, reg) in regs_tmpl.index", v-if="state[reg + 'vt']")
+ tr(v-for="(index, reg) in regs_tmpl.index", v-if="state[reg + 'vt']",
+ :class="{warn: get_reg_fails(reg)}")
td.reg-index {{index}}
td.reg-type {{get_reg_type(reg)}}
td.reg-addr {{get_reg_addr(reg)}}
td.reg-value {{get_reg_value(reg)}}
+ td.reg-fails {{get_reg_fails(reg)}}
button.pure-button-secondary(@click="customize") Customize
button.pure-button-secondary(@click="clear") Clear
v-if="!index || reg['reg-type'] != 'disabled' || " +
"config['modbus-spindle'].regs[index - 1]['reg-type'] != " +
"'disabled'")
+
+ .notes(v-if="tool_type == 'HUANYANG VFD'")
+ h2 Notes
+ p Set the following using the VFD's frontpanel.
+ table.modbus-regs.fixed-regs
+ tr
+ th Address
+ th Value
+ td Meaning
+ th Description
+ tr
+ td.reg-addr PD000
+ td.reg-value 0
+ td Unlock
+ td Unlock parameters
+ tr
+ td.reg-addr PD001
+ td.reg-value 2
+ td RS485
+ td Command source
+ tr
+ td.reg-addr PD002
+ td.reg-value 2
+ td RS485
+ td Speed/frequency source
+ tr
+ td.reg-addr PD163
+ td.reg-value 1
+ td Modbus ID
+ td Must match <tt>bus-id</tt> above.
+ tr
+ td.reg-addr PD164
+ td.reg-value 1
+ td 9600 baud
+ td Must match <tt>baud</tt> above.
+ tr
+ td.reg-addr PD166
+ td.reg-value 3
+ td 8 bit, no parity, RTU mode
+ td Must match <tt>parity</tt> above.
+
+ p
+ | Other settings according to the <a
+ | href="https://buildbotics.com/upload/vfd/Huanyang-VFD-manual.pdf"
+ | target="_blank">Huanyang VFD manual</a> and spindle type.
+
+ .notes(v-if="tool_type.startsWith('DELTA VFD015M21A')")
+ h2 Notes
+ p Set the following using the VFD's frontpanel.
+ table.modbus-regs.fixed-regs
+ tr
+ th Address
+ th Value
+ th Meaning
+ th Description
+ tr
+ td.reg-addr Pr.00
+ td.reg-value 3
+ td RS-485
+ td Source of frequency command
+ tr
+ td.reg-addr Pr.01
+ td.reg-value 3
+ td RS-485 with STOP
+ td Source of operation command
+ tr
+ td.reg-addr Pr.88
+ td.reg-value 1
+ td Modbus ID
+ td Must match <tt>bus-id</tt> above
+ tr
+ td.reg-addr Pr.89
+ td.reg-value 1
+ td 9600 baud
+ td Must match <tt>baud</tt> above
+ tr
+ td.reg-addr Pr.92
+ td.reg-value 3
+ td 8 bit, no parity, RTU mode
+ td Must match <tt>parity</tt> above
+ tr
+ td.reg-addr Pr.157
+ td.reg-value 1
+ td Modbus mode
+ td Communication mode
+
+ p
+ | Other settings according to the <a
+ | href="https://buildbotics.com/upload/vfd/Delta_VFD015M21A.pdf"
+ | target="_blank">Delta VFD015M21A VFD manual</a> and spindle type.
get_reg_value: function (reg) {return this.state[reg + 'vv']},
+ get_reg_fails: function (reg) {
+ var fails = this.state[reg + 'vr']
+ return fails == 255 ? 'Max' : fails;
+ },
+
+
read: function (e) {
e.preventDefault();
api.put('modbus/read', {address: this.address});
if not 'code' in tmpl: return
if tmpl['type'] == 'enum':
- if value in tmpl['values']:
- value = tmpl['values'].index(value)
+ if value in tmpl['values']: value = tmpl['values'].index(value)
else: value = tmpl['default']
elif tmpl['type'] == 'bool': value = 1 if value else 0
"tool": {
"tool-type": {
"type": "enum",
- "values": ["Disabled", "PWM Spindle", "Huanyang VFD", "VFD Test",
- "Custom Modbus VFD", "YL600 VFD", "AC-Tech VFD", "FR-D700"],
+ "values": ["Disabled", "PWM Spindle", "Huanyang VFD", "Custom Modbus VFD",
+ "AC-Tech VFD", "Delta VFD015M21A (Beta)", "YL600 VFD (Beta)",
+ "FR-D700 (Beta)"],
"default": "Disabled",
"code": "st"
},
"freq-set", "freq-signed-set",
"stop-write", "forward-write", "reverse-write",
"freq-read", "freq-signed-read", "freq-actech-read",
+ "status-read",
"disconnect-write"],
"default": "disabled",
"code": "vt"
width 24em
height 12em
+ > select, > input:not([type=checkbox])
+ min-width 13em
+
+ > tt
+ min-width 15.25em
+ padding 0.7em 1em
+ border-radius 3px
+ display inline-block
+
@keyframes blink
50%
fill #ff9d00
&:hover
opacity 0.5
+tt.save
+ display inline-block
+ border-radius 2px
+ background #1cb841
+ color rgba(0, 0, 0, 0.8)
+ padding 0.25em
+ line-height initial
+
.modbus-program button
margin 0.25em 0
td.reg-index, td.reg-addr, td.reg-value
text-align right
- tr:nth-child(even)
+ tr:nth-child(even):not(.warn)
background-color #f3f3f3