Preliminary FR-D700 VFD support, modbus ignore leading zeros, Fix for modbus read...
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 8 May 2018 23:37:17 +0000 (16:37 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 8 May 2018 23:38:16 +0000 (16:38 -0700)
CHANGELOG.md
package.json
src/avr/src/config.h
src/avr/src/modbus.c
src/avr/src/modbus.h
src/avr/src/spindle.h
src/avr/src/vfd_spindle.c
src/avr/src/vfd_test.c
src/jade/templates/control-view.jade
src/jade/templates/indicators.jade
src/resources/config-template.json

index df8a88f3d067849799f3bb201d059e944f6cd5a3..6f3be1878a1190f1ec6d3bd37a7fd3438e8f8bca 100644 (file)
@@ -1,6 +1,11 @@
 Buildbotics CNC Controller Firmware Changelog
 ==============================================
 
+## v0.3.23
+ - Fix for modbus read operation.
+ - Finalized AC-Tech VFD support.
+ - Preliminary FR-D700 VFD support.
+
 ## v0.3.22
  - Fix position loss after program pause.  #130
  - Correctly handle disabled axes.
index 4678b1532e54ea5e88b366b491b80b1fb2a49cac..648aca8248a868ded5cbfa446de5c073ae81b587 100644 (file)
@@ -1,6 +1,6 @@
 {
   "name": "bbctrl",
-  "version": "0.3.22",
+  "version": "0.3.23",
   "homepage": "http://buildbotics.com/",
   "repository": "https://github.com/buildbotics/bbctrl-firmware",
   "license": "GPL-3.0+",
index eb254c3e5d2dc146028e477aaae1800a07529f74..fd38b01245c460c78e581192f683f8c139e5eb52 100644 (file)
@@ -183,9 +183,9 @@ enum {
 
 
 // Modbus settings
-#define MODBUS_TIMEOUT           50  // ms. response timeout
+#define MODBUS_TIMEOUT           100 // ms. response timeout
 #define MODBUS_RETRIES           4   // Number of retries before failure
-#define MODBUS_BUF_SIZE            // Max bytes in rx/tx buffers
+#define MODBUS_BUF_SIZE          18  // Max bytes in rx/tx buffers
 #define VFD_QUERY_DELAY          100 // ms
 
 // Serial settings
index be3840053d1dd3958c7ae91332d0671299e9da0a..f3c1af5880816ee007ed0d1a0d45585a8c8d4f2a 100644 (file)
@@ -211,7 +211,10 @@ ISR(RS485_TXC_vect) {
 
 /// Data received interrupt
 ISR(RS485_RXC_vect) {
-  state.response[state.bytes++] = RS485_PORT.DATA;
+  state.response[state.bytes] = RS485_PORT.DATA;
+
+  // Ignore leading zeros
+  if (state.bytes || state.response[0]) state.bytes++;
 
   if (state.bytes == state.response_length) {
     _set_rxc_interrupt(false);
@@ -223,8 +226,10 @@ ISR(RS485_RXC_vect) {
 
 
 static void _read_cb(uint8_t func, uint8_t bytes, const uint8_t *data) {
-  if (func == MODBUS_READ_OUTPUT_REG && bytes == 3 && data[0] == 2) {
-    if (state.rw_cb) state.rw_cb(true, state.addr, _read_word(data, false));
+  if (func == MODBUS_READ_OUTPUT_REG && data[0] == bytes - 1) {
+    if (state.rw_cb)
+      for (uint8_t i = 0; i < bytes >> 1; i++)
+        state.rw_cb(true, state.addr + i, _read_word(data + i * 2 + 1, false));
     return;
   }
 
@@ -379,12 +384,13 @@ void modbus_func(uint8_t func, uint8_t send, const uint8_t *data,
 }
 
 
-void modbus_read(uint16_t addr, modbus_rw_cb_t cb) {
+void modbus_read(uint16_t addr, uint16_t count, modbus_rw_cb_t cb) {
   state.rw_cb = cb;
   state.addr = addr;
-  uint8_t cmd[4] = {0, 0, 0, 1};
+  uint8_t cmd[4];
   _write_word(cmd, addr, false);
-  modbus_func(MODBUS_READ_OUTPUT_REG, 4, cmd, 3, _read_cb);
+  _write_word(cmd + 2, count, false);
+  modbus_func(MODBUS_READ_OUTPUT_REG, 4, cmd, 2 * count + 1, _read_cb);
 }
 
 
index 42a7de2f48afb9d356cf7c7bdbfb5f4f517658c9..90cdb12f1da3e4fc7a3f94cf8cba30de8ba2951a 100644 (file)
@@ -106,6 +106,6 @@ void modbus_deinit();
 bool modbus_busy();
 void modbus_func(uint8_t func, uint8_t send, const uint8_t *data,
                  uint8_t receive, modbus_cb_t cb);
-void modbus_read(uint16_t addr, modbus_rw_cb_t cb);
+void modbus_read(uint16_t addr, uint16_t count, modbus_rw_cb_t cb);
 void modbus_write(uint16_t addr, uint16_t value, modbus_rw_cb_t cb);
 void modbus_rtc_callback();
index b1dd5ce70135fd445ad975a346fa71b24bad3b84..2dba5ea31ab07bd27674dd3ec34559cff0f41b79 100644 (file)
@@ -38,6 +38,7 @@ typedef enum {
   SPINDLE_TYPE_CUSTOM,
   SPINDLE_TYPE_YL600,
   SPINDLE_TYPE_AC_TECH,
+  SPINDLE_TYPE_FR_D700,
 } spindle_type_t;
 
 
index ddfc790d32a7ad8347e9283e3cafed4565c324e5..9ad646038dea711baa91afb6502e4fdfb40857ca 100644 (file)
@@ -53,6 +53,7 @@ typedef enum {
 
   REG_FREQ_READ,
   REG_FREQ_SIGN_READ,
+  REG_FREQ_ACTECH_READ,
 
   REG_DISCONNECT_WRITE,
 } vfd_reg_type_t;
@@ -85,17 +86,28 @@ const vfd_reg_t yl600_regs[] PROGMEM = {
 
 // NOTE, Modbus reg = AC Tech reg + 1
 const vfd_reg_t ac_tech_regs[] PROGMEM = {
-  {REG_CONNECT_WRITE,    49,   19}, // Password unlock
-  {REG_CONNECT_WRITE,     2,  512}, // Manual mode
-  {REG_MAX_FREQ_READ,    63,    0}, // Max frequency
-  {REG_FREQ_SET,         41,    0}, // Frequency
-  {REG_STOP_WRITE,        2,    4}, // Stop drive
-  {REG_FWD_WRITE,         2,  128}, // Forward
-  {REG_FWD_WRITE,         2,    8}, // Start drive
-  {REG_REV_WRITE,         2,   64}, // Reverse
-  {REG_REV_WRITE,         2,    8}, // Start drive
-  {REG_FREQ_READ,        26,    0}, // Actual speed
-  {REG_DISCONNECT_WRITE,  2,    2}, // Lock controls and parameters
+  {REG_CONNECT_WRITE,    48,   19}, // Password unlock
+  {REG_CONNECT_WRITE,     1,  512}, // Manual mode
+  {REG_MAX_FREQ_READ,    62,    0}, // Max frequency
+  {REG_FREQ_SET,         40,    0}, // Frequency
+  {REG_STOP_WRITE,        1,    4}, // Stop drive
+  {REG_FWD_WRITE,         1,  128}, // Forward
+  {REG_FWD_WRITE,         1,    8}, // Start drive
+  {REG_REV_WRITE,         1,   64}, // Reverse
+  {REG_REV_WRITE,         1,    8}, // Start drive
+  {REG_FREQ_ACTECH_READ, 24,    0}, // Actual speed
+  {REG_DISCONNECT_WRITE,  1,    2}, // Lock controls and parameters
+  {REG_DISABLED},
+};
+
+
+const vfd_reg_t fr_d700_regs[] PROGMEM = {
+  {REG_MAX_FREQ_READ,  1000,    0}, // Max frequency
+  {REG_FREQ_SET,         13,    0}, // Frequency
+  {REG_STOP_WRITE,        8,    1}, // Stop drive
+  {REG_FWD_WRITE,         8,    2}, // Forward
+  {REG_REV_WRITE,         8,    4}, // Reverse
+  {REG_FREQ_READ,       200,    0}, // Output freq
   {REG_DISABLED},
 };
 
@@ -106,6 +118,7 @@ static vfd_reg_t custom_regs[VFDREG];
 static struct {
   vfd_reg_type_t state;
   int8_t reg;
+  uint8_t read_count;
   bool changed;
   bool shutdown;
 
@@ -127,6 +140,11 @@ static void _disconnected() {
 
 static bool _next_state() {
   switch (vfd.state) {
+  case REG_MAX_FREQ_FIXED:
+    if (!vfd.speed) vfd.state = REG_STOP_WRITE;
+    else vfd.state = REG_FREQ_SET;
+    break;
+
   case REG_FREQ_SIGN_SET:
     if (vfd.speed < 0) vfd.state = REG_REV_WRITE;
     else if (0 < vfd.speed) vfd.state = REG_FWD_WRITE;
@@ -137,7 +155,7 @@ static bool _next_state() {
     vfd.state = REG_FREQ_READ;
     break;
 
-  case REG_FREQ_SIGN_READ:
+  case REG_FREQ_ACTECH_READ:
     if (vfd.shutdown) vfd.state = REG_DISCONNECT_WRITE;
 
     else if (vfd.changed) {
@@ -174,6 +192,7 @@ static void _next_reg() {
 
     if (vfd.reg == VFDREG) {
       vfd.reg = -1;
+      vfd.read_count = 0;
       if (!_next_state()) break;
 
     } else if (regs[vfd.reg].type == vfd.state && _exec_command()) break;
@@ -197,6 +216,8 @@ static void _modbus_cb(bool ok, uint16_t addr, uint16_t value) {
   }
 
   // Handle read result
+  vfd.read_count++;
+
   switch (regs[vfd.reg].type) {
   case REG_MAX_FREQ_READ: vfd.max_freq = value; break;
   case REG_FREQ_READ: vfd.actual_speed = value / (float)vfd.max_freq; break;
@@ -205,6 +226,11 @@ static void _modbus_cb(bool ok, uint16_t addr, uint16_t value) {
     vfd.actual_speed = (int16_t)value / (float)vfd.max_freq;
     break;
 
+  case REG_FREQ_ACTECH_READ:
+    if (vfd.read_count == 2) vfd.actual_speed = value / (float)vfd.max_freq;
+    if (vfd.read_count < 6) return;
+    break;
+
   default: break;
   }
 
@@ -217,6 +243,7 @@ static bool _exec_command() {
   if (vfd.wait) return true;
 
   vfd_reg_t reg = regs[vfd.reg];
+  uint16_t words = 1;
   bool read = false;
   bool write = false;
 
@@ -243,6 +270,9 @@ static bool _exec_command() {
     write = true;
     break;
 
+  case REG_FREQ_ACTECH_READ:
+    words = 6;
+
   case REG_FREQ_READ:
   case REG_FREQ_SIGN_READ:
   case REG_MAX_FREQ_READ:
@@ -250,7 +280,7 @@ static bool _exec_command() {
     break;
   }
 
-  if (read) modbus_read(reg.addr, _modbus_cb);
+  if (read) modbus_read(reg.addr, words, _modbus_cb);
   else if (write) modbus_write(reg.addr, reg.value, _modbus_cb);
   else return false;
 
@@ -278,6 +308,7 @@ void vfd_spindle_init() {
   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;
   default: break;
   }
 
index 318d3026af7304389cffee7ac2a5cbce368774da..309aa6da9c5e3fc4ddcea1e131cde1bb06117b4b 100644 (file)
@@ -106,7 +106,7 @@ void command_modbus_read_exec(void *data) {
   uint16_t addr = *(uint16_t *)data;
 
   vt.waiting = true;
-  modbus_read(addr, _modbus_rw_cb);
+  modbus_read(addr, 1, _modbus_rw_cb);
   exec_set_cb(_modbus_cmd_exec);
 }
 
index 6ebb988d3b3de28e437d64ce2fe04cbdc6d11585..ee9f84e1809ef678dc615c635dc382c3888b9481 100644 (file)
@@ -124,7 +124,7 @@ script#control-view-template(type="text/x-template")
         td mm/min
       tr
         th Speed
-        td {{state.speed || 0 | fixed 0}}
+        td {{state.speed || 0 | fixed 0}} ({{state.s || 0 | fixed 0}})
         td RPM
 
     table.info
index 511a4ffac8bd76e8b1ba47544d6accb5ccf8f866..36cdc0633561473126bb1aa91f1212b120dfe6a7 100644 (file)
@@ -167,9 +167,9 @@ script#indicators-template(type="text/x-template")
         td {{state['2ai'] | percent 0}} A
         th Analog 2
 
-    table.rs485
+    table.modbus
       tr
-        th.header(colspan=5) RS485 Spindle
+        th.header(colspan=5) Modbus VFD
 
       tr
         th(colspan=5) {{modbus_status}}
index d985dfc019c61093696561fd5182e302626ececd..6da0be181cb646643ca946eb4cbad366cc692320 100644 (file)
     "tool-type": {
       "type": "enum",
       "values": ["Disabled", "PWM Spindle", "Huanyang VFD", "VFD Test",
-                 "Custom Modbus VFD", "YL600 VFD", "AC-Tech VFD"],
+                 "Custom Modbus VFD", "YL600 VFD", "AC-Tech VFD", "FR-D700"],
       "default": "Disabled",
       "code": "st"
     },
             "max-freq-read", "max-freq-fixed",
             "freq-set", "freq-signed-set",
             "stop-write", "forward-write", "reverse-write",
-            "freq-read", "freq-signed-read",
+            "freq-read", "freq-signed-read", "freq-actech-read",
             "disconnect-write"],
           "default": "disabled",
           "code": "vt"