From da8e241e536992da1b55d7785ee7af184241af0c Mon Sep 17 00:00:00 2001 From: "avery.babka" Date: Fri, 25 Jul 2025 14:06:16 -0500 Subject: [PATCH] Upload files to "/" --- Parms_ADI.h | 268 ++++++++++++++++++++++++++++++++++++++++++++ Parms_ADI.ino | 281 +++++++++++++++++++++++++++++++++++++++++++++++ platformio.ini | 6 + printControl.h | 19 ++++ printControl.ino | 133 ++++++++++++++++++++++ 5 files changed, 707 insertions(+) create mode 100644 Parms_ADI.h create mode 100644 Parms_ADI.ino create mode 100644 platformio.ini create mode 100644 printControl.h create mode 100644 printControl.ino diff --git a/Parms_ADI.h b/Parms_ADI.h new file mode 100644 index 0000000..abfe70f --- /dev/null +++ b/Parms_ADI.h @@ -0,0 +1,268 @@ +#ifndef Parms_ADI +#define Parms_ADI 1 + +#define PARMSIZE 140 +int32_t parm[PARMSIZE]; +int32_t tempParm[PARMSIZE]; // used to store parms of slave unit +int32_t remoteParm[PARMSIZE]; + +const int32_t parmlimits[][6] = // default, min, max, 1 = allow-default, 1 = needs-unlock-code + { + {0, 0, 2653999, 0, 0, 0}, // 0 Checksum + {0, 0, 2653999, 1, 0, 0}, // 1 Adnet address 0 = single door master, 100 = slave + {10, 0, 100, 1, 0, 0}, // 2 Gasket Delay + {10, 0, 10000, 1, 0, 0}, // 3 Bug Screen Button Time seconds * 10 + {1, 0, 10000, 1, 0, 0}, // 4 Use Obstruction Sensor + {600, 0, 10000, 1, 0, 0}, // 5 Door Open Travel Timeout + {600, 1, 10000, 1, 0, 0}, // 6 Door Close Jog Limit -time from open to hit upper switch + {-6, -12, 12, 1, 0, 0}, // 7 Time Zone + {0, 0, 10000, 1, 0, 0}, // 8 Security Code Access + {0, 0, 1, 1, 0, 0}, // 9 Enable WiFi + {115, 0, 10000, 1, 0, 0}, // 10 Lo Battery voltage *10 / 0 = off + {0, 0, 10000, 0, 0, 0}, // 11 Open counter + {0, 0, 100000, 1, 0, 0}, // 12 auto setup script + {0, 0, 10000, 1, 0, 0}, // 13 0 = 2.4" Display, 1 = 5" Display + {0, 0, 10000, 0, 1, 0}, // 14 Store FIRMWARE Version Here + {1, 0, 15, 1, 0, 0}, // 15 bug screen channel + {0, 0, 10000, 1, 0, 0}, // 16 use SPARE relay for lock circuit ENERGIZE to UNLOCK + {1, 0, 10000, 1, 0, 0}, // 17 + {1253, 0, 10000, 1, 0, 0}, // 18 batteryvoltage cal + {0, 0, 10000, 1, 0, 0}, // 19 number of 5" displays at address 181+ + {0, 0, 10000, 1, 0, 0}, // 20 number of 2" displays at address 191+ + {0, 0, 10000, 1, 0, 0}, // 21 number of motor controls at address 200+ + {5, 1, 10000, 1, 0, 0}, // 22 WiFi service timer + {800, 200, 10000, 1, 0, 0}, // 23 WiFi Update timer + {0, 0, 10000, 0, 0, 0}, // 24 set to 1 to use NC interlock on spare 1 + {0, 0, 2, 1, 0, 0}, // 25 #io expanders + {0, 0, 10000, 1, 0, 0}, // 26 ioExpander #0 remote open/close button mode -optos 0 and 1 + {190, 0, 240, 1, 0, 0}, // 27 motor max current * 10 + {0, 0, 10000, 1, 0, 538}, // 28 use ioExpander relays for Somfy screen control + {0, 0, 10000, 1, 0, 538}, // 29 splash screen timeout to blank screen 0 = off 1 = on + {30, 20, 10000, 1, 0, 538}, // 30 timeout for start motor + {10, 5, 10000, 1, 0, 538}, // 31 timeout for running motor + {0, 0, 10000, 1, 0, 0}, // 32 + {0, 0, 20000, 1, 0, 0}, // 33 time between cycles for exercise mode / seconds * 10 + {0, 0, 10000, 1, 0, 0}, // 34 + {0, 0, 10000, 1, 0, 0}, // 35 + {0, 0, 10000, 1, 0, 0}, // 36 + {0, 0, 10000, 1, 0, 0}, // 37 + {0, 0, 10000, 1, 0, 0}, // 38 + {10, 0, 10000, 1, 0, 0}, // 39 Learned close position + {2000, 100, 10000, 1, 0, 0}, // 40 Learned open position + + {5, 0, 10000, 1, 0, 0}, // 41 SYNC Inteval + {100, 0, 10000, 1, 0, 0}, // 42 SYNC Integral + {50, 0, 10000, 1, 0, 0}, // 43 SYNC Proportional + {200, 0, 10000, 1, 0, 0}, // 44 MAX_DELTA + {250, 0, 10000, 1, 0, 0}, // 45 MAX_CURRENT + {50, 0, 10000, 1, 0, 0}, // 46 MOTOR_SPEED + {3000, 0, 10000, 1, 0, 0}, // 47 EXTEND_LIMIT + {0, -10000, 10000, 1, 0, 0}, // 48 SLAVE OFFSET + + {0, -1000, 1000, 1, 0, 0}, // 49 setCurrentBalance open + {0, -1000, 1000, 1, 0, 0}, // 50 setCurrentBalance close + {0, 0, 10000, 1, 0, 0}, // 51 + {0, 0, 10000, 1, 0, 538}, // 52 number of slaves + {0, 0, 10000, 1, 0, 0}, // 53 + {0, 0, 10000, 1, 0, 0}, // 54 Use Lidar + {0, 0, 10000, 1, 0, 0}, // 55 Lidar parm 2 door height + {0, 0, 10000, 1, 0, 0}, // 56 Lidar parm 3 door width + {0, 0, 10000, 1, 0, 0}, // 57 Lidar parm 4 deadband + {5, 0, 10000, 1, 0, 0}, // 58 Lidar parm 5 debounce count + {0, 0, 10000, 1, 0, 0}, // 59 Lidar parm 6 mounting angle + {0, 0, 10000, 1, 0, 0}, // 60 Lidar parm 7 run mode + {0, 0, 10000, 1, 0, 0}, // 61 + {0, 0, 10000, 1, 0, 0}, // 62 + {0, 0, 10000, 1, 0, 0}, // 63 + {2002, 3, 9000000, 0, 1, 0}, // 64 serial# stored here.. not included in factory default set + {400, 0, 10000, 1, 0, 0}, // 65 Lidar down from open deadband + {300, 0, 10000, 1, 0, 0}, // 66 Lidar up from closed deadband + {0, 0, 10000, 1, 0, 538}, // 67 splash screen timeout to blank screen 0 = off 1 = on + {0, 0, 10000, 1, 0, 0}, // 68 + {0, 0, 999999999, 1, 0, 0}, // 69 temp storage of last rtc set + {0, 0, 999999999, 1, 0, 0}, // 70 + {0, 0, 999999999, 1, 0, 0}, // 71 + {0, 0, 999999999, 1, 0, 0}, // 72 + {0, 0, 999999999, 1, 0, 0}, // 73 + {0, 0, 999999999, 1, 0, 0}, // 74 + {1, 1, 1, 1, 0, 0}, // 75 Device type + {0, 0, 2147000000, 1, 0, 0}, // 76 Last Service time + {0, 0, 999999999, 1, 0, 0}, // 77 + {0, 0, 999999999, 1, 0, 0}, // 78 + {0, 0, 999999999, 1, 0, 0}, // 79 + {0, 0, 999999999, 1, 0, 0}, // 80 + {0, 0, 999999999, 1, 0, 0}, // 81 + {0, 0, 999999999, 1, 0, 0}, // 82 + {0, 0, 999999999, 1, 0, 0}, // 83 + {0, 0, 999999999, 1, 0, 0}, // 84 + {0, 0, 999999999, 1, 0, 0}, // 85 + {0, 0, 999999999, 1, 0, 0}, // 86 + {0, 0, 999999999, 1, 0, 0}, // 87 + {0, 0, 999999999, 1, 0, 0}, // 88 + {0, 0, 999999999, 1, 0, 0}, // 89 + {0, 0, 999999999, 1, 0, 0}, // 90 + {0, 0, 999999999, 1, 0, 0}, // 91 + {0, 0, 999999999, 1, 0, 0}, // 92 + {0, 0, 999999999, 1, 0, 0}, // 93 + {0, 0, 999999999, 1, 0, 0}, // 94 + {0, 0, 999999999, 1, 0, 0}, // 95 + {0, 0, 999999999, 1, 0, 0}, // 96 + {0, 0, 999999999, 1, 0, 0}, // 97 + {0, 0, 999999999, 1, 0, 0}, // 98 + {0, 0, 999999999, 1, 0, 0}, // 99 + {0, 0, 999999999, 1, 0, 0}, // 100 + {10, 0, 500, 1, 0, 0}, // 101 Clarity advertising repeat count v534 + {0, 0, 999999999, 1, 0, 0}, // 102 + {0, 0, 999999999, 1, 0, 0}, // 103 + {0, 0, 999999999, 1, 0, 0}, // 104 + {0, 0, 999999999, 1, 0, 0}, // 105 + {0, 0, 999999999, 1, 0, 0}, // 106 + {0, 0, 999999999, 1, 0, 0}, // 107 + {0, 0, 999999999, 1, 0, 0}, // 108 + {0, 0, 999999999, 1, 0, 0}, // 109 + {0, 0, 999999999, 1, 0, 0}, // 110 + {0, 0, 999999999, 1, 0, 0}, // 111 + {0, 0, 999999999, 1, 0, 0}, // 112 + {0, 0, 999999999, 1, 0, 0}, // 113 + {0, 0, 999999999, 1, 0, 0}, // 114 + {0, 0, 999999999, 1, 0, 0}, // 115 + {0, 0, 999999999, 1, 0, 0}, // 116 + {0, 0, 999999999, 1, 0, 0}, // 117 + {0, 0, 999999999, 1, 0, 0}, // 118 + {0, 0, 999999999, 1, 0, 0}, // 119 + {0, 0, 999999999, 1, 0, 0}, // 120 + {0, 0, 999999999, 1, 0, 0}, // 121 + {0, 0, 999999999, 1, 0, 0}, // 122 + {0, 0, 999999999, 1, 0, 0}, // 123 + {0, 0, 999999999, 1, 0, 0}, // 124 + {0, 0, 999999999, 1, 0, 0}, // 125 + {0, 0, 999999999, 1, 0, 0}, // 126 + {0, 0, 999999999, 1, 0, 0}, // 127 + {0, 0, 999999999, 1, 0, 0}, // 128 + {0, 0, 999999999, 1, 0, 0}, // 129 + {0, 0, 999999999, 1, 0, 0}, // 130 + {0, 0, 999999999, 1, 0, 0}, // 131 + {0, 0, 999999999, 1, 0, 0}, // 132 + {0, 0, 999999999, 1, 0, 0}, // 133 + {0, 0, 999999999, 1, 0, 0}, // 134 + {0, 0, 999999999, 1, 0, 0}, // 135 + {0, 0, 999999999, 1, 0, 0}, // 136 + {0, 0, 999999999, 1, 0, 0}, // 137 + {0, 0, 999999999, 1, 0, 0}, // 138 + {0, 0, 999999999, 1, 0, 0}, // 139 +}; + +#endif +/* + if 255, factory default, + // if 19315, set serial to parm 22 + // if 6911, set RLY08 at address 1 to parm 22 valid numbers are 2-4 + // if 257, ssid = ADITEST, pass = 12345678 + // if 6011, OTA + // if 6013, Sensor screen + // if 6012, Timer screen + // if 6014, Toggle VB + +*/ + + +#ifndef PARMS_LIB_H +#define PARMS_LIB_H +#include "FileLib.h" + +class ParmsLibClass +{ +private: + /** + * File system + */ + FileLibClass &_fileLib; + + /** + * Verbose mode flag + */ + bool _verbose = false; + + /** + * Qualify a single parm + * @param pnum Index of the parm to qualify + * @param pdat Value to qualify + * + * @return true if parm is valid + */ + bool _qualify(uint16_t pnum, int32_t pdat); + + /** + * Qualify all parms and set parm to default if invalid + */ + void _qualifyAll(void); + + /** + * Print out message, if verbose mode is enabled + */ + void _printMessage(const char *message, ...); + + /** + * Calculate the checksum + * + * @return Checksum value + */ + int32_t _calcChecksum(void); + +public: + /** + * Constructor + */ + ParmsLibClass(FileLibClass &fileLib) : _fileLib(fileLib){}; + + /** + * Destructor + */ + ~ParmsLibClass(); + + /** + * Set verbose mode + * @param verbose true to enable verbose mode + */ + void setVerbose(bool verbose) { _verbose = verbose; } + + /** + * Read parm + * @param pnum Index of the parm to read + * + * @returns Value at the parm index + */ + int32_t read(uint16_t pnum); + + /** + * Write parm + * @param pnum Index of the parm to write + * @param pdat Value to write + * + * @return true if successful + */ + bool write(uint16_t pnum, int32_t pdat); + + /** + * Set factory parms + */ + void factoryReset(void); + + /** + * Read from FS + * @param filename Optional, default "/PARMS.ADI". Filename to write to. + * + * @return true if successful + */ + bool loadFromFS(char *filename = "/PARMS.ADI"); + + /** + * Write to FS + * @param filename Optional, default "/PARMS.ADI". Filename to write to. + * + * @return true if successful + */ + bool saveToFS(char *filename = "/PARMS.ADI"); +}; + +#endif diff --git a/Parms_ADI.ino b/Parms_ADI.ino new file mode 100644 index 0000000..4e29320 --- /dev/null +++ b/Parms_ADI.ino @@ -0,0 +1,281 @@ +#include "Parms_ADI.h" + +ParmsLibClass::~ParmsLibClass() +{ + _fileLib.~FileLibClass(); +} + +int32_t ParmsLibClass::read(uint16_t pnum) +{ + _printMessage("Read parm %d.\n", pnum); + return parm[pnum]; +} + +void ParmsLibClass::factoryReset(void) +{ + //_printMessage("Setting factory parms.\n"); + displayText("Parm Restore"); + Serial.println("Setting factory parms.\n"); + + + uint16_t parmLimitSize = sizeof(parmlimits) / sizeof(parmlimits[0]); + // skip 0 for checksum + for (int i = 1; i < parmLimitSize; i++) + { + // skip serial number + if (i != 64) + { + if (parmlimits[i][3] == 1) + { + parm[i] = parmlimits[i][0]; + } + } + } + + parm[0] = _calcChecksum(); + + // save to FS + saveToFS(); + + _printMessage("CheckSum: %d\n", parm[0]); + delay(2000); +} + +bool ParmsLibClass::write(uint16_t pnum, int32_t pdat) +{ + _printMessage("Write parm %d = %d.\n", pnum, pdat); + int csi, csi2; + if ((pnum == 1) && (pdat == 255)) + { + factoryReset(); + return true; + } + + if ((pnum == 1) && (pdat == 253)) + { + // esp_task_wdt_init(180, true); //enable panic so ESP32 restarts 180 seconds + updateFromFS(); + return true; + } + + if ((pnum == 1) && (pdat == 1234)) // v509 + { + parm[76] = getEpochRtc(); + saveToFS(); + return true; + } + + if ((pnum == 1) && (pdat == 252)) // v509 + { + displayText("WDT TEST LONG"); + delay(6000); + displayText("WDT TEST SHORT"); + tone(HEARTBEATLED, 100, 500); // set wdog timeout to 2 sec + delay(5000); + displayText("WDT FAILED!!!!"); + delay(4000); + return true; + } + + if ((pnum == 1) && (pdat == 250)) // Lidar test mode + { + displayText("LIDAR TEST"); + lidarTest = 1; + return true; + } + + if ((pnum == 1) && (pdat == 6014)) + { + displayText("TOGGLE VB"); + if (VB) + { + VB = 0; + Serial.println("Verbose OFF"); + } + else + { + VB = 1; + Serial.println("Verbose ON"); + } + return true; + } + + if (pnum == 18) // calibrate battery voltage + { + Serial.printf("Raw Battery A2D: %d\n", analogRead(BATTERYINPUTPIN)); + pdat *= 1000; // voltage * 1000 + + csi = 0; + for (csi2 = 0; csi2 < 20; csi2++) + csi += analogRead(BATTERYINPUTPIN); + csi /= 20; + + if (csi == 0) + csi = 1; + pdat /= csi; + } + + // don't write parm 33(exercise mode) to SD, its set to 0 on boot + if (pnum == 33) + { + parm[pnum] = pdat; + return true; + } + + if (!_qualify(pnum, pdat)) + { + _printMessage("Parm %d with value %d is out of range.\n", pnum, pdat); + return false; + } + if (pnum == 1) + if ((pdat < 5) || (pdat == 100)) + {} + else + return true; + + parm[pnum] = pdat; + // update checksum + parm[0] = _calcChecksum(); + // now write to SD + saveToFS(); + return true; + +} + +//******************************************************* +// +//******************************************************* + +bool ParmsLibClass::saveToFS(char *filename) +{ + _printMessage("Writing parms to FS.\n"); + _qualifyAll(); + if (!_fileLib.write(filename, reinterpret_cast(parm), sizeof(parm))) + { + _printMessage("Failed to write parms to FS.\n"); + return false; + } + return true; +} + +bool ParmsLibClass::loadFromFS(char *filename) +{ + _printMessage("Setting parms from FS.\n"); + memset(parm, 0, sizeof(parm)); + if (!_fileLib.read(filename, reinterpret_cast(parm), sizeof(parm))) + { + _printMessage("Failed to read parms from FS.\n"); + factoryReset(); + return false; + } + + int32_t checkSum = _calcChecksum(); + if (checkSum != parm[0]) + { + _printMessage("Error checksum mismatch. Expected %d, got %d.\n", parm[0], checkSum); + factoryReset(); + return false; + } + + return true; +} + +bool ParmsLibClass::_qualify(uint16_t pnum, int32_t pdat) +{ + _printMessage("Qualifying parm %d with value %d.\n", pnum, pdat); + uint16_t parmLimitSize = sizeof(parmlimits) / sizeof(parmlimits[0]); + // qualify parms min/max + if(pnum > PARMSIZE) // disallow write to an non-existant parm + return false; + + if (pnum > parmLimitSize) // allow any data if parm number is outside of limit table + { + return true; + } + + if (pdat >= parmlimits[pnum][1]) + { + if (pdat <= parmlimits[pnum][2]) + { + return true; + } + } + + return false; +} + +void ParmsLibClass::_qualifyAll(void) +{ + uint16_t parmLimitSize = sizeof(parmlimits) / sizeof(parmlimits[0]); + for (uint16_t i = 1; i < parmLimitSize; i++) + { + if (!_qualify(i, parm[i])) + { + parm[i] = parmlimits[i][0]; + } + } +} + +int32_t ParmsLibClass::_calcChecksum(void) +{ + int32_t checkSum = 0; + uint16_t parmLimitSize = sizeof(parmlimits) / sizeof(parmlimits[0]); + // skip 0 for checksum + for (uint16_t i = 1; i < parmLimitSize; i++) + { + checkSum += parm[i]; + } + return checkSum; +} + +void ParmsLibClass::_printMessage(const char *message, ...) +{ + if (_verbose) + { + char buffer[256]; + + va_list args; + va_start(args, message); + vsnprintf(buffer, sizeof(buffer), message, args); + va_end(args); + Serial.printf("ParmsLibClass:: %s", buffer); + } +} + + + + + + +void SD_LogWrite(char *str) +{ + return; + + char lstr[80]; + char tstr[80]; + String St; + + Serial.println("Writing Log"); + displayText("Writing Log"); + + St = makeTimeStr(); + St.toCharArray(tstr, 80); + sprintf(lstr, "%s -> %s\n", tstr, str); + + Serial.print("Log: "); + Serial.println(lstr); + +} + +void qualifyParms(void) +{ + int i; + // qualify parms min/max + for (i = 1; i < (PARMSIZE - 1); i++) + { + if (parm[i] < parmlimits[i][1]) + parm[i] = parmlimits[i][1]; + if (parm[i] > parmlimits[i][2]) + parm[i] = parmlimits[i][2]; + } +} diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..c222544 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,6 @@ +[env:esp32dev] +platform = espressif32 +board = esp32dev +framework = arduino +build_flags = -v +build_dir = ./ diff --git a/printControl.h b/printControl.h new file mode 100644 index 0000000..153162a --- /dev/null +++ b/printControl.h @@ -0,0 +1,19 @@ +#ifndef PRINT_H +#define PRINT_H +char printBuff[200]; + +#define _DEBUG_CAN 1 +// define _DEBUG_SYNC 1 +#define _DEBUG_MOTOR 1 +bool vbCAN; +bool vbSync; +bool vb = 1; +bool vbCSV; + +void printStartOfRun(); + +void printEndOfRun(); +void printEndOfRunCSV(); +void printPosition(void); +void printPrint(); // dump print buffer to serial port +#endif // PRINT_H diff --git a/printControl.ino b/printControl.ino new file mode 100644 index 0000000..62e64d8 --- /dev/null +++ b/printControl.ino @@ -0,0 +1,133 @@ +#include "printControl.h" + +// printing variables + +void printPrint() +{ + if (vb || vbCSV) + { + strcat(printBuff, "\r\n"); + Serial.print(printBuff); + } +} + +void printStartOfRun() +{ + if (vbCSV == 1) + { + startMaster = mStatus[MASTER].bits.position; + startSlave = mStatus[SLAVE].bits.position; + return; + } + + strcpy(printBuff, "****** Motor Start "); + if (motorDir == EXTEND) + strcat(printBuff, "Extend *****"); + else + strcat(printBuff, "Retract *****"); + printPrint(); + + if (bSyncEnable == 1) + strcpy(printBuff, "Sync Enabled"); + else + strcpy(printBuff, "Sync Disabled"); + printPrint(); + + if (cycleMax > 0) + { + sprintf(printBuff, "***** Start cycle %d of %d\r\n", (cycleMax - cycleCount), cycleMax); + printPrint(); + } + sprintf(printBuff, "Position M:%04u S:%04u", + mStatus[MASTER].bits.position, mStatus[SLAVE].bits.position); + printPrint(); + + sprintf(printBuff, "Integral %u Proportional %u Update Rate %u\r\n", + parm[P_MOTOR_ADJ_I], parm[P_MOTOR_ADJ_P], parm[P_MOTOR_ADJ_INTERVAL]); + printPrint(); + sprintf(printBuff, "Master Speed %u", masterSpeed); + printPrint(); + + if (vbSync) + { + sprintf(printBuff, "Delt MPOS SPOS INTG DxP +I +M1 M2 MS SS MA SA"); + printPrint(); + } +} + +void printEndOfRun() +{ + if (vbCSV) + { + printEndOfRunCSV(); + return; + } + sprintf(printBuff, "*** End of Run "); + if (motorDir == EXTEND) + strcat(printBuff, "Extend"); + else + strcat(printBuff, "Retract"); + printPrint(); + if (cycleCount > 0) + { + sprintf(printBuff, "Cycle %d", cycleMax - cycleCount); + printPrint(); + } + + sprintf(printBuff, "Position M:%04u S:%04u", + mStatus[MASTER].bits.position, mStatus[SLAVE].bits.position); + printPrint(); + + sprintf(printBuff, "Delta Max %d Min %d", maxDelta, minDelta); + printPrint(); + + sprintf(printBuff, "Speed Master %u Max Slave %u", + masterSpeed, maxSpeed); + printPrint(); + + sprintf(printBuff, "Max Current M-%d S-%d", + maxCurrentM, maxCurrentS); + printPrint(); + + sprintf(printBuff, "\r\nRun Time %d.%1d", runTime / 1000, runTime % 1000); + printPrint(); + if (motorError != MOTOR_ERROR_NONE) + { + sprintf(printBuff, "Motor Error:%u", motorError); + printPrint(); + cycleCount = 0; + } + if (vbSync) + printPosition(); +} +// Print run data in a CSV Format +// Cycle count,masterStartPosition, master End, slave start, slave end, min delta, max delta, +// master speed, max slave speed, master current, slave current, runtime +void printEndOfRunCSV() +{ + char c; + if (startMaster > mStatus[MASTER].bits.position) + c = 'R'; + else + c = 'E'; + sprintf(printBuff, "%u,%c,%u,%u,%u,%u,%d,%d,%u,%u,%u,%u,%d.%1d", + (cycleMax - cycleCount), c, + startMaster, mStatus[MASTER].bits.position, + startSlave, mStatus[SLAVE].bits.position, + minDelta, maxDelta, + masterSpeed, maxSpeed, + maxCurrentM, maxCurrentS, + runTime / 1000, runTime % 1000); + + printPrint(); +} + +void printPosition(void) +{ + sprintf(printBuff, "M:%04u S:%04u D:%04d\r\n", + mStatus[MASTER].bits.position, + mStatus[SLAVE].bits.position, + (mStatus[MASTER].bits.position - mStatus[SLAVE].bits.position)); + + printPrint(); +}