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};
36
41 Motoron256 = 0b0000,
43 MotoronHp = 0b0010,
45 Motoron550 = 0b0011,
46};
47
49{
50 uint16_t raw;
51 int16_t speed;
52 uint16_t processed;
53};
54
61{
62public:
64 {
65 lastError = 0;
66 protocolOptions = defaultProtocolOptions;
67 }
68
71 uint8_t getLastError()
72 {
73 return lastError;
74 }
75
86 void getFirmwareVersion(uint16_t * productId, uint16_t * firmwareVersion)
87 {
88 uint8_t cmd = MOTORON_CMD_GET_FIRMWARE_VERSION;
89 uint8_t response[4];
90 sendCommandAndReadResponse(1, &cmd, sizeof(response), response);
91 if (productId != nullptr) { *productId = response[0] | (response[1] << 8); }
92 if (firmwareVersion != nullptr) { *firmwareVersion = response[2] | (response[3] << 8); }
93 }
94
134 void setProtocolOptions(uint8_t options)
135 {
136 this->protocolOptions = options;
137 uint8_t cmd[] = {
138 MOTORON_CMD_SET_PROTOCOL_OPTIONS,
139 (uint8_t)(options & 0x7F),
140 (uint8_t)(~options & 0x7F),
141 };
142 sendCommandCore(sizeof(cmd), cmd, true);
143 if (getLastError()) { return; }
144 }
145
153 void setProtocolOptionsLocally(uint8_t options)
154 {
155 this->protocolOptions = options;
156 }
157
162 {
163 return this->protocolOptions;
164 }
165
168 {
170 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS)
171 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
172 }
173
176 {
178 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS)
179 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
180 }
181
184 {
186 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS));
187 }
188
191 {
193 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS));
194 }
195
198 {
200 | (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
201 }
202
205 {
207 & ~(1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES));
208 }
209
212 {
214 | (1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL));
215 }
216
219 {
221 & ~(1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL));
222 }
223
228 void readEeprom(uint8_t offset, uint8_t length, uint8_t * buffer)
229 {
230 uint8_t cmd[] = {
231 MOTORON_CMD_READ_EEPROM,
232 (uint8_t)(offset & 0x7F),
233 (uint8_t)(length & 0x7F),
234 };
235 sendCommandAndReadResponse(sizeof(cmd), cmd, length, buffer);
236 }
237
243 {
244 uint8_t number;
245 readEeprom(MOTORON_SETTING_DEVICE_NUMBER, 1, &number);
246 return number;
247 }
248
259 void writeEeprom(uint8_t offset, uint8_t value)
260 {
261 uint8_t cmd[7];
262 cmd[0] = MOTORON_CMD_WRITE_EEPROM;
263 cmd[1] = offset & 0x7F;
264 cmd[2] = value & 0x7F;
265 cmd[3] = value >> 7 & 1;
266 cmd[4] = cmd[1] ^ 0x7F;
267 cmd[5] = cmd[2] ^ 0x7F;
268 cmd[6] = cmd[3] ^ 0x7F;
269 sendCommand(sizeof(cmd), cmd);
270 flushTransmission();
271 delay(6);
272 }
273
281 void writeEeprom16(uint8_t offset, uint16_t value)
282 {
283 writeEeprom(offset, value & 0xFF);
284 writeEeprom(offset + 1, value >> 8 & 0xFF);
285 }
286
295 void writeEepromDeviceNumber(uint16_t number)
296 {
297 writeEeprom(MOTORON_SETTING_DEVICE_NUMBER, number & 0x7F);
298 writeEeprom(MOTORON_SETTING_DEVICE_NUMBER + 1, number >> 7 & 0x7F);
299 }
300
313 {
314 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER, (number & 0x7F) | 0x80);
315 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER + 1, number >> 7 & 0x7F);
316 }
317
329 {
330 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER, 0);
331 writeEeprom(MOTORON_SETTING_ALTERNATIVE_DEVICE_NUMBER + 1, 0);
332 }
333
347 {
348 writeEeprom(MOTORON_SETTING_COMMUNICATION_OPTIONS, options);
349 }
350
360 void writeEepromBaudRate(uint32_t baud)
361 {
362 if (baud < MOTORON_MIN_BAUD_RATE) { baud = MOTORON_MIN_BAUD_RATE; }
363 if (baud > MOTORON_MAX_BAUD_RATE) { baud = MOTORON_MAX_BAUD_RATE; }
364 writeEeprom16(MOTORON_SETTING_BAUD_DIVIDER, (16000000 + (baud >> 1)) / baud);
365 }
366
376 void writeEepromResponseDelay(uint8_t delay)
377 {
378 writeEeprom(MOTORON_SETTING_RESPONSE_DELAY, delay);
379 }
380
389 {
390 // Always send the reset command with a CRC byte to make it more reliable.
391 uint8_t cmd = MOTORON_CMD_REINITIALIZE;
392 sendCommandCore(1, &cmd, true);
393 protocolOptions = defaultProtocolOptions;
394 }
395
406 void reset()
407 {
408 uint8_t cmd = MOTORON_CMD_RESET;
409 sendCommandCore(1, &cmd, true);
410 flushTransmission();
411 protocolOptions = defaultProtocolOptions;
412 }
413
426 void getVariables(uint8_t motor, uint8_t offset, uint8_t length, uint8_t * buffer)
427 {
428 uint8_t cmd[] = {
429 MOTORON_CMD_GET_VARIABLES,
430 (uint8_t)(motor & 0x7F),
431 (uint8_t)(offset & 0x7F),
432 (uint8_t)(length & 0x7F),
433 };
434 sendCommandAndReadResponse(sizeof(cmd), cmd, length, buffer);
435 }
436
442 uint8_t getVar8(uint8_t motor, uint8_t offset)
443 {
444 uint8_t result;
445 getVariables(motor, offset, 1, &result);
446 return result;
447 }
448
454 uint16_t getVar16(uint8_t motor, uint8_t offset)
455 {
456 uint8_t buffer[2];
457 getVariables(motor, offset, 2, buffer);
458 return buffer[0] | ((uint16_t)buffer[1] << 8);
459 }
460
509 uint16_t getStatusFlags()
510 {
511 return getVar16(0, MOTORON_VAR_STATUS_FLAGS);
512 }
513
519 {
520 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_PROTOCOL_ERROR);
521 }
522
528 {
529 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_CRC_ERROR);
530 }
531
537 {
538 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT_LATCHED);
539 }
540
546 {
547 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_FAULT_LATCHED);
548 }
549
555 {
556 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_NO_POWER_LATCHED);
557 }
558
570 {
571 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_UART_ERROR);
572 }
573
586 {
587 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_RESET);
588 }
589
595 {
596 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_FAULTING);
597 }
598
604 {
605 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_NO_POWER);
606 }
607
613 {
614 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_ERROR_ACTIVE);
615 }
616
622 {
623 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_OUTPUT_ENABLED);
624 }
625
631 {
632 return getStatusFlags() & (1 << MOTORON_STATUS_FLAG_MOTOR_DRIVING);
633 }
634
656 {
657 return getVar8(0, MOTORON_VAR_UART_FAULTS);
658 }
659
666 uint16_t getVinVoltage()
667 {
668 return getVar16(0, MOTORON_VAR_VIN_VOLTAGE);
669 }
670
681 uint32_t getVinVoltageMv(uint16_t referenceMv,
682 MotoronVinSenseType type = MotoronVinSenseType::Motoron256)
683 {
684 uint16_t scale = (uint8_t)type & 1 ? 459 : 1047;
685 return (uint32_t)getVinVoltage() * referenceMv / 1024 * scale / 47;
686 }
687
695 {
696 return getVar16(0, MOTORON_VAR_COMMAND_TIMEOUT) * 4;
697 }
698
707 {
708 return getVar8(0, MOTORON_VAR_ERROR_RESPONSE);
709 }
710
718 uint16_t getErrorMask()
719 {
720 return getVar16(0, MOTORON_VAR_ERROR_MASK);
721 }
722
728 {
729 return getVar8(0, MOTORON_VAR_JUMPER_STATE);
730 }
731
739 int16_t getTargetSpeed(uint8_t motor)
740 {
741 return getVar16(motor, MOTORON_MVAR_TARGET_SPEED);
742 }
743
750 uint16_t getTargetBrakeAmount(uint8_t motor)
751 {
752 return getVar16(motor, MOTORON_MVAR_TARGET_BRAKE_AMOUNT);
753 }
754
762 int16_t getCurrentSpeed(uint8_t motor)
763 {
764 return getVar16(motor, MOTORON_MVAR_CURRENT_SPEED);
765 }
766
773 int16_t getBufferedSpeed(uint8_t motor)
774 {
775 return getVar16(motor, MOTORON_MVAR_BUFFERED_SPEED);
776 }
777
784 uint8_t getPwmMode(uint8_t motor)
785 {
786 return getVar8(motor, MOTORON_MVAR_PWM_MODE);
787 }
788
796 uint16_t getMaxAccelerationForward(uint8_t motor)
797 {
798 return getVar16(motor, MOTORON_MVAR_MAX_ACCEL_FORWARD);
799 }
800
808 uint16_t getMaxAccelerationReverse(uint8_t motor)
809 {
810 return getVar16(motor, MOTORON_MVAR_MAX_ACCEL_REVERSE);
811 }
812
820 uint16_t getMaxDecelerationForward(uint8_t motor)
821 {
822 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_FORWARD);
823 }
824
832 uint16_t getMaxDecelerationReverse(uint8_t motor)
833 {
834 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_REVERSE);
835 }
836
838
839 // This function is used by Pololu for testing.
840 uint16_t getMaxDecelerationTemporary(uint8_t motor)
841 {
842 return getVar16(motor, MOTORON_MVAR_MAX_DECEL_TMP);
843 }
844
846
853 uint16_t getStartingSpeedForward(uint8_t motor)
854 {
855 return getVar16(motor, MOTORON_MVAR_STARTING_SPEED_FORWARD);
856 }
857
864 uint16_t getStartingSpeedReverse(uint8_t motor)
865 {
866 return getVar16(motor, MOTORON_MVAR_STARTING_SPEED_REVERSE);
867 }
868
876 uint8_t getDirectionChangeDelayForward(uint8_t motor)
877 {
878 return getVar8(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_FORWARD);
879 }
880
888 uint8_t getDirectionChangeDelayReverse(uint8_t motor)
889 {
890 return getVar8(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_REVERSE);
891 }
892
901 uint16_t getCurrentLimit(uint8_t motor)
902 {
903 return getVar16(motor, MOTORON_MVAR_CURRENT_LIMIT);
904 }
905
918 {
919 uint8_t buffer[6];
920 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_RAW, sizeof(buffer), buffer);
922 r.raw = buffer[0] | ((uint16_t)buffer[1] << 8);
923 r.speed = buffer[2] | ((uint16_t)buffer[3] << 8);
924 r.processed = buffer[4] | ((uint16_t)buffer[5] << 8);
925 return r;
926 }
927
935 {
936 uint8_t buffer[4];
937 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_RAW, sizeof(buffer), buffer);
939 r.raw = buffer[0] | ((uint16_t)buffer[1] << 8);
940 r.speed = buffer[2] | ((uint16_t)buffer[3] << 8);
941 return r;
942 }
943
951 {
952 uint8_t buffer[4];
953 getVariables(motor, MOTORON_MVAR_CURRENT_SENSE_SPEED, sizeof(buffer), buffer);
955 r.speed = buffer[0] | ((uint16_t)buffer[1] << 8);
956 r.processed = buffer[2] | ((uint16_t)buffer[3] << 8);
957 return r;
958 }
959
968 uint16_t getCurrentSenseRaw(uint8_t motor)
969 {
970 return getVar16(motor, MOTORON_MVAR_CURRENT_SENSE_RAW);
971 }
972
990 uint16_t getCurrentSenseProcessed(uint8_t motor)
991 {
992 return getVar16(motor, MOTORON_MVAR_CURRENT_SENSE_PROCESSED);
993 }
994
1003 uint8_t getCurrentSenseOffset(uint8_t motor)
1004 {
1005 return getVar8(motor, MOTORON_MVAR_CURRENT_SENSE_OFFSET);
1006 }
1007
1017 uint16_t getCurrentSenseMinimumDivisor(uint8_t motor)
1018 {
1019 return getVar8(motor, MOTORON_MVAR_CURRENT_SENSE_MINIMUM_DIVISOR) << 2;
1020 }
1021
1034 void setVariable(uint8_t motor, uint8_t offset, uint16_t value)
1035 {
1036 if (value > 0x3FFF) { value = 0x3FFF; }
1037 uint8_t cmd[] = {
1038 MOTORON_CMD_SET_VARIABLE,
1039 (uint8_t)(motor & 0x1F),
1040 (uint8_t)(offset & 0x7F),
1041 (uint8_t)(value & 0x7F),
1042 (uint8_t)((value >> 7) & 0x7F),
1043 };
1044 sendCommand(sizeof(cmd), cmd);
1045 }
1046
1054 {
1055 // Divide by 4, but round up, and make sure we don't have
1056 // an overflow if 0xFFFF is passed.
1057 uint16_t timeout = (ms / 4) + ((ms & 3) ? 1 : 0);
1058 setVariable(0, MOTORON_VAR_COMMAND_TIMEOUT, timeout);
1059 }
1060
1075 void setErrorResponse(uint8_t response)
1076 {
1077 setVariable(0, MOTORON_VAR_ERROR_RESPONSE, response);
1078 }
1079
1087 void setErrorMask(uint16_t mask)
1088 {
1089 setVariable(0, MOTORON_VAR_ERROR_MASK, mask);
1090 }
1091
1108 {
1109 setErrorMask(defaultErrorMask & ~(1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT));
1110 }
1111
1120 void clearUARTFaults(uint8_t flags)
1121 {
1122 setVariable(0, MOTORON_VAR_UART_FAULTS, ~(uint16_t)flags & 0x3FFF);
1123 }
1124
1143 void setPwmMode(uint8_t motor, uint8_t mode)
1144 {
1145 setVariable(motor, MOTORON_MVAR_PWM_MODE, mode);
1146 }
1147
1155 void setMaxAccelerationForward(uint8_t motor, uint16_t accel)
1156 {
1157 setVariable(motor, MOTORON_MVAR_MAX_ACCEL_FORWARD, accel);
1158 }
1159
1167 void setMaxAccelerationReverse(uint8_t motor, uint16_t accel)
1168 {
1169 setVariable(motor, MOTORON_MVAR_MAX_ACCEL_REVERSE, accel);
1170 }
1171
1176 void setMaxAcceleration(uint8_t motor, uint16_t accel)
1177 {
1178 setMaxAccelerationForward(motor, accel);
1179 if (getLastError()) { return; }
1180 setMaxAccelerationReverse(motor, accel);
1181 }
1182
1190 void setMaxDecelerationForward(uint8_t motor, uint16_t decel)
1191 {
1192 setVariable(motor, MOTORON_MVAR_MAX_DECEL_FORWARD, decel);
1193 }
1194
1202 void setMaxDecelerationReverse(uint8_t motor, uint16_t decel)
1203 {
1204 setVariable(motor, MOTORON_MVAR_MAX_DECEL_REVERSE, decel);
1205 }
1206
1211 void setMaxDeceleration(uint8_t motor, uint16_t decel)
1212 {
1213 setMaxDecelerationForward(motor, decel);
1214 if (getLastError()) { return; }
1215 setMaxDecelerationReverse(motor, decel);
1216 }
1217
1225 void setStartingSpeedForward(uint8_t motor, uint16_t speed)
1226 {
1227 setVariable(motor, MOTORON_MVAR_STARTING_SPEED_FORWARD, speed);
1228 }
1229
1237 void setStartingSpeedReverse(uint8_t motor, uint16_t speed)
1238 {
1239 setVariable(motor, MOTORON_MVAR_STARTING_SPEED_REVERSE, speed);
1240 }
1241
1246 void setStartingSpeed(uint8_t motor, uint16_t speed)
1247 {
1248 setStartingSpeedForward(motor, speed);
1249 if (getLastError()) { return; }
1250 setStartingSpeedReverse(motor, speed);
1251 }
1252
1260 void setDirectionChangeDelayForward(uint8_t motor, uint8_t duration)
1261 {
1262 setVariable(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_FORWARD, duration);
1263 }
1264
1272 void setDirectionChangeDelayReverse(uint8_t motor, uint8_t duration)
1273 {
1274 setVariable(motor, MOTORON_MVAR_DIRECTION_CHANGE_DELAY_REVERSE, duration);
1275 }
1276
1282 void setDirectionChangeDelay(uint8_t motor, uint8_t duration)
1283 {
1284 setDirectionChangeDelayForward(motor, duration);
1285 if (getLastError()) { return; }
1286 setDirectionChangeDelayReverse(motor, duration);
1287 }
1288
1299 void setCurrentLimit(uint8_t motor, uint16_t limit)
1300 {
1301 setVariable(motor, MOTORON_MVAR_CURRENT_LIMIT, limit);
1302 }
1303
1323 void setCurrentSenseOffset(uint8_t motor, uint8_t offset)
1324 {
1325 setVariable(motor, MOTORON_MVAR_CURRENT_SENSE_OFFSET, offset);
1326 }
1327
1343 void setCurrentSenseMinimumDivisor(uint8_t motor, uint16_t speed)
1344 {
1345 setVariable(motor, MOTORON_MVAR_CURRENT_SENSE_MINIMUM_DIVISOR, speed >> 2);
1346 }
1347
1354 {
1355 uint8_t cmd = MOTORON_CMD_COAST_NOW;
1356 sendCommand(1, &cmd);
1357 }
1358
1369 void clearMotorFault(uint8_t flags = 0)
1370 {
1371 uint8_t cmd[] = { MOTORON_CMD_CLEAR_MOTOR_FAULT, (uint8_t)(flags & 0x7F) };
1372 sendCommand(sizeof(cmd), cmd);
1373 }
1374
1381 {
1382 clearMotorFault(1 << MOTORON_CLEAR_MOTOR_FAULT_UNCONDITIONAL);
1383 }
1384
1394 void clearLatchedStatusFlags(uint16_t flags)
1395 {
1396 uint8_t cmd[] = { MOTORON_CMD_CLEAR_LATCHED_STATUS_FLAGS,
1397 (uint8_t)(flags & 0x7F),
1398 (uint8_t)(flags >> 7 & 0x7F)
1399 };
1400 sendCommand(sizeof(cmd), cmd);
1401 }
1402
1411
1420 {
1421 clearLatchedStatusFlags(1 << MOTORON_STATUS_FLAG_RESET);
1422 }
1423
1433 void setLatchedStatusFlags(uint16_t flags)
1434 {
1435 uint8_t cmd[] = { MOTORON_CMD_SET_LATCHED_STATUS_FLAGS,
1436 (uint8_t)(flags & 0x7F),
1437 (uint8_t)(flags >> 7 & 0x7F)
1438 };
1439 sendCommand(sizeof(cmd), cmd);
1440 }
1441
1460 void setSpeed(uint8_t motor, int16_t speed)
1461 {
1462 uint8_t cmd[] = {
1463 MOTORON_CMD_SET_SPEED,
1464 (uint8_t)(motor & 0x7F),
1465 (uint8_t)(speed & 0x7F),
1466 (uint8_t)((speed >> 7) & 0x7F),
1467 };
1468 sendCommand(sizeof(cmd), cmd);
1469 }
1470
1481 void setSpeedNow(uint8_t motor, int16_t speed)
1482 {
1483 uint8_t cmd[] = {
1484 MOTORON_CMD_SET_SPEED_NOW,
1485 (uint8_t)(motor & 0x7F),
1486 (uint8_t)(speed & 0x7F),
1487 (uint8_t)((speed >> 7) & 0x7F),
1488 };
1489 sendCommand(sizeof(cmd), cmd);
1490 }
1491
1506 void setBufferedSpeed(uint8_t motor, int16_t speed)
1507 {
1508 uint8_t cmd[] = {
1509 MOTORON_CMD_SET_BUFFERED_SPEED,
1510 (uint8_t)(motor & 0x7F),
1511 (uint8_t)(speed & 0x7F),
1512 (uint8_t)((speed >> 7) & 0x7F),
1513 };
1514 sendCommand(sizeof(cmd), cmd);
1515 }
1516
1517
1531 void setAllSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
1532 {
1533 uint8_t cmd[] = {
1534 MOTORON_CMD_SET_ALL_SPEEDS,
1535 (uint8_t)(speed1 & 0x7F),
1536 (uint8_t)((speed1 >> 7) & 0x7F),
1537 (uint8_t)(speed2 & 0x7F),
1538 (uint8_t)((speed2 >> 7) & 0x7F),
1539 (uint8_t)(speed3 & 0x7F),
1540 (uint8_t)((speed3 >> 7) & 0x7F),
1541 };
1542 sendCommand(sizeof(cmd), cmd);
1543 }
1544
1546 void setAllSpeeds(int16_t speed1, int16_t speed2)
1547 {
1548 uint8_t cmd[] = {
1549 MOTORON_CMD_SET_ALL_SPEEDS,
1550 (uint8_t)(speed1 & 0x7F),
1551 (uint8_t)((speed1 >> 7) & 0x7F),
1552 (uint8_t)(speed2 & 0x7F),
1553 (uint8_t)((speed2 >> 7) & 0x7F),
1554 };
1555 sendCommand(sizeof(cmd), cmd);
1556 }
1557
1559 void setAllSpeeds(int16_t speed1)
1560 {
1561 uint8_t cmd[] = {
1562 MOTORON_CMD_SET_ALL_SPEEDS,
1563 (uint8_t)(speed1 & 0x7F),
1564 (uint8_t)((speed1 >> 7) & 0x7F),
1565 };
1566 sendCommand(sizeof(cmd), cmd);
1567 }
1568
1582 void setAllSpeedsNow(int16_t speed1, int16_t speed2, int16_t speed3)
1583 {
1584 uint8_t cmd[] = {
1585 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1586 (uint8_t)(speed1 & 0x7F),
1587 (uint8_t)((speed1 >> 7) & 0x7F),
1588 (uint8_t)(speed2 & 0x7F),
1589 (uint8_t)((speed2 >> 7) & 0x7F),
1590 (uint8_t)(speed3 & 0x7F),
1591 (uint8_t)((speed3 >> 7) & 0x7F),
1592 };
1593 sendCommand(sizeof(cmd), cmd);
1594 }
1595
1597 void setAllSpeedsNow(int16_t speed1, int16_t speed2)
1598 {
1599 uint8_t cmd[] = {
1600 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1601 (uint8_t)(speed1 & 0x7F),
1602 (uint8_t)((speed1 >> 7) & 0x7F),
1603 (uint8_t)(speed2 & 0x7F),
1604 (uint8_t)((speed2 >> 7) & 0x7F),
1605 };
1606 sendCommand(sizeof(cmd), cmd);
1607 }
1608
1610 void setAllSpeedsNow(int16_t speed1)
1611 {
1612 uint8_t cmd[] = {
1613 MOTORON_CMD_SET_ALL_SPEEDS_NOW,
1614 (uint8_t)(speed1 & 0x7F),
1615 (uint8_t)((speed1 >> 7) & 0x7F),
1616 };
1617 sendCommand(sizeof(cmd), cmd);
1618 }
1619
1639 void setAllBufferedSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
1640 {
1641 uint8_t cmd[] = {
1642 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1643 (uint8_t)(speed1 & 0x7F),
1644 (uint8_t)((speed1 >> 7) & 0x7F),
1645 (uint8_t)(speed2 & 0x7F),
1646 (uint8_t)((speed2 >> 7) & 0x7F),
1647 (uint8_t)(speed3 & 0x7F),
1648 (uint8_t)((speed3 >> 7) & 0x7F),
1649 };
1650 sendCommand(sizeof(cmd), cmd);
1651 }
1652
1654 void setAllBufferedSpeeds(int16_t speed1, int16_t speed2)
1655 {
1656 uint8_t cmd[] = {
1657 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1658 (uint8_t)(speed1 & 0x7F),
1659 (uint8_t)((speed1 >> 7) & 0x7F),
1660 (uint8_t)(speed2 & 0x7F),
1661 (uint8_t)((speed2 >> 7) & 0x7F),
1662 };
1663 sendCommand(sizeof(cmd), cmd);
1664 }
1665
1667 void setAllBufferedSpeeds(int16_t speed1)
1668 {
1669 uint8_t cmd[] = {
1670 MOTORON_CMD_SET_ALL_BUFFERED_SPEEDS,
1671 (uint8_t)(speed1 & 0x7F),
1672 (uint8_t)((speed1 >> 7) & 0x7F),
1673 };
1674 sendCommand(sizeof(cmd), cmd);
1675 }
1676
1685 {
1686 uint8_t cmd = MOTORON_CMD_SET_ALL_SPEEDS_USING_BUFFERS;
1687 sendCommand(1, &cmd);
1688 }
1689
1699 {
1700 uint8_t cmd = MOTORON_CMD_SET_ALL_SPEEDS_NOW_USING_BUFFERS;
1701 sendCommand(1, &cmd);
1702 }
1703
1722 void setBraking(uint8_t motor, uint16_t amount)
1723 {
1724 uint8_t cmd[] = {
1725 MOTORON_CMD_SET_BRAKING,
1726 (uint8_t)(motor & 0x7F),
1727 (uint8_t)(amount & 0x7F),
1728 (uint8_t)((amount >> 7) & 0x7F),
1729 };
1730 sendCommand(sizeof(cmd), cmd);
1731 }
1732
1750 void setBrakingNow(uint8_t motor, uint16_t amount)
1751 {
1752 uint8_t cmd[] = {
1753 MOTORON_CMD_SET_BRAKING_NOW,
1754 (uint8_t)(motor & 0x7F),
1755 (uint8_t)(amount & 0x7F),
1756 (uint8_t)((amount >> 7) & 0x7F),
1757 };
1758 sendCommand(sizeof(cmd), cmd);
1759 }
1760
1772 {
1773 uint8_t cmd = MOTORON_CMD_RESET_COMMAND_TIMEOUT;
1774 sendCommand(1, &cmd);
1775 }
1776
1781 static uint8_t calculateCrc(uint8_t length, const uint8_t * buffer,
1782 uint8_t init = 0)
1783 {
1784 uint8_t crc = init;
1785 for (uint8_t i = 0; i < length; i++)
1786 {
1787 crc = pgm_read_byte(&motoronCrcTable[crc ^ buffer[i]]);
1788
1789 // The code below shows an alternative method to calculate the CRC
1790 // without using a lookup table. It will generally be slower but save
1791 // program space.
1792 // crc ^= buffer[i];
1793 // for (uint8_t j = 0; j < 8; j++)
1794 // {
1795 // if (crc & 1) { crc ^= 0x91; }
1796 // crc >>= 1;
1797 // }
1798 }
1799 return crc;
1800 }
1801
1815 static uint16_t calculateCurrentLimit(uint32_t milliamps,
1816 MotoronCurrentSenseType type, uint16_t referenceMv, uint16_t offset)
1817 {
1818 if (milliamps > 1000000) { milliamps = 1000000; }
1819 uint16_t limit = (uint32_t)(offset * 125 + 64) / 128 +
1820 milliamps * 20 / (referenceMv * ((uint8_t)type & 3));
1821 if (limit > 1000) { limit = 1000; }
1822 return limit;
1823 }
1824
1837 static constexpr uint16_t currentSenseUnitsMilliamps(
1838 MotoronCurrentSenseType type, uint16_t referenceMv)
1839 {
1840 return ((uint32_t)referenceMv * ((uint8_t)type & 3) * 25 / 512);
1841 }
1842
1843protected:
1846 uint8_t lastError;
1847
1850
1853 void sendCommand(uint8_t length, const uint8_t * cmd)
1854 {
1855 bool sendCrc = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS);
1856 sendCommandCore(length, cmd, sendCrc);
1857 }
1858
1861 void sendCommandAndReadResponse(uint8_t cmdLength, const uint8_t * cmd,
1862 uint8_t responseLength, uint8_t * response)
1863 {
1864 sendCommand(cmdLength, cmd);
1865 if (getLastError())
1866 {
1867 memset(response, 0, responseLength);
1868 return;
1869 }
1870 readResponse(responseLength, response);
1871 }
1872
1873private:
1874
1875 virtual void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) = 0;
1876 virtual void flushTransmission() = 0;
1877 virtual void readResponse(uint8_t length, uint8_t * response) = 0;
1878
1879 static const uint8_t defaultProtocolOptions =
1880 (1 << MOTORON_PROTOCOL_OPTION_I2C_GENERAL_CALL) |
1881 (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS) |
1882 (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
1883
1884 static const uint16_t defaultErrorMask =
1885 (1 << MOTORON_STATUS_FLAG_COMMAND_TIMEOUT) |
1886 (1 << MOTORON_STATUS_FLAG_RESET);
1887};
1888
1891{
1892public:
1897 MotoronI2C(uint8_t address = 16) : bus(&Wire), address(address) {}
1898
1906 void setBus(TwoWire * bus)
1907 {
1908 this->bus = bus;
1909 }
1910
1913 TwoWire * getBus()
1914 {
1915 return this->bus;
1916 }
1917
1920 void setAddress(uint8_t address)
1921 {
1922 this->address = address;
1923 }
1924
1926 uint8_t getAddress()
1927 {
1928 return address;
1929 }
1930
1931private:
1932 TwoWire * bus;
1933 uint8_t address;
1934
1935 void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) override
1936 {
1937 bus->beginTransmission(address);
1938 for (uint8_t i = 0; i < length; i++)
1939 {
1940 bus->write(cmd[i]);
1941 }
1942 if (sendCrc)
1943 {
1944 bus->write(calculateCrc(length, cmd));
1945 }
1946 lastError = bus->endTransmission();
1947 }
1948
1949 void flushTransmission() { }
1950
1951 void readResponse(uint8_t length, uint8_t * response) override
1952 {
1953 bool crcEnabled = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
1954 uint8_t byteCount = bus->requestFrom(address, (uint8_t)(length + crcEnabled));
1955 if (byteCount != length + crcEnabled)
1956 {
1957 memset(response, 0, length);
1958 lastError = 50;
1959 return;
1960 }
1961 lastError = 0;
1962 uint8_t * ptr = response;
1963 for (uint8_t i = 0; i < length; i++)
1964 {
1965 *ptr = bus->read();
1966 ptr++;
1967 }
1968 if (crcEnabled && bus->read() != calculateCrc(length, response))
1969 {
1970 lastError = 51;
1971 return;
1972 }
1973 }
1974};
1975
1988{
1989public:
1997 MotoronSerial(uint16_t deviceNumber = 0xFFFF) :
1998 port(nullptr), deviceNumber(deviceNumber), communicationOptions(0)
1999 {
2000 }
2001
2004 MotoronSerial(Stream & port, uint16_t deviceNumber = 0xFFFF) :
2005 port(&port), deviceNumber(deviceNumber), communicationOptions(0)
2006 {
2007 }
2008
2016 void setPort(Stream * port)
2017 {
2018 this->port = port;
2019 }
2020
2023 Stream * getPort()
2024 {
2025 return port;
2026 }
2027
2038 void setDeviceNumber(uint16_t deviceNumber)
2039 {
2040 this->deviceNumber = deviceNumber;
2041 }
2042
2048 {
2049 return deviceNumber;
2050 }
2051
2064 void setCommunicationOptions(uint8_t options)
2065 {
2066 communicationOptions = options;
2067 }
2068
2074 {
2075 return communicationOptions;
2076 }
2077
2085 {
2086 communicationOptions |= (1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2087 }
2088
2092 {
2093 communicationOptions &= ~(1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2094 }
2095
2103 {
2104 communicationOptions |= (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER);
2105 }
2106
2110 {
2111 communicationOptions &= ~(1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER);
2112 }
2113
2121 void multiDeviceErrorCheckStart(uint16_t startingDeviceNumber, uint16_t deviceCount)
2122 {
2123 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2124 {
2125 if (deviceCount > 0x3FFF) { lastError = 55; return; }
2126 uint8_t cmd[] = {
2127 MOTORON_CMD_MULTI_DEVICE_ERROR_CHECK,
2128 (uint8_t)(startingDeviceNumber & 0x7F),
2129 (uint8_t)(startingDeviceNumber >> 7 & 0x7F),
2130 (uint8_t)(deviceCount & 0x7F),
2131 (uint8_t)(deviceCount >> 7 & 0x7F),
2132 };
2133 sendCommand(sizeof(cmd), cmd);
2134 }
2135 else
2136 {
2137 if (deviceCount > 0x7F) { lastError = 55; return; }
2138 uint8_t cmd[] = {
2139 MOTORON_CMD_MULTI_DEVICE_ERROR_CHECK,
2140 (uint8_t)(startingDeviceNumber & 0x7F),
2141 (uint8_t)deviceCount,
2142 };
2143 sendCommand(sizeof(cmd), cmd);
2144 }
2145
2146 port->flush();
2147 }
2148
2164 uint16_t multiDeviceErrorCheck(uint16_t startingDeviceNumber, uint16_t deviceCount)
2165 {
2166 multiDeviceErrorCheckStart(startingDeviceNumber, deviceCount);
2167 uint16_t i;
2168 for (i = 0; i < deviceCount; i++)
2169 {
2170 uint8_t response;
2171 size_t byteCount = port->readBytes(&response, 1);
2172 if (byteCount < 1 || response != MOTORON_ERROR_CHECK_CONTINUE)
2173 {
2174 break;
2175 }
2176 }
2177 return i;
2178 }
2179
2186 void multiDeviceWrite(uint16_t startingDeviceNumber, uint16_t deviceCount,
2187 uint8_t bytesPerDevice, uint8_t commandByte, const uint8_t * data)
2188 {
2189 if (port == nullptr) { lastError = 52; return; }
2190 if (bytesPerDevice > 15) { lastError = 56; return; }
2191
2192 bool sendCrc = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_COMMANDS);
2193
2194 uint8_t header[10] = { 0 };
2195 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2196 {
2197 if (deviceCount > 0x3FFF) { lastError = 55; return; }
2198
2199 header[4] = startingDeviceNumber & 0x7F;
2200 header[5] = startingDeviceNumber >> 7 & 0x7F;
2201 header[6] = deviceCount & 0x7F;
2202 header[7] = deviceCount >> 7 & 0x7F;
2203 header[8] = bytesPerDevice;
2204 header[9] = commandByte & 0x7F;
2205
2206 if (deviceNumber == 0xFFFF)
2207 {
2208 header[3] = MOTORON_CMD_MULTI_DEVICE_WRITE;
2209 port->write(header + 3, 7);
2210 }
2211 else
2212 {
2213 header[0] = 0xAA;
2214 header[1] = deviceNumber & 0x7F;
2215 header[2] = deviceNumber >> 7 & 0x7F;
2216 header[3] = MOTORON_CMD_MULTI_DEVICE_WRITE & 0x7F;
2217 port->write(header, 10);
2218 }
2219 }
2220 else
2221 {
2222 if (deviceCount > 0x7F) { lastError = 55; return; }
2223
2224 header[6] = startingDeviceNumber & 0x7F;
2225 header[7] = deviceCount;
2226 header[8] = bytesPerDevice;
2227 header[9] = commandByte & 0x7F;
2228
2229 if (deviceNumber == 0xFFFF)
2230 {
2231 header[5] = MOTORON_CMD_MULTI_DEVICE_WRITE;
2232 port->write(header + 5, 5);
2233 }
2234 else
2235 {
2236 header[3] = 0xAA;
2237 header[4] = deviceNumber & 0x7F;
2238 header[5] = MOTORON_CMD_MULTI_DEVICE_WRITE & 0x7F;
2239 port->write(header + 3, 7);
2240 }
2241 }
2242
2243 uint8_t crc = 0;
2244 if (sendCrc) { crc = calculateCrc(sizeof(header), header); }
2245
2246 if (bytesPerDevice)
2247 {
2248 while (deviceCount)
2249 {
2250 port->write(data, bytesPerDevice);
2251 if (sendCrc) { crc = calculateCrc(bytesPerDevice, data, crc); }
2252 data += bytesPerDevice;
2253 deviceCount--;
2254 }
2255 }
2256
2257 if (sendCrc) { port->write(crc); }
2258 }
2259
2260private:
2261 Stream * port;
2262 uint16_t deviceNumber;
2263 uint8_t communicationOptions;
2264
2265 void sendCommandCore(uint8_t length, const uint8_t * cmd, bool sendCrc) override
2266 {
2267 if (port == nullptr) { lastError = 52; return; }
2268
2269 if (deviceNumber == 0xFFFF)
2270 {
2271 port->write(cmd, length);
2272 if (sendCrc)
2273 {
2274 port->write(calculateCrc(length, cmd));
2275 }
2276 }
2277 else
2278 {
2279 uint8_t header[4];
2280 if (communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_14BIT_DEVICE_NUMBER))
2281 {
2282 header[0] = 0xAA;
2283 header[1] = deviceNumber & 0x7F;
2284 header[2] = deviceNumber >> 7 & 0x7F;
2285 header[3] = cmd[0] & 0x7F;
2286 port->write(header, 4);
2287 }
2288 else
2289 {
2290 header[0] = 0;
2291 header[1] = 0xAA;
2292 header[2] = deviceNumber & 0x7F;
2293 header[3] = cmd[0] & 0x7F;
2294 port->write(header + 1, 3);
2295 }
2296 port->write(cmd + 1, length - 1);
2297 if (sendCrc)
2298 {
2299 uint8_t crc = calculateCrc(sizeof(header), header);
2300 crc = calculateCrc(length - 1, cmd + 1, crc);
2301 port->write(crc);
2302 }
2303 }
2304 lastError = 0;
2305 }
2306
2307 void flushTransmission()
2308 {
2309 if (port == nullptr) { return; }
2310 port->flush();
2311 }
2312
2313 void readResponse(uint8_t length, uint8_t * response) override
2314 {
2315 if (port == nullptr)
2316 {
2317 lastError = 52;
2318 memset(response, 0, length);
2319 return;
2320 }
2321
2322 bool response7Bit = communicationOptions & (1 << MOTORON_COMMUNICATION_OPTION_7BIT_RESPONSES);
2323 if (response7Bit && length > 7)
2324 {
2325 // In 7-bit response mode, the Motoron does not support response
2326 // payloads longer than 7 bytes. That seems short enough that it would be
2327 // good to signal it with a special error code.
2328 lastError = 53;
2329 memset(response, 0, length);
2330 return;
2331 }
2332
2333 port->flush();
2334
2335 size_t byteCount = port->readBytes(response, length);
2336 if (byteCount != length)
2337 {
2338 lastError = 50;
2339 memset(response, 0, length);
2340 return;
2341 }
2342
2343 uint8_t msbs = 0;
2344 if (response7Bit)
2345 {
2346 if (port->readBytes(&msbs, 1) != 1)
2347 {
2348 lastError = 54;
2349 return;
2350 }
2351 }
2352
2353 bool crcEnabled = protocolOptions & (1 << MOTORON_PROTOCOL_OPTION_CRC_FOR_RESPONSES);
2354 if (crcEnabled)
2355 {
2356 uint8_t crc = 0;
2357 if (port->readBytes(&crc, 1) != 1)
2358 {
2359 lastError = 49;
2360 return;
2361 }
2362
2363 uint8_t expected_crc = calculateCrc(length, response);
2364 if (response7Bit)
2365 {
2366 expected_crc = calculateCrc(1, &msbs, expected_crc);
2367 }
2368
2369 if (crc != expected_crc)
2370 {
2371 lastError = 51;
2372 return;
2373 }
2374 }
2375
2376 if (response7Bit)
2377 {
2378 for (uint8_t i = 0; i < length; i++)
2379 {
2380 if (msbs & 1) { response[i] |= 0x80; }
2381 msbs >>= 1;
2382 }
2383 }
2384
2385 lastError = 0;
2386 }
2387};
MotoronCurrentSenseType
Definition: Motoron.h:30
MotoronVinSenseType
Definition: Motoron.h:39
@ Motoron550
M*550 Motorons.
@ MotoronHp
High-power Motorons.
@ Motoron256
M*256 Motorons.
void setDirectionChangeDelay(uint8_t motor, uint8_t duration)
Definition: Motoron.h:1282
void setCommandTimeoutMilliseconds(uint16_t ms)
Definition: Motoron.h:1053
uint16_t getMaxAccelerationForward(uint8_t motor)
Definition: Motoron.h:796
uint16_t getCurrentLimit(uint8_t motor)
Definition: Motoron.h:901
int16_t getBufferedSpeed(uint8_t motor)
Definition: Motoron.h:773
bool getResetFlag()
Definition: Motoron.h:585
void setErrorResponse(uint8_t response)
Definition: Motoron.h:1075
void setBraking(uint8_t motor, uint16_t amount)
Definition: Motoron.h:1722
int16_t getTargetSpeed(uint8_t motor)
Definition: Motoron.h:739
uint16_t getMaxDecelerationForward(uint8_t motor)
Definition: Motoron.h:820
bool getMotorDrivingFlag()
Definition: Motoron.h:630
void clearUARTFaults(uint8_t flags)
Definition: Motoron.h:1120
void writeEepromAlternativeDeviceNumber(uint16_t number)
Definition: Motoron.h:312
uint16_t getTargetBrakeAmount(uint8_t motor)
Definition: Motoron.h:750
uint16_t getMaxAccelerationReverse(uint8_t motor)
Definition: Motoron.h:808
uint8_t getErrorResponse()
Definition: Motoron.h:706
void setErrorMask(uint16_t mask)
Definition: Motoron.h:1087
void writeEepromDeviceNumber(uint16_t number)
Definition: Motoron.h:295
void setMaxDeceleration(uint8_t motor, uint16_t decel)
Definition: Motoron.h:1211
void setVariable(uint8_t motor, uint8_t offset, uint16_t value)
Definition: Motoron.h:1034
uint8_t getJumperState()
Definition: Motoron.h:727
uint16_t getStartingSpeedReverse(uint8_t motor)
Definition: Motoron.h:864
void enableI2cGeneralCall()
Enables the I2C general call address. See setProtocolOptions().
Definition: Motoron.h:211
void coastNow()
Definition: Motoron.h:1353
void setAllBufferedSpeeds(int16_t speed1, int16_t speed2)
An overload of setAllBufferedSpeeds() for 2-channel Motorons.
Definition: Motoron.h:1654
uint16_t getMaxDecelerationReverse(uint8_t motor)
Definition: Motoron.h:832
uint16_t getVar16(uint8_t motor, uint8_t offset)
Definition: Motoron.h:454
MotoronCurrentSenseReading getCurrentSenseReading(uint8_t motor)
Definition: Motoron.h:917
void writeEeprom(uint8_t offset, uint8_t value)
Definition: Motoron.h:259
void enableCrcForCommands()
Enables CRC for commands. See setProtocolOptions().
Definition: Motoron.h:183
static uint8_t calculateCrc(uint8_t length, const uint8_t *buffer, uint8_t init=0)
Definition: Motoron.h:1781
uint16_t getErrorMask()
Definition: Motoron.h:718
void setCurrentSenseMinimumDivisor(uint8_t motor, uint16_t speed)
Definition: Motoron.h:1343
void disableCrc()
Disables CRC for commands and responses. See setProtocolOptions().
Definition: Motoron.h:175
void setAllSpeedsUsingBuffers()
Definition: Motoron.h:1684
uint16_t getVinVoltage()
Definition: Motoron.h:666
void setAllBufferedSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
Definition: Motoron.h:1639
uint8_t getCurrentSenseOffset(uint8_t motor)
Definition: Motoron.h:1003
uint16_t getCommandTimeoutMilliseconds()
Definition: Motoron.h:694
uint32_t getVinVoltageMv(uint16_t referenceMv, MotoronVinSenseType type=MotoronVinSenseType::Motoron256)
Definition: Motoron.h:681
void disableCrcForResponses()
Disables CRC for responses. See setProtocolOptions().
Definition: Motoron.h:204
void setBufferedSpeed(uint8_t motor, int16_t speed)
Definition: Motoron.h:1506
void setStartingSpeedForward(uint8_t motor, uint16_t speed)
Definition: Motoron.h:1225
void setMaxAccelerationForward(uint8_t motor, uint16_t accel)
Definition: Motoron.h:1155
void getVariables(uint8_t motor, uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: Motoron.h:426
bool getMotorFaultLatchedFlag()
Definition: Motoron.h:545
void setMaxAccelerationReverse(uint8_t motor, uint16_t accel)
Definition: Motoron.h:1167
void disableCrcForCommands()
Disables CRC for commands. See setProtocolOptions().
Definition: Motoron.h:190
void enableCrcForResponses()
Enables CRC for responses. See setProtocolOptions().
Definition: Motoron.h:197
uint16_t getStatusFlags()
Definition: Motoron.h:509
void clearMotorFaultUnconditional()
Definition: Motoron.h:1380
void writeEepromDisableAlternativeDeviceNumber()
Definition: Motoron.h:328
bool getCommandTimeoutLatchedFlag()
Definition: Motoron.h:536
uint8_t getPwmMode(uint8_t motor)
Definition: Motoron.h:784
void setProtocolOptionsLocally(uint8_t options)
Definition: Motoron.h:153
uint8_t readEepromDeviceNumber()
Definition: Motoron.h:242
uint8_t getDirectionChangeDelayForward(uint8_t motor)
Definition: Motoron.h:876
uint8_t lastError
Definition: Motoron.h:1846
uint8_t getDirectionChangeDelayReverse(uint8_t motor)
Definition: Motoron.h:888
void setAllBufferedSpeeds(int16_t speed1)
An overload of setAllBufferedSpeeds() for 1-channel Motorons.
Definition: Motoron.h:1667
void reset()
Definition: Motoron.h:406
void setDirectionChangeDelayReverse(uint8_t motor, uint8_t duration)
Definition: Motoron.h:1272
void setPwmMode(uint8_t motor, uint8_t mode)
Definition: Motoron.h:1143
bool getUARTErrorFlag()
Definition: Motoron.h:569
void setCurrentLimit(uint8_t motor, uint16_t limit)
Definition: Motoron.h:1299
void sendCommandAndReadResponse(uint8_t cmdLength, const uint8_t *cmd, uint8_t responseLength, uint8_t *response)
Definition: Motoron.h:1861
void disableI2cGeneralCall()
Disables the I2C general call address. See setProtocolOptions().
Definition: Motoron.h:218
void setAllSpeeds(int16_t speed1, int16_t speed2, int16_t speed3)
Definition: Motoron.h:1531
uint8_t protocolOptions
See setProtocolOptions.
Definition: Motoron.h:1849
bool getProtocolErrorFlag()
Definition: Motoron.h:518
void resetCommandTimeout()
Definition: Motoron.h:1771
void setLatchedStatusFlags(uint16_t flags)
Definition: Motoron.h:1433
uint8_t getProtocolOptionsLocally()
Definition: Motoron.h:161
void getFirmwareVersion(uint16_t *productId, uint16_t *firmwareVersion)
Definition: Motoron.h:86
bool getNoPowerFlag()
Definition: Motoron.h:603
void setAllSpeedsNow(int16_t speed1, int16_t speed2, int16_t speed3)
Definition: Motoron.h:1582
void setAllSpeeds(int16_t speed1)
An overload of setAllSpeeds() for single-channel Motorons.
Definition: Motoron.h:1559
void setMaxDecelerationReverse(uint8_t motor, uint16_t decel)
Definition: Motoron.h:1202
void setStartingSpeed(uint8_t motor, uint16_t speed)
Definition: Motoron.h:1246
void clearResetFlag()
Definition: Motoron.h:1419
void clearLatchedStatusFlags(uint16_t flags)
Definition: Motoron.h:1394
bool getCrcErrorFlag()
Definition: Motoron.h:527
void setMaxDecelerationForward(uint8_t motor, uint16_t decel)
Definition: Motoron.h:1190
static constexpr uint16_t currentSenseUnitsMilliamps(MotoronCurrentSenseType type, uint16_t referenceMv)
Definition: Motoron.h:1837
MotoronCurrentSenseReading getCurrentSenseProcessedAndSpeed(uint8_t motor)
Definition: Motoron.h:950
bool getMotorOutputEnabledFlag()
Definition: Motoron.h:621
uint16_t getCurrentSenseRaw(uint8_t motor)
Definition: Motoron.h:968
void setCurrentSenseOffset(uint8_t motor, uint8_t offset)
Definition: Motoron.h:1323
void setMaxAcceleration(uint8_t motor, uint16_t accel)
Definition: Motoron.h:1176
bool getErrorActiveFlag()
Definition: Motoron.h:612
void sendCommand(uint8_t length, const uint8_t *cmd)
Definition: Motoron.h:1853
uint8_t getLastError()
Definition: Motoron.h:71
uint8_t getUARTFaults()
Definition: Motoron.h:655
void setStartingSpeedReverse(uint8_t motor, uint16_t speed)
Definition: Motoron.h:1237
uint16_t getStartingSpeedForward(uint8_t motor)
Definition: Motoron.h:853
void writeEepromBaudRate(uint32_t baud)
Definition: Motoron.h:360
void setAllSpeeds(int16_t speed1, int16_t speed2)
An overload of setAllSpeeds() for 2-channel Motorons.
Definition: Motoron.h:1546
void setAllSpeedsNowUsingBuffers()
Definition: Motoron.h:1698
bool getNoPowerLatchedFlag()
Definition: Motoron.h:554
uint16_t getCurrentSenseMinimumDivisor(uint8_t motor)
Definition: Motoron.h:1017
void disableCommandTimeout()
Definition: Motoron.h:1107
void setDirectionChangeDelayForward(uint8_t motor, uint8_t duration)
Definition: Motoron.h:1260
uint8_t getVar8(uint8_t motor, uint8_t offset)
Definition: Motoron.h:442
void writeEeprom16(uint8_t offset, uint16_t value)
Definition: Motoron.h:281
void setAllSpeedsNow(int16_t speed1)
An overload of setAllSpeedsNow() for single-channel Motorons.
Definition: Motoron.h:1610
void setBrakingNow(uint8_t motor, uint16_t amount)
Definition: Motoron.h:1750
void enableCrc()
Enables CRC for commands and responses. See setProtocolOptions().
Definition: Motoron.h:167
uint16_t getCurrentSenseProcessed(uint8_t motor)
Definition: Motoron.h:990
void readEeprom(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: Motoron.h:228
void setSpeed(uint8_t motor, int16_t speed)
Definition: Motoron.h:1460
void writeEepromResponseDelay(uint8_t delay)
Definition: Motoron.h:376
bool getMotorFaultingFlag()
Definition: Motoron.h:594
static uint16_t calculateCurrentLimit(uint32_t milliamps, MotoronCurrentSenseType type, uint16_t referenceMv, uint16_t offset)
Definition: Motoron.h:1815
void setSpeedNow(uint8_t motor, int16_t speed)
Definition: Motoron.h:1481
void reinitialize()
Definition: Motoron.h:388
void setAllSpeedsNow(int16_t speed1, int16_t speed2)
An overload of setAllSpeedsNow() for 2-channel Motorons.
Definition: Motoron.h:1597
void setProtocolOptions(uint8_t options)
Definition: Motoron.h:134
void clearMotorFault(uint8_t flags=0)
Definition: Motoron.h:1369
MotoronCurrentSenseReading getCurrentSenseRawAndSpeed(uint8_t motor)
Definition: Motoron.h:934
int16_t getCurrentSpeed(uint8_t motor)
Definition: Motoron.h:762
void writeEepromCommunicationOptions(uint8_t options)
Definition: Motoron.h:346
Represents an I2C connection to a Motoron Motor Controller.
Definition: Motoron.h:1891
void setBus(TwoWire *bus)
Definition: Motoron.h:1906
void setAddress(uint8_t address)
Definition: Motoron.h:1920
TwoWire * getBus()
Definition: Motoron.h:1913
MotoronI2C(uint8_t address=16)
Definition: Motoron.h:1897
uint8_t getAddress()
Returns the 7-bit I2C address that this object is configured to use.
Definition: Motoron.h:1926
void setCommunicationOptions(uint8_t options)
Definition: Motoron.h:2064
MotoronSerial(Stream &port, uint16_t deviceNumber=0xFFFF)
Definition: Motoron.h:2004
void use7BitDeviceNumber()
Definition: Motoron.h:2109
void expect8BitResponses()
Definition: Motoron.h:2091
uint16_t multiDeviceErrorCheck(uint16_t startingDeviceNumber, uint16_t deviceCount)
Definition: Motoron.h:2164
void multiDeviceWrite(uint16_t startingDeviceNumber, uint16_t deviceCount, uint8_t bytesPerDevice, uint8_t commandByte, const uint8_t *data)
Definition: Motoron.h:2186
void multiDeviceErrorCheckStart(uint16_t startingDeviceNumber, uint16_t deviceCount)
Definition: Motoron.h:2121
uint8_t getCommunicationOptionsLocally()
Definition: Motoron.h:2073
MotoronSerial(uint16_t deviceNumber=0xFFFF)
Definition: Motoron.h:1997
uint16_t getDeviceNumber()
Definition: Motoron.h:2047
void use14BitDeviceNumber()
Definition: Motoron.h:2102
void setPort(Stream *port)
Definition: Motoron.h:2016
void setDeviceNumber(uint16_t deviceNumber)
Definition: Motoron.h:2038
Stream * getPort()
Definition: Motoron.h:2023
void expect7BitResponses()
Definition: Motoron.h:2084