Motoron Motor Controller library for Arduino
Loading...
Searching...
No Matches
Motoron.h
Go to the documentation of this file.
1// Copyright (C) Pololu Corporation. See LICENSE.txt for details.
2
10
15
16#pragma once
17
18#include <Arduino.h>
19#include <Wire.h>
20#include "motoron_protocol.h"
21
23
24extern const PROGMEM uint8_t motoronCrcTable[256];
25
27
31 Motoron18v18 = 0b0001,
32 Motoron24v14 = 0b0101,
33 Motoron18v20 = 0b1010,
34 Motoron24v16 = 0b1101,
35 Motoron453 = 0b0110,
36};
37
42 Motoron256 = 0b0000,
44 MotoronHp = 0b0010,
46 Motoron550 = 0b0011,
48 Motoron453 = 0b0110,
49};
50
52{
53 uint16_t raw;
54 int16_t speed;
55 uint16_t processed;
56};
57
63class MotoronBase
64{
65public:
66 MotoronBase()
67 {
68 lastError = 0;
69 protocolOptions = defaultProtocolOptions;
70 }
71
74 uint8_t getLastError()
75 {
76 return lastError;
77 }
78
89 void getFirmwareVersion(uint16_t * productId, uint16_t * firmwareVersion)
90 {
91 uint8_t cmd = MOTORON_CMD_GET_FIRMWARE_VERSION;
92 uint8_t response[4];
93 sendCommandAndReadResponse(1, &cmd, sizeof(response), response);
94 if (productId != nullptr) { *productId = response[0] | (response[1] << 8); }
95 if (firmwareVersion != nullptr) { *firmwareVersion = response[2] | (response[3] << 8); }
96 }
97
137 void setProtocolOptions(uint8_t options)
138 {
139 this->protocolOptions = options;
140 uint8_t cmd[] = {
141 MOTORON_CMD_SET_PROTOCOL_OPTIONS,
142 (uint8_t)(options & 0x7F),
143 (uint8_t)(~options & 0x7F),
144 };
145 sendCommandCore(sizeof(cmd), cmd, true);
146 if (getLastError()) { return; }
147 }
148
156 void setProtocolOptionsLocally(uint8_t options)
157 {
158 this->protocolOptions = options;
159 }
160
165 {
166 return this->protocolOptions;
167 }
168
171 {
173 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS)
174 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
175 }
176
179 {
181 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS)
182 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
183 }
184
187 {
189 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS));
190 }
191
194 {
196 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS));
197 }
198
201 {
203 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
204 }
205
208 {
210 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
211 }
212
215 {
217 | (1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL));
218 }
219
222 {
224 & ~(1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL));
225 }
226
231 void readEeprom(uint8_t offset, uint8_t length, uint8_t * buffer)
232 {
233 uint8_t cmd[] = {
234 MOTORON_CMD_READ_EEPROM,
235 (uint8_t)(offset & 0x7F),
236 (uint8_t)(length & 0x7F),
237 };
238 sendCommandAndReadResponse(sizeof(cmd), cmd, length, buffer);
239 }
240
246 {
247 uint8_t number;
248 readEeprom(MOTORON_SETTING_DEVICE_NUMBER, 1, &number);
249 return number;
250 }
251
262 void writeEeprom(uint8_t offset, uint8_t value)
263 {
264 uint8_t cmd[7];
265 cmd[0] = MOTORON_CMD_WRITE_EEPROM;
266 cmd[1] = offset & 0x7F;
267 cmd[2] = value & 0x7F;
268 cmd[3] = value >> 7 & 1;
269 cmd[4] = cmd[1] ^ 0x7F;
270 cmd[5] = cmd[2] ^ 0x7F;
271 cmd[6] = cmd[3] ^ 0x7F;
272 sendCommand(sizeof(cmd), cmd);
273 flushTransmission();
274 delay(6);
275 }
276
284 void writeEeprom16(uint8_t offset, uint16_t value)
285 {
286 writeEeprom(offset, value & 0xFF);
287 writeEeprom(offset + 1, value >> 8 & 0xFF);
288 }
289
298 void writeEepromDeviceNumber(uint16_t number)
299 {
300 writeEeprom(MOTORON_SETTING_DEVICE_NUMBER, number & 0x7F);
301 writeEeprom(MOTORON_SETTING_DEVICE_NUMBER + 1, number >> 7 & 0x7F);
302 }
303
316 {
317 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER, (number & 0x7F) | 0x80);
318 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER + 1, number >> 7 & 0x7F);
319 }
320
332 {
333 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER, 0);
334 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER + 1, 0);
335 }
336
350 {
351 writeEeprom(MOTORON_SETTING_COMMUNICATION_OPTIONS, options);
352 }
353
363 void writeEepromBaudRate(uint32_t baud)
364 {
365 if (baud < MOTORON_MIN_BAUD_RATE) { baud = MOTORON_MIN_BAUD_RATE; }
366 if (baud > MOTORON_MAX_BAUD_RATE) { baud = MOTORON_MAX_BAUD_RATE; }
367 writeEeprom16(MOTORON_SETTING_BAUD_DIVIDER, (16000000 + (baud >> 1)) / baud);
368 }
369
379 void writeEepromResponseDelay(uint8_t delay)
380 {
381 writeEeprom(MOTORON_SETTING_RESPONSE_DELAY, delay);
382 }
383
392 {
393 // Always send the reset command with a CRC byte to make it more reliable.
394 uint8_t cmd = MOTORON_CMD_REINITIALIZE;
395 sendCommandCore(1, &cmd, true);
396 protocolOptions = defaultProtocolOptions;
397 }
398
409 void reset()
410 {
411 uint8_t cmd = MOTORON_CMD_RESET;
412 sendCommandCore(1, &cmd, true);
413 flushTransmission();
414 protocolOptions = defaultProtocolOptions;
415 }
416
429 void getVariables(uint8_t motor, uint8_t offset, uint8_t length, uint8_t * buffer)
430 {
431 uint8_t cmd[] = {
432 MOTORON_CMD_GET_VARIABLES,
433 (uint8_t)(motor & 0x7F),
434 (uint8_t)(offset & 0x7F),
435 (uint8_t)(length & 0x7F),
436 };
437 sendCommandAndReadResponse(sizeof(cmd), cmd, length, buffer);
438 }
439
445 uint8_t getVar8(uint8_t motor, uint8_t offset)
446 {
447 uint8_t result;
448 getVariables(motor, offset, 1, &result);
449 return result;
450 }
451
457 uint16_t getVar16(uint8_t motor, uint8_t offset)
458 {
459 uint8_t buffer[2];
460 getVariables(motor, offset, 2, buffer);
461 return buffer[0] | ((uint16_t)buffer[1] << 8);
462 }
463
512 uint16_t getStatusFlags()
513 {
514 return getVar16(0, MOTORON_VAR_STATUS_FLAGS);
515 }
516
522 {
523 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_PROTOCOL_ERROR);
524 }
525
531 {
532 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_CRC_ERROR);
533 }
534
540 {
541 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT_LATCHED);
542 }
543
549 {
550 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_FAULT_LATCHED);
551 }
552
558 {
559 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_NO_POWER_LATCHED);
560 }
561
573 {
574 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_UART_ERROR);
575 }
576
589 {
590 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_RESET);
591 }
592
598 {
599 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_FAULTING);
600 }
601
607 {
608 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_NO_POWER);
609 }
610
616 {
617 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_ERROR_ACTIVE);
618 }
619
625 {
626 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_OUTPUT_ENABLED);
627 }
628
634 {
635 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_DRIVING);
636 }
637
659 {
660 return getVar8(0, MOTORON_VAR_UART_FAULTS);
661 }
662
669 uint16_t getVinVoltage()
670 {
671 return getVar16(0, MOTORON_VAR_VIN_VOLTAGE);
672 }
673
683 uint32_t getVinVoltageMv(uint16_t referenceMv,
685 {
686 uint16_t scale = (uint8_t)type & 1 ? 459 : 1047;
687 return (uint32_t)getVinVoltage() * referenceMv / 1024 * scale / 47;
688 }
689
697 {
698 return getVar16(0, MOTORON_VAR_COMMAND_TIMEOUT) * 4;
699 }
700
709 {
710 return getVar8(0, MOTORON_VAR_ERROR_RESPONSE);
711 }
712
720 uint16_t getErrorMask()
721 {
722 return getVar16(0, MOTORON_VAR_ERROR_MASK);
723 }
724
730 {
731 return getVar8(0, MOTORON_VAR_JUMPER_STATE);
732 }
733
741 int16_t getTargetSpeed(uint8_t motor)
742 {
743 return getVar16(motor, MOTORON_MVAR_TARGET_SPEED);
744 }
745
752 uint16_t getTargetBrakeAmount(uint8_t motor)
753 {
754 return getVar16(motor, MOTORON_MVAR_TARGET_BRAKE_AMOUNT);
755 }
756
764 int16_t getCurrentSpeed(uint8_t motor)
765 {
766 return getVar16(motor, MOTORON_MVAR_CURRENT_SPEED);
767 }
768
775 int16_t getBufferedSpeed(uint8_t motor)
776 {
777 return getVar16(motor, MOTORON_MVAR_BUFFERED_SPEED);
778 }
779
786 uint8_t getPwmMode(uint8_t motor)
787 {
788 return getVar8(motor, MOTORON_MVAR_PWM_MODE);
789 }
790
798 uint16_t getMaxAccelerationForward(uint8_t motor)
799 {
800 return getVar16(motor, MOTORON_MVAR_MAX_ACCEL_FORWARD);
801 }
802
810 uint16_t getMaxAccelerationReverse(uint8_t motor)
811 {
812 return getVar16(motor, MOTORON_MVAR_MAX_ACCEL_REVERSE);
813 }
814
822 uint16_t getMaxDecelerationForward(uint8_t motor)
823 {
824 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_FORWARD);
825 }
826
834 uint16_t getMaxDecelerationReverse(uint8_t motor)
835 {
836 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_REVERSE);
837 }
838
840
841 // This function is used by Pololu for testing.
842 uint16_t getMaxDecelerationTemporary(uint8_t motor)
843 {
844 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_TMP);
845 }
846
848
855 uint16_t getStartingSpeedForward(uint8_t motor)
856 {
857 return getVar16(motor, MOTORON_MVAR_STARTING_SPEED_FORWARD);
858 }
859
866 uint16_t getStartingSpeedReverse(uint8_t motor)
867 {
868 return getVar16(motor, MOTORON_MVAR_STARTING_SPEED_REVERSE);
869 }
870
878 uint8_t getDirectionChangeDelayForward(uint8_t motor)
879 {
880 return getVar8(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_FORWARD);
881 }
882
890 uint8_t getDirectionChangeDelayReverse(uint8_t motor)
891 {
892 return getVar8(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_REVERSE);
893 }
894
903 uint16_t getCurrentLimit(uint8_t motor)
904 {
905 return getVar16(motor, MOTORON_MVAR_CURRENT_LIMIT);
906 }
907
920 {
921 uint8_t buffer[6];
922 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_RAW, sizeof(buffer), buffer);
924 r.raw = buffer[0] | ((uint16_t)buffer[1] << 8);
925 r.speed = buffer[2] | ((uint16_t)buffer[3] << 8);
926 r.processed = buffer[4] | ((uint16_t)buffer[5] << 8);
927 return r;
928 }
929
937 {
938 uint8_t buffer[4];
939 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_RAW, sizeof(buffer), buffer);
941 r.raw = buffer[0] | ((uint16_t)buffer[1] << 8);
942 r.speed = buffer[2] | ((uint16_t)buffer[3] << 8);
943 return r;
944 }
945
953 {
954 uint8_t buffer[4];
955 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_SPEED, sizeof(buffer), buffer);
957 r.speed = buffer[0] | ((uint16_t)buffer[1] << 8);
958 r.processed = buffer[2] | ((uint16_t)buffer[3] << 8);
959 return r;
960 }
961
970 uint16_t getCurrentSenseRaw(uint8_t motor)
971 {
972 return getVar16(motor, MOTORON_MVAR_CURRENT_SENSE_RAW);
973 }
974
994 uint16_t getCurrentSenseProcessed(uint8_t motor)
995 {
996 return getVar16(motor, MOTORON_MVAR_CURRENT_SENSE_PROCESSED);
997 }
998
1007 uint8_t getCurrentSenseOffset(uint8_t motor)
1008 {
1009 return getVar8(motor, MOTORON_MVAR_CURRENT_SENSE_OFFSET);
1010 }
1011
1021 uint16_t getCurrentSenseMinimumDivisor(uint8_t motor)
1022 {
1023 return getVar8(motor, MOTORON_MVAR_CURRENT_SENSE_MINIMUM_DIVISOR) << 2;
1024 }
1025
1038 void setVariable(uint8_t motor, uint8_t offset, uint16_t value)
1039 {
1040 if (value > 0x3FFF) { value = 0x3FFF; }
1041 uint8_t cmd[] = {
1042 MOTORON_CMD_SET_VARIABLE,
1043 (uint8_t)(motor & 0x1F),
1044 (uint8_t)(offset & 0x7F),
1045 (uint8_t)(value & 0x7F),
1046 (uint8_t)((value >> 7) & 0x7F),
1047 };
1048 sendCommand(sizeof(cmd), cmd);
1049 }
1050
1058 {
1059 // Divide by 4, but round up, and make sure we don't have
1060 // an overflow if 0xFFFF is passed.
1061 uint16_t timeout = (ms / 4) + ((ms & 3) ? 1 : 0);
1062 setVariable(0, MOTORON_VAR_COMMAND_TIMEOUT, timeout);
1063 }
1064
1079 void setErrorResponse(uint8_t response)
1080 {
1081 setVariable(0, MOTORON_VAR_ERROR_RESPONSE, response);
1082 }
1083
1091 void setErrorMask(uint16_t mask)
1092 {
1093 setVariable(0, MOTORON_VAR_ERROR_MASK, mask);
1094 }
1095
1112 {
1113 setErrorMask(defaultErrorMask & ~(1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT));
1114 }
1115
1124 void clearUARTFaults(uint8_t flags)
1125 {
1126 setVariable(0, MOTORON_VAR_UART_FAULTS, ~(uint16_t)flags & 0x3FFF);
1127 }
1128
1147 void setPwmMode(uint8_t motor, uint8_t mode)
1148 {
1149 setVariable(motor, MOTORON_MVAR_PWM_MODE, mode);
1150 }
1151
1159 void setMaxAccelerationForward(uint8_t motor, uint16_t accel)
1160 {
1161 setVariable(motor, MOTORON_MVAR_MAX_ACCEL_FORWARD, accel);
1162 }
1163
1171 void setMaxAccelerationReverse(uint8_t motor, uint16_t accel)
1172 {
1173 setVariable(motor, MOTORON_MVAR_MAX_ACCEL_REVERSE, accel);
1174 }
1175
1180 void setMaxAcceleration(uint8_t motor, uint16_t accel)
1181 {
1182 setMaxAccelerationForward(motor, accel);
1183 if (getLastError()) { return; }
1184 setMaxAccelerationReverse(motor, accel);
1185 }
1186
1194 void setMaxDecelerationForward(uint8_t motor, uint16_t decel)
1195 {
1196 setVariable(motor, MOTORON_MVAR_MAX_DECEL_FORWARD, decel);
1197 }
1198
1206 void setMaxDecelerationReverse(uint8_t motor, uint16_t decel)
1207 {
1208 setVariable(motor, MOTORON_MVAR_MAX_DECEL_REVERSE, decel);
1209 }
1210
1215 void setMaxDeceleration(uint8_t motor, uint16_t decel)
1216 {
1217 setMaxDecelerationForward(motor, decel);
1218 if (getLastError()) { return; }
1219 setMaxDecelerationReverse(motor, decel);
1220 }
1221
1229 void setStartingSpeedForward(uint8_t motor, uint16_t speed)
1230 {
1231 setVariable(motor, MOTORON_MVAR_STARTING_SPEED_FORWARD, speed);
1232 }
1233
1241 void setStartingSpeedReverse(uint8_t motor, uint16_t speed)
1242 {
1243 setVariable(motor, MOTORON_MVAR_STARTING_SPEED_REVERSE, speed);
1244 }
1245
1250 void setStartingSpeed(uint8_t motor, uint16_t speed)
1251 {
1252 setStartingSpeedForward(motor, speed);
1253 if (getLastError()) { return; }
1254 setStartingSpeedReverse(motor, speed);
1255 }
1256
1264 void setDirectionChangeDelayForward(uint8_t motor, uint8_t duration)
1265 {
1266 setVariable(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_FORWARD, duration);
1267 }
1268
1276 void setDirectionChangeDelayReverse(uint8_t motor, uint8_t duration)
1277 {
1278 setVariable(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_REVERSE, duration);
1279 }
1280
1286 void setDirectionChangeDelay(uint8_t motor, uint8_t duration)
1287 {
1288 setDirectionChangeDelayForward(motor, duration);
1289 if (getLastError()) { return; }
1290 setDirectionChangeDelayReverse(motor, duration);
1291 }
1292
1303 void setCurrentLimit(uint8_t motor, uint16_t limit)
1304 {
1305 setVariable(motor, MOTORON_MVAR_CURRENT_LIMIT, limit);
1306 }
1307
1327 void setCurrentSenseOffset(uint8_t motor, uint8_t offset)
1328 {
1329 setVariable(motor, MOTORON_MVAR_CURRENT_SENSE_OFFSET, offset);
1330 }
1331
1347 void setCurrentSenseMinimumDivisor(uint8_t motor, uint16_t speed)
1348 {
1349 setVariable(motor, MOTORON_MVAR_CURRENT_SENSE_MINIMUM_DIVISOR, speed >> 2);
1350 }
1351
1358 {
1359 uint8_t cmd = MOTORON_CMD_COAST_NOW;
1360 sendCommand(1, &cmd);
1361 }
1362
1373 void clearMotorFault(uint8_t flags = 0)
1374 {
1375 uint8_t cmd[] = { MOTORON_CMD_CLEAR_MOTOR_FAULT, (uint8_t)(flags & 0x7F) };
1376 sendCommand(sizeof(cmd), cmd);
1377 }
1378
1385 {
1386 clearMotorFault(1 << MOTORON_CLEAR_MOTOR_FAULT_UNCONDITIONAL);
1387 }
1388
1398 void clearLatchedStatusFlags(uint16_t flags)
1399 {
1400 uint8_t cmd[] = { MOTORON_CMD_CLEAR_LATCHED_STATUS_FLAGS,
1401 (uint8_t)(flags & 0x7F),
1402 (uint8_t)(flags >> 7 & 0x7F)
1403 };
1404 sendCommand(sizeof(cmd), cmd);
1405 }
1406
1415
1424 {
1425 clearLatchedStatusFlags(1 << MOTORON_STATUS_FLAG_RESET);
1426 }
1427
1437 void setLatchedStatusFlags(uint16_t flags)
1438 {
1439 uint8_t cmd[] = { MOTORON_CMD_SET_LATCHED_STATUS_FLAGS,
1440 (uint8_t)(flags & 0x7F),
1441 (uint8_t)(flags >> 7 & 0x7F)
1442 };
1443 sendCommand(sizeof(cmd), cmd);
1444 }
1445
1464 void setSpeed(uint8_t motor, int16_t speed)
1465 {
1466 uint8_t cmd[] = {
1467 MOTORON_CMD_SET_SPEED,
1468 (uint8_t)(motor & 0x7F),
1469 (uint8_t)(speed & 0x7F),
1470 (uint8_t)((speed >> 7) & 0x7F),
1471 };
1472 sendCommand(sizeof(cmd), cmd);
1473 }
1474
1485 void setSpeedNow(uint8_t motor, int16_t speed)
1486 {
1487 uint8_t cmd[] = {
1488 MOTORON_CMD_SET_SPEED_NOW,
1489 (uint8_t)(motor & 0x7F),
1490 (uint8_t)(speed & 0x7F),
1491 (uint8_t)((speed >> 7) & 0x7F),
1492 };
1493 sendCommand(sizeof(cmd), cmd);
1494 }
1495
1510 void setBufferedSpeed(uint8_t motor, int16_t speed)
1511 {
1512 uint8_t cmd[] = {
1513 MOTORON_CMD_SET_BUFFERED_SPEED,
1514 (uint8_t)(motor & 0x7F),
1515 (uint8_t)(speed & 0x7F),
1516 (uint8_t)((speed >> 7) & 0x7F),
1517 };
1518 sendCommand(sizeof(cmd), cmd);
1519 }
1520
1521
1535 void setAllSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
1536 {
1537 uint8_t cmd[] = {
1538 MOTORON_CMD_SET_ALL_SPEEDS,
1539 (uint8_t)(speed1 & 0x7F),
1540 (uint8_t)((speed1 >> 7) & 0x7F),
1541 (uint8_t)(speed2 & 0x7F),
1542 (uint8_t)((speed2 >> 7) & 0x7F),
1543 (uint8_t)(speed3 & 0x7F),
1544 (uint8_t)((speed3 >> 7) & 0x7F),
1545 };
1546 sendCommand(sizeof(cmd), cmd);
1547 }
1548
1550 void setAllSpeeds(int16_t speed1, int16_t speed2)
1551 {
1552 uint8_t cmd[] = {
1553 MOTORON_CMD_SET_ALL_SPEEDS,
1554 (uint8_t)(speed1 & 0x7F),
1555 (uint8_t)((speed1 >> 7) & 0x7F),
1556 (uint8_t)(speed2 & 0x7F),
1557 (uint8_t)((speed2 >> 7) & 0x7F),
1558 };
1559 sendCommand(sizeof(cmd), cmd);
1560 }
1561
1563 void setAllSpeeds(int16_t speed1)
1564 {
1565 uint8_t cmd[] = {
1566 MOTORON_CMD_SET_ALL_SPEEDS,
1567 (uint8_t)(speed1 & 0x7F),
1568 (uint8_t)((speed1 >> 7) & 0x7F),
1569 };
1570 sendCommand(sizeof(cmd), cmd);
1571 }
1572
1586 void setAllSpeedsNow(int16_t speed1, int16_t speed2, int16_t speed3)
1587 {
1588 uint8_t cmd[] = {
1589 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1590 (uint8_t)(speed1 & 0x7F),
1591 (uint8_t)((speed1 >> 7) & 0x7F),
1592 (uint8_t)(speed2 & 0x7F),
1593 (uint8_t)((speed2 >> 7) & 0x7F),
1594 (uint8_t)(speed3 & 0x7F),
1595 (uint8_t)((speed3 >> 7) & 0x7F),
1596 };
1597 sendCommand(sizeof(cmd), cmd);
1598 }
1599
1601 void setAllSpeedsNow(int16_t speed1, int16_t speed2)
1602 {
1603 uint8_t cmd[] = {
1604 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1605 (uint8_t)(speed1 & 0x7F),
1606 (uint8_t)((speed1 >> 7) & 0x7F),
1607 (uint8_t)(speed2 & 0x7F),
1608 (uint8_t)((speed2 >> 7) & 0x7F),
1609 };
1610 sendCommand(sizeof(cmd), cmd);
1611 }
1612
1614 void setAllSpeedsNow(int16_t speed1)
1615 {
1616 uint8_t cmd[] = {
1617 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1618 (uint8_t)(speed1 & 0x7F),
1619 (uint8_t)((speed1 >> 7) & 0x7F),
1620 };
1621 sendCommand(sizeof(cmd), cmd);
1622 }
1623
1643 void setAllBufferedSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
1644 {
1645 uint8_t cmd[] = {
1646 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1647 (uint8_t)(speed1 & 0x7F),
1648 (uint8_t)((speed1 >> 7) & 0x7F),
1649 (uint8_t)(speed2 & 0x7F),
1650 (uint8_t)((speed2 >> 7) & 0x7F),
1651 (uint8_t)(speed3 & 0x7F),
1652 (uint8_t)((speed3 >> 7) & 0x7F),
1653 };
1654 sendCommand(sizeof(cmd), cmd);
1655 }
1656
1658 void setAllBufferedSpeeds(int16_t speed1, int16_t speed2)
1659 {
1660 uint8_t cmd[] = {
1661 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1662 (uint8_t)(speed1 & 0x7F),
1663 (uint8_t)((speed1 >> 7) & 0x7F),
1664 (uint8_t)(speed2 & 0x7F),
1665 (uint8_t)((speed2 >> 7) & 0x7F),
1666 };
1667 sendCommand(sizeof(cmd), cmd);
1668 }
1669
1671 void setAllBufferedSpeeds(int16_t speed1)
1672 {
1673 uint8_t cmd[] = {
1674 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1675 (uint8_t)(speed1 & 0x7F),
1676 (uint8_t)((speed1 >> 7) & 0x7F),
1677 };
1678 sendCommand(sizeof(cmd), cmd);
1679 }
1680
1689 {
1690 uint8_t cmd = MOTORON_CMD_SET_ALL_SPEEDS_USING_BUFFERS;
1691 sendCommand(1, &cmd);
1692 }
1693
1703 {
1704 uint8_t cmd = MOTORON_CMD_SET_ALL_SPEEDS_NOW_USING_BUFFERS;
1705 sendCommand(1, &cmd);
1706 }
1707
1726 void setBraking(uint8_t motor, uint16_t amount)
1727 {
1728 uint8_t cmd[] = {
1729 MOTORON_CMD_SET_BRAKING,
1730 (uint8_t)(motor & 0x7F),
1731 (uint8_t)(amount & 0x7F),
1732 (uint8_t)((amount >> 7) & 0x7F),
1733 };
1734 sendCommand(sizeof(cmd), cmd);
1735 }
1736
1754 void setBrakingNow(uint8_t motor, uint16_t amount)
1755 {
1756 uint8_t cmd[] = {
1757 MOTORON_CMD_SET_BRAKING_NOW,
1758 (uint8_t)(motor & 0x7F),
1759 (uint8_t)(amount & 0x7F),
1760 (uint8_t)((amount >> 7) & 0x7F),
1761 };
1762 sendCommand(sizeof(cmd), cmd);
1763 }
1764
1776 {
1777 uint8_t cmd = MOTORON_CMD_RESET_COMMAND_TIMEOUT;
1778 sendCommand(1, &cmd);
1779 }
1780
1785 static uint8_t calculateCrc(uint8_t length, const uint8_t * buffer,
1786 uint8_t init = 0)
1787 {
1788 uint8_t crc = init;
1789 for (uint8_t i = 0; i < length; i++)
1790 {
1791 crc = pgm_read_byte(&motoronCrcTable[crc ^ buffer[i]]);
1792
1793 // The code below shows an alternative method to calculate the CRC
1794 // without using a lookup table. It will generally be slower but save
1795 // program space.
1796 // crc ^= buffer[i];
1797 // for (uint8_t j = 0; j < 8; j++)
1798 // {
1799 // if (crc & 1) { crc ^= 0x91; }
1800 // crc >>= 1;
1801 // }
1802 }
1803 return crc;
1804 }
1805
1819 static uint16_t calculateCurrentLimit(uint32_t milliamps,
1820 MotoronCurrentSenseType type, uint16_t referenceMv, uint16_t offset)
1821 {
1822 if (milliamps > 1000000) { milliamps = 1000000; }
1823 uint16_t limit = (uint32_t)(offset * 125 + 64) / 128 +
1824 milliamps * 20 / (referenceMv * ((uint8_t)type & 3));
1825 if (limit > 1000) { limit = 1000; }
1826 return limit;
1827 }
1828
1845 static constexpr uint16_t currentSenseUnitsMilliamps(
1846 MotoronCurrentSenseType type, uint16_t referenceMv)
1847 {
1848 return (type == MotoronCurrentSenseType::Motoron453) ? 0
1849 : ((uint32_t)referenceMv * ((uint8_t)type & 3) * 25 / 512);
1850 }
1851
1869 static constexpr uint32_t currentSenseUnitsMicroamps(
1870 MotoronCurrentSenseType type, uint16_t referenceMv)
1871 {
1872 return type == MotoronCurrentSenseType::Motoron453
1873 ? (uint32_t)referenceMv * 625 / 1056
1874 : ((uint32_t)referenceMv * ((uint8_t)type & 3) * 3125 / 64);
1875 }
1876
1877protected:
1880 uint8_t lastError;
1881
1884
1887 void sendCommand(uint8_t length, const uint8_t * cmd)
1888 {
1889 bool sendCrc = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS);
1890 sendCommandCore(length, cmd, sendCrc);
1891 }
1892
1895 void sendCommandAndReadResponse(uint8_t cmdLength, const uint8_t * cmd,
1896 uint8_t responseLength, uint8_t * response)
1897 {
1898 sendCommand(cmdLength, cmd);
1899 if (getLastError())
1900 {
1901 memset(response, 0, responseLength);
1902 return;
1903 }
1904 readResponse(responseLength, response);
1905 }
1906
1907private:
1908
1909 virtual void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) = 0;
1910 virtual void flushTransmission() = 0;
1911 virtual void readResponse(uint8_t length, uint8_t * response) = 0;
1912
1913 static const uint8_t defaultProtocolOptions =
1914 (1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL) |
1915 (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS) |
1916 (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
1917
1918 static const uint16_t defaultErrorMask =
1919 (1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT) |
1920 (1 << MOTORON_STATUS_FLAG_RESET);
1921};
1922
1924class MotoronI2C : public MotoronBase
1925{
1926public:
1931 MotoronI2C(uint8_t address = 16) : bus(&Wire), address(address) {}
1932
1940 void setBus(TwoWire * bus)
1941 {
1942 this->bus = bus;
1943 }
1944
1947 TwoWire * getBus()
1948 {
1949 return this->bus;
1950 }
1951
1954 void setAddress(uint8_t address)
1955 {
1956 this->address = address;
1957 }
1958
1960 uint8_t getAddress()
1961 {
1962 return address;
1963 }
1964
1965private:
1966 TwoWire * bus;
1967 uint8_t address;
1968
1969 void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) override
1970 {
1971 bus->beginTransmission(address);
1972 for (uint8_t i = 0; i < length; i++)
1973 {
1974 bus->write(cmd[i]);
1975 }
1976 if (sendCrc)
1977 {
1978 bus->write(calculateCrc(length, cmd));
1979 }
1980 lastError = bus->endTransmission();
1981 }
1982
1983 void flushTransmission() { }
1984
1985 void readResponse(uint8_t length, uint8_t * response) override
1986 {
1987 bool crcEnabled = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
1988 uint8_t byteCount = bus->requestFrom(address, (uint8_t)(length + crcEnabled));
1989 if (byteCount != length + crcEnabled)
1990 {
1991 memset(response, 0, length);
1992 lastError = 50;
1993 return;
1994 }
1995 lastError = 0;
1996 uint8_t * ptr = response;
1997 for (uint8_t i = 0; i < length; i++)
1998 {
1999 *ptr = bus->read();
2000 ptr++;
2001 }
2002 if (crcEnabled && bus->read() != calculateCrc(length, response))
2003 {
2004 lastError = 51;
2005 return;
2006 }
2007 }
2008};
2009
2021class MotoronSerial : public MotoronBase
2022{
2023public:
2031 MotoronSerial(uint16_t deviceNumber = 0xFFFF) :
2032 port(nullptr), deviceNumber(deviceNumber), communicationOptions(0)
2033 {
2034 }
2035
2038 MotoronSerial(Stream & port, uint16_t deviceNumber = 0xFFFF) :
2039 port(&port), deviceNumber(deviceNumber), communicationOptions(0)
2040 {
2041 }
2042
2050 void setPort(Stream * port)
2051 {
2052 this->port = port;
2053 }
2054
2057 Stream * getPort()
2058 {
2059 return port;
2060 }
2061
2072 void setDeviceNumber(uint16_t deviceNumber)
2073 {
2074 this->deviceNumber = deviceNumber;
2075 }
2076
2082 {
2083 return deviceNumber;
2084 }
2085
2098 void setCommunicationOptions(uint8_t options)
2099 {
2100 communicationOptions = options;
2101 }
2102
2108 {
2109 return communicationOptions;
2110 }
2111
2119 {
2120 communicationOptions |= (1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2121 }
2122
2126 {
2127 communicationOptions &= ~(1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2128 }
2129
2137 {
2138 communicationOptions |= (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER);
2139 }
2140
2144 {
2145 communicationOptions &= ~(1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER);
2146 }
2147
2155 void multiDeviceErrorCheckStart(uint16_t startingDeviceNumber, uint16_t deviceCount)
2156 {
2157 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2158 {
2159 if (deviceCount > 0x3FFF) { lastError = 55; return; }
2160 uint8_t cmd[] = {
2161 MOTORON_CMD_MULTI_DEVICE_ERROR_CHECK,
2162 (uint8_t)(startingDeviceNumber & 0x7F),
2163 (uint8_t)(startingDeviceNumber >> 7 & 0x7F),
2164 (uint8_t)(deviceCount & 0x7F),
2165 (uint8_t)(deviceCount >> 7 & 0x7F),
2166 };
2167 sendCommand(sizeof(cmd), cmd);
2168 }
2169 else
2170 {
2171 if (deviceCount > 0x7F) { lastError = 55; return; }
2172 uint8_t cmd[] = {
2173 MOTORON_CMD_MULTI_DEVICE_ERROR_CHECK,
2174 (uint8_t)(startingDeviceNumber & 0x7F),
2175 (uint8_t)deviceCount,
2176 };
2177 sendCommand(sizeof(cmd), cmd);
2178 }
2179
2180 port->flush();
2181 }
2182
2198 uint16_t multiDeviceErrorCheck(uint16_t startingDeviceNumber, uint16_t deviceCount)
2199 {
2200 multiDeviceErrorCheckStart(startingDeviceNumber, deviceCount);
2201 uint16_t i;
2202 for (i = 0; i < deviceCount; i++)
2203 {
2204 uint8_t response;
2205 size_t byteCount = port->readBytes(&response, 1);
2206 if (byteCount < 1 || response != MOTORON_ERROR_CHECK_CONTINUE)
2207 {
2208 break;
2209 }
2210 }
2211 return i;
2212 }
2213
2220 void multiDeviceWrite(uint16_t startingDeviceNumber, uint16_t deviceCount,
2221 uint8_t bytesPerDevice, uint8_t commandByte, const uint8_t * data)
2222 {
2223 if (port == nullptr) { lastError = 52; return; }
2224 if (bytesPerDevice > 15) { lastError = 56; return; }
2225
2226 bool sendCrc = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS);
2227
2228 uint8_t header[10] = { 0 };
2229 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2230 {
2231 if (deviceCount > 0x3FFF) { lastError = 55; return; }
2232
2233 header[4] = startingDeviceNumber & 0x7F;
2234 header[5] = startingDeviceNumber >> 7 & 0x7F;
2235 header[6] = deviceCount & 0x7F;
2236 header[7] = deviceCount >> 7 & 0x7F;
2237 header[8] = bytesPerDevice;
2238 header[9] = commandByte & 0x7F;
2239
2240 if (deviceNumber == 0xFFFF)
2241 {
2242 header[3] = MOTORON_CMD_MULTI_DEVICE_WRITE;
2243 port->write(header + 3, 7);
2244 }
2245 else
2246 {
2247 header[0] = 0xAA;
2248 header[1] = deviceNumber & 0x7F;
2249 header[2] = deviceNumber >> 7 & 0x7F;
2250 header[3] = MOTORON_CMD_MULTI_DEVICE_WRITE & 0x7F;
2251 port->write(header, 10);
2252 }
2253 }
2254 else
2255 {
2256 if (deviceCount > 0x7F) { lastError = 55; return; }
2257
2258 header[6] = startingDeviceNumber & 0x7F;
2259 header[7] = deviceCount;
2260 header[8] = bytesPerDevice;
2261 header[9] = commandByte & 0x7F;
2262
2263 if (deviceNumber == 0xFFFF)
2264 {
2265 header[5] = MOTORON_CMD_MULTI_DEVICE_WRITE;
2266 port->write(header + 5, 5);
2267 }
2268 else
2269 {
2270 header[3] = 0xAA;
2271 header[4] = deviceNumber & 0x7F;
2272 header[5] = MOTORON_CMD_MULTI_DEVICE_WRITE & 0x7F;
2273 port->write(header + 3, 7);
2274 }
2275 }
2276
2277 uint8_t crc = 0;
2278 if (sendCrc) { crc = calculateCrc(sizeof(header), header); }
2279
2280 if (bytesPerDevice)
2281 {
2282 while (deviceCount)
2283 {
2284 port->write(data, bytesPerDevice);
2285 if (sendCrc) { crc = calculateCrc(bytesPerDevice, data, crc); }
2286 data += bytesPerDevice;
2287 deviceCount--;
2288 }
2289 }
2290
2291 if (sendCrc) { port->write(crc); }
2292 }
2293
2294private:
2295 Stream * port;
2296 uint16_t deviceNumber;
2297 uint8_t communicationOptions;
2298
2299 void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) override
2300 {
2301 if (port == nullptr) { lastError = 52; return; }
2302
2303 if (deviceNumber == 0xFFFF)
2304 {
2305 port->write(cmd, length);
2306 if (sendCrc)
2307 {
2308 port->write(calculateCrc(length, cmd));
2309 }
2310 }
2311 else
2312 {
2313 uint8_t header[4];
2314 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2315 {
2316 header[0] = 0xAA;
2317 header[1] = deviceNumber & 0x7F;
2318 header[2] = deviceNumber >> 7 & 0x7F;
2319 header[3] = cmd[0] & 0x7F;
2320 port->write(header, 4);
2321 }
2322 else
2323 {
2324 header[0] = 0;
2325 header[1] = 0xAA;
2326 header[2] = deviceNumber & 0x7F;
2327 header[3] = cmd[0] & 0x7F;
2328 port->write(header + 1, 3);
2329 }
2330 port->write(cmd + 1, length - 1);
2331 if (sendCrc)
2332 {
2333 uint8_t crc = calculateCrc(sizeof(header), header);
2334 crc = calculateCrc(length - 1, cmd + 1, crc);
2335 port->write(crc);
2336 }
2337 }
2338 lastError = 0;
2339 }
2340
2341 void flushTransmission()
2342 {
2343 if (port == nullptr) { return; }
2344 port->flush();
2345 }
2346
2347 void readResponse(uint8_t length, uint8_t * response) override
2348 {
2349 if (port == nullptr)
2350 {
2351 lastError = 52;
2352 memset(response, 0, length);
2353 return;
2354 }
2355
2356 bool response7Bit = communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2357 if (response7Bit && length > 7)
2358 {
2359 // In 7-bit response mode, the Motoron does not support response
2360 // payloads longer than 7 bytes. That seems short enough that it would be
2361 // good to signal it with a special error code.
2362 lastError = 53;
2363 memset(response, 0, length);
2364 return;
2365 }
2366
2367 port->flush();
2368
2369 size_t byteCount = port->readBytes(response, length);
2370 if (byteCount != length)
2371 {
2372 lastError = 50;
2373 memset(response, 0, length);
2374 return;
2375 }
2376
2377 uint8_t msbs = 0;
2378 if (response7Bit)
2379 {
2380 if (port->readBytes(&msbs, 1) != 1)
2381 {
2382 lastError = 54;
2383 return;
2384 }
2385 }
2386
2387 bool crcEnabled = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
2388 if (crcEnabled)
2389 {
2390 uint8_t crc = 0;
2391 if (port->readBytes(&crc, 1) != 1)
2392 {
2393 lastError = 49;
2394 return;
2395 }
2396
2397 uint8_t expected_crc = calculateCrc(length, response);
2398 if (response7Bit)
2399 {
2400 expected_crc = calculateCrc(1, &msbs, expected_crc);
2401 }
2402
2403 if (crc != expected_crc)
2404 {
2405 lastError = 51;
2406 return;
2407 }
2408 }
2409
2410 if (response7Bit)
2411 {
2412 for (uint8_t i = 0; i < length; i++)
2413 {
2414 if (msbs & 1) { response[i] |= 0x80; }
2415 msbs >>= 1;
2416 }
2417 }
2418
2419 lastError = 0;
2420 }
2421};
MotoronCurrentSenseType
Definition Motoron.h:30
MotoronVinSenseType
Definition Motoron.h:40
@ Motoron550
M*550 Motorons.
Definition Motoron.h:46
@ MotoronHp
High-power Motorons.
Definition Motoron.h:44
@ Motoron256
M*256 Motorons.
Definition Motoron.h:42
void setDirectionChangeDelay(uint8_t motor, uint8_t duration)
Definition Motoron.h:1286
void setCommandTimeoutMilliseconds(uint16_t ms)
Definition Motoron.h:1057
uint16_t getMaxAccelerationForward(uint8_t motor)
Definition Motoron.h:798
uint16_t getCurrentLimit(uint8_t motor)
Definition Motoron.h:903
int16_t getBufferedSpeed(uint8_t motor)
Definition Motoron.h:775
bool getResetFlag()
Definition Motoron.h:588
void setErrorResponse(uint8_t response)
Definition Motoron.h:1079
void setBraking(uint8_t motor, uint16_t amount)
Definition Motoron.h:1726
int16_t getTargetSpeed(uint8_t motor)
Definition Motoron.h:741
uint16_t getMaxDecelerationForward(uint8_t motor)
Definition Motoron.h:822
bool getMotorDrivingFlag()
Definition Motoron.h:633
void clearUARTFaults(uint8_t flags)
Definition Motoron.h:1124
void writeEepromAlternativeDeviceNumber(uint16_t number)
Definition Motoron.h:315
uint16_t getTargetBrakeAmount(uint8_t motor)
Definition Motoron.h:752
uint16_t getMaxAccelerationReverse(uint8_t motor)
Definition Motoron.h:810
uint8_t getErrorResponse()
Definition Motoron.h:708
void setErrorMask(uint16_t mask)
Definition Motoron.h:1091
void writeEepromDeviceNumber(uint16_t number)
Definition Motoron.h:298
void setMaxDeceleration(uint8_t motor, uint16_t decel)
Definition Motoron.h:1215
void setVariable(uint8_t motor, uint8_t offset, uint16_t value)
Definition Motoron.h:1038
uint8_t getJumperState()
Definition Motoron.h:729
uint16_t getStartingSpeedReverse(uint8_t motor)
Definition Motoron.h:866
void enableI2cGeneralCall()
Enables the I2C general call address. See setProtocolOptions().
Definition Motoron.h:214
void coastNow()
Definition Motoron.h:1357
void setAllBufferedSpeeds(int16_t speed1, int16_t speed2)
An overload of setAllBufferedSpeeds() for 2-channel Motorons.
Definition Motoron.h:1658
uint16_t getMaxDecelerationReverse(uint8_t motor)
Definition Motoron.h:834
uint16_t getVar16(uint8_t motor, uint8_t offset)
Definition Motoron.h:457
MotoronCurrentSenseReading getCurrentSenseReading(uint8_t motor)
Definition Motoron.h:919
void writeEeprom(uint8_t offset, uint8_t value)
Definition Motoron.h:262
void enableCrcForCommands()
Enables CRC for commands. See setProtocolOptions().
Definition Motoron.h:186
static constexpr uint32_t currentSenseUnitsMicroamps(MotoronCurrentSenseType type, uint16_t referenceMv)
Definition Motoron.h:1869
static uint8_t calculateCrc(uint8_t length, const uint8_t *buffer, uint8_t init=0)
Definition Motoron.h:1785
uint16_t getErrorMask()
Definition Motoron.h:720
void setCurrentSenseMinimumDivisor(uint8_t motor, uint16_t speed)
Definition Motoron.h:1347
void disableCrc()
Disables CRC for commands and responses. See setProtocolOptions().
Definition Motoron.h:178
void setAllSpeedsUsingBuffers()
Definition Motoron.h:1688
uint16_t getVinVoltage()
Definition Motoron.h:669
void setAllBufferedSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
Definition Motoron.h:1643
uint8_t getCurrentSenseOffset(uint8_t motor)
Definition Motoron.h:1007
uint16_t getCommandTimeoutMilliseconds()
Definition Motoron.h:696
uint32_t getVinVoltageMv(uint16_t referenceMv, MotoronVinSenseType type=MotoronVinSenseType::Motoron256)
Definition Motoron.h:683
void disableCrcForResponses()
Disables CRC for responses. See setProtocolOptions().
Definition Motoron.h:207
void setBufferedSpeed(uint8_t motor, int16_t speed)
Definition Motoron.h:1510
void setStartingSpeedForward(uint8_t motor, uint16_t speed)
Definition Motoron.h:1229
void setMaxAccelerationForward(uint8_t motor, uint16_t accel)
Definition Motoron.h:1159
void getVariables(uint8_t motor, uint8_t offset, uint8_t length, uint8_t *buffer)
Definition Motoron.h:429
bool getMotorFaultLatchedFlag()
Definition Motoron.h:548
void setMaxAccelerationReverse(uint8_t motor, uint16_t accel)
Definition Motoron.h:1171
void disableCrcForCommands()
Disables CRC for commands. See setProtocolOptions().
Definition Motoron.h:193
void enableCrcForResponses()
Enables CRC for responses. See setProtocolOptions().
Definition Motoron.h:200
uint16_t getStatusFlags()
Definition Motoron.h:512
void clearMotorFaultUnconditional()
Definition Motoron.h:1384
void writeEepromDisableAlternativeDeviceNumber()
Definition Motoron.h:331
bool getCommandTimeoutLatchedFlag()
Definition Motoron.h:539
uint8_t getPwmMode(uint8_t motor)
Definition Motoron.h:786
void setProtocolOptionsLocally(uint8_t options)
Definition Motoron.h:156
uint8_t readEepromDeviceNumber()
Definition Motoron.h:245
uint8_t getDirectionChangeDelayForward(uint8_t motor)
Definition Motoron.h:878
uint8_t lastError
Definition Motoron.h:1880
uint8_t getDirectionChangeDelayReverse(uint8_t motor)
Definition Motoron.h:890
void setAllBufferedSpeeds(int16_t speed1)
An overload of setAllBufferedSpeeds() for 1-channel Motorons.
Definition Motoron.h:1671
void reset()
Definition Motoron.h:409
void setDirectionChangeDelayReverse(uint8_t motor, uint8_t duration)
Definition Motoron.h:1276
void setPwmMode(uint8_t motor, uint8_t mode)
Definition Motoron.h:1147
bool getUARTErrorFlag()
Definition Motoron.h:572
void setCurrentLimit(uint8_t motor, uint16_t limit)
Definition Motoron.h:1303
void sendCommandAndReadResponse(uint8_t cmdLength, const uint8_t *cmd, uint8_t responseLength, uint8_t *response)
Definition Motoron.h:1895
void disableI2cGeneralCall()
Disables the I2C general call address. See setProtocolOptions().
Definition Motoron.h:221
void setAllSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
Definition Motoron.h:1535
uint8_t protocolOptions
See setProtocolOptions.
Definition Motoron.h:1883
bool getProtocolErrorFlag()
Definition Motoron.h:521
void resetCommandTimeout()
Definition Motoron.h:1775
void setLatchedStatusFlags(uint16_t flags)
Definition Motoron.h:1437
uint8_t getProtocolOptionsLocally()
Definition Motoron.h:164
void getFirmwareVersion(uint16_t *productId, uint16_t *firmwareVersion)
Definition Motoron.h:89
bool getNoPowerFlag()
Definition Motoron.h:606
void setAllSpeedsNow(int16_t speed1, int16_t speed2, int16_t speed3)
Definition Motoron.h:1586
void setAllSpeeds(int16_t speed1)
An overload of setAllSpeeds() for single-channel Motorons.
Definition Motoron.h:1563
void setMaxDecelerationReverse(uint8_t motor, uint16_t decel)
Definition Motoron.h:1206
void setStartingSpeed(uint8_t motor, uint16_t speed)
Definition Motoron.h:1250
void clearResetFlag()
Definition Motoron.h:1423
void clearLatchedStatusFlags(uint16_t flags)
Definition Motoron.h:1398
bool getCrcErrorFlag()
Definition Motoron.h:530
void setMaxDecelerationForward(uint8_t motor, uint16_t decel)
Definition Motoron.h:1194
static constexpr uint16_t currentSenseUnitsMilliamps(MotoronCurrentSenseType type, uint16_t referenceMv)
Definition Motoron.h:1845
MotoronCurrentSenseReading getCurrentSenseProcessedAndSpeed(uint8_t motor)
Definition Motoron.h:952
bool getMotorOutputEnabledFlag()
Definition Motoron.h:624
uint16_t getCurrentSenseRaw(uint8_t motor)
Definition Motoron.h:970
void setCurrentSenseOffset(uint8_t motor, uint8_t offset)
Definition Motoron.h:1327
void setMaxAcceleration(uint8_t motor, uint16_t accel)
Definition Motoron.h:1180
bool getErrorActiveFlag()
Definition Motoron.h:615
void sendCommand(uint8_t length, const uint8_t *cmd)
Definition Motoron.h:1887
uint8_t getLastError()
Definition Motoron.h:74
uint8_t getUARTFaults()
Definition Motoron.h:658
void setStartingSpeedReverse(uint8_t motor, uint16_t speed)
Definition Motoron.h:1241
uint16_t getStartingSpeedForward(uint8_t motor)
Definition Motoron.h:855
void writeEepromBaudRate(uint32_t baud)
Definition Motoron.h:363
void setAllSpeeds(int16_t speed1, int16_t speed2)
An overload of setAllSpeeds() for 2-channel Motorons.
Definition Motoron.h:1550
void setAllSpeedsNowUsingBuffers()
Definition Motoron.h:1702
bool getNoPowerLatchedFlag()
Definition Motoron.h:557
uint16_t getCurrentSenseMinimumDivisor(uint8_t motor)
Definition Motoron.h:1021
void disableCommandTimeout()
Definition Motoron.h:1111
void setDirectionChangeDelayForward(uint8_t motor, uint8_t duration)
Definition Motoron.h:1264
uint8_t getVar8(uint8_t motor, uint8_t offset)
Definition Motoron.h:445
void writeEeprom16(uint8_t offset, uint16_t value)
Definition Motoron.h:284
void setAllSpeedsNow(int16_t speed1)
An overload of setAllSpeedsNow() for single-channel Motorons.
Definition Motoron.h:1614
void setBrakingNow(uint8_t motor, uint16_t amount)
Definition Motoron.h:1754
void enableCrc()
Enables CRC for commands and responses. See setProtocolOptions().
Definition Motoron.h:170
uint16_t getCurrentSenseProcessed(uint8_t motor)
Definition Motoron.h:994
void readEeprom(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition Motoron.h:231
void setSpeed(uint8_t motor, int16_t speed)
Definition Motoron.h:1464
void writeEepromResponseDelay(uint8_t delay)
Definition Motoron.h:379
bool getMotorFaultingFlag()
Definition Motoron.h:597
static uint16_t calculateCurrentLimit(uint32_t milliamps, MotoronCurrentSenseType type, uint16_t referenceMv, uint16_t offset)
Definition Motoron.h:1819
void setSpeedNow(uint8_t motor, int16_t speed)
Definition Motoron.h:1485
void reinitialize()
Definition Motoron.h:391
void setAllSpeedsNow(int16_t speed1, int16_t speed2)
An overload of setAllSpeedsNow() for 2-channel Motorons.
Definition Motoron.h:1601
void setProtocolOptions(uint8_t options)
Definition Motoron.h:137
void clearMotorFault(uint8_t flags=0)
Definition Motoron.h:1373
MotoronCurrentSenseReading getCurrentSenseRawAndSpeed(uint8_t motor)
Definition Motoron.h:936
int16_t getCurrentSpeed(uint8_t motor)
Definition Motoron.h:764
void writeEepromCommunicationOptions(uint8_t options)
Definition Motoron.h:349
void setBus(TwoWire *bus)
Definition Motoron.h:1940
void setAddress(uint8_t address)
Definition Motoron.h:1954
TwoWire * getBus()
Definition Motoron.h:1947
MotoronI2C(uint8_t address=16)
Definition Motoron.h:1931
uint8_t getAddress()
Returns the 7-bit I2C address that this object is configured to use.
Definition Motoron.h:1960
void setCommunicationOptions(uint8_t options)
Definition Motoron.h:2098
MotoronSerial(Stream &port, uint16_t deviceNumber=0xFFFF)
Definition Motoron.h:2038
void use7BitDeviceNumber()
Definition Motoron.h:2143
void expect8BitResponses()
Definition Motoron.h:2125
uint16_t multiDeviceErrorCheck(uint16_t startingDeviceNumber, uint16_t deviceCount)
Definition Motoron.h:2198
void multiDeviceWrite(uint16_t startingDeviceNumber, uint16_t deviceCount, uint8_t bytesPerDevice, uint8_t commandByte, const uint8_t *data)
Definition Motoron.h:2220
void multiDeviceErrorCheckStart(uint16_t startingDeviceNumber, uint16_t deviceCount)
Definition Motoron.h:2155
uint8_t getCommunicationOptionsLocally()
Definition Motoron.h:2107
MotoronSerial(uint16_t deviceNumber=0xFFFF)
Definition Motoron.h:2031
uint16_t getDeviceNumber()
Definition Motoron.h:2081
void use14BitDeviceNumber()
Definition Motoron.h:2136
void setPort(Stream *port)
Definition Motoron.h:2050
void setDeviceNumber(uint16_t deviceNumber)
Definition Motoron.h:2072
Stream * getPort()
Definition Motoron.h:2057
void expect7BitResponses()
Definition Motoron.h:2118