Jrk G2 library for Arduino
JrkG2.h
Go to the documentation of this file.
1 // Copyright (C) Pololu Corporation. See LICENSE.txt for details.
2 
10 
11 #pragma once
12 
13 #include <Arduino.h>
14 #include <Stream.h>
15 #include <Wire.h>
16 
19 const uint16_t JrkG2InputNull = 0xFFFF;
20 
23 const uint8_t JrkG2CommReadError = 50;
24 
29 enum class JrkG2Error
30 {
31  AwaitingCommand = 0,
32  NoPower = 1,
33  MotorDriver = 2,
34  InputInvalid = 3,
35  InputDisconnect = 4,
36  FeedbackDisconnect = 5,
37  SoftOvercurrent = 6,
38  SerialSignal = 7,
39  SerialOverrun = 8,
40  SerialBufferFull = 9,
41  SerialCrc = 10,
42  SerialProtocol = 11,
43  SerialTimeout = 12,
44  HardOvercurrent = 13,
45 };
46 
50 enum class JrkG2Command
51 {
52  SetTarget = 0xC0,
53  SetTargetLowResRev = 0xE0,
54  SetTargetLowResFwd = 0xE1,
55  ForceDutyCycleTarget = 0xF2,
56  ForceDutyCycle = 0xF4,
57  MotorOff = 0xFF,
58  GetVariable8 = 0x80,
59  GetVariable16 = 0xA0,
60  GetEEPROMSettings = 0xE3,
61  GetVariables = 0xE5,
62  SetRAMSettings = 0xE6,
63  GetRAMSettings = 0xEA,
64  GetCurrentChoppingOccurrenceCount = 0xEC,
65 };
66 
73 enum class JrkG2ForceMode
74 {
75  None = 0,
76  DutyCycleTarget = 1,
77  DutyCycle = 2,
78 };
79 
84 enum class JrkG2Reset
85 {
86  PowerUp = 0,
87  Brownout = 1,
88  ResetLine = 2,
89  Watchdog = 4,
90  Software = 8,
91  StackOverflow = 16,
92  StackUnderflow = 32,
93 };
94 
96 enum class JrkG2Pin
97 {
98  SCL = 0,
99  SDA = 1,
100  TX = 2,
101  RX = 3,
102  RC = 4,
103  AUX = 5,
104  FBA = 6,
105  FBT = 7,
106 };
107 
113 {
114  ResetIntegral = 0,
115  CoastWhenOff = 1,
116 };
117 
124 {
125 public:
128  uint8_t getLastError()
129  {
130  return _lastError;
131  }
132 
135 
152  void setTarget(uint16_t target)
153  {
154  // lower 5 bits in command byte
155  // upper 7 bits in data byte
156  if (target > 4095) { target = 4095; }
157  commandW7((uint8_t)JrkG2Command::SetTarget | (target & 0x1F), target >> 5);
158  }
159 
182  void setTargetLowResRev(uint8_t target)
183  {
184  if (target > 127) { target = 127; }
185  commandW7(JrkG2Command::SetTargetLowResRev, target);
186  }
187 
209  void setTargetLowResFwd(uint8_t target)
210  {
211  if (target > 127) { target = 127; }
212  commandW7(JrkG2Command::SetTargetLowResFwd, target);
213  }
214 
238  void forceDutyCycleTarget(int16_t dutyCycle)
239  {
240  if (dutyCycle > 600) { dutyCycle = 600; }
241  if (dutyCycle < -600) { dutyCycle = -600; }
242  commandWs14(JrkG2Command::ForceDutyCycleTarget, dutyCycle);
243  }
244 
270  void forceDutyCycle(int16_t dutyCycle)
271  {
272  if (dutyCycle > 600) { dutyCycle = 600; }
273  if (dutyCycle < -600) { dutyCycle = -600; }
274  commandWs14(JrkG2Command::ForceDutyCycle, dutyCycle);
275  }
276 
289  void stopMotor()
290  {
291  commandQuick(JrkG2Command::MotorOff);
292  }
293 
295 
298 
312  uint16_t getInput()
313  {
314  return getVar16SingleByte(VarOffset::Input);
315  }
316 
324  uint16_t getTarget()
325  {
326  return getVar16SingleByte(VarOffset::Target);
327  }
328 
341  uint16_t getFeedback()
342  {
343  return getVar16SingleByte(VarOffset::Feedback);
344  }
345 
352  uint16_t getScaledFeedback()
353  {
354  return getVar16SingleByte(VarOffset::ScaledFeedback);
355  }
356 
363  int16_t getIntegral()
364  {
365  return getVar16SingleByte(VarOffset::Integral);
366  }
367 
385  {
386  return getVar16SingleByte(VarOffset::DutyCycleTarget);
387  }
388 
400  int16_t getDutyCycle()
401  {
402  return getVar16SingleByte(VarOffset::DutyCycle);
403  }
404 
411  {
412  return getVar8SingleByte(VarOffset::CurrentLowRes);
413  }
414 
421  {
422  return getVar8SingleByte(VarOffset::PIDPeriodExceeded);
423  }
424 
428  uint16_t getPIDPeriodCount()
429  {
430  return getVar16SingleByte(VarOffset::PIDPeriodCount);
431  }
432 
455  {
456  return getVar16SingleByte(VarOffset::ErrorFlagsHalting);
457  }
458 
484  {
485  return getVar16SingleByte(VarOffset::ErrorFlagsOccurred);
486  }
487 
501  {
502  return (JrkG2ForceMode)(getVar8SingleByte(VarOffset::FlagByte1) & 0x03);
503  }
504 
511  uint16_t getVinVoltage()
512  {
513  return getVar16SingleByte(VarOffset::VinVoltage);
514  }
515 
518  uint16_t getCurrent()
519  {
520  return getVar16SingleByte(VarOffset::Current);
521  }
522 
533  {
534  return (JrkG2Reset)getVar8(VarOffset::DeviceReset);
535  }
536 
544  uint32_t getUpTime()
545  {
546  return getVar32(VarOffset::UpTime);
547  }
548 
562  uint16_t getRCPulseWidth()
563  {
564  return getVar16(VarOffset::RCPulseWidth);
565  }
566 
581  uint16_t getFBTReading()
582  {
583  return getVar16(VarOffset::FBTReading);
584  }
585 
603  {
604  switch (pin)
605  {
606  case JrkG2Pin::SDA:
607  return getVar16(VarOffset::AnalogReadingSDA);
608  case JrkG2Pin::FBA:
609  return getVar16(VarOffset::AnalogReadingFBA);
610  default:
611  return JrkG2InputNull;
612  }
613  }
614 
629  {
630  uint8_t readings = getVar8(VarOffset::DigitalReadings);
631  return (readings >> (uint8_t)pin) & 1;
632  }
633 
641  uint16_t getRawCurrent()
642  {
643  return getVar16(VarOffset::RawCurrent);
644  }
645 
654  {
655  return getVar16(VarOffset::EncodedHardCurrentLimit);
656  }
657 
665  {
666  return getVar16(VarOffset::LastDutyCycle);
667  }
668 
674  {
675  return getVar8(VarOffset::CurrentChoppingConsecutiveCount);
676  }
677 
689  {
690  return commandR8(JrkG2Command::GetCurrentChoppingOccurrenceCount);
691  }
693 
696 
713  void setResetIntegral(bool reset)
714  {
715  uint8_t tmp = getRAMSetting8(SettingOffset::OptionsByte3);
716  if (getLastError()) { return; }
717  if (reset)
718  {
719  tmp |= 1 << (uint8_t)JrkG2OptionsByte3::ResetIntegral;
720  }
721  else
722  {
723  tmp &= ~(1 << (uint8_t)JrkG2OptionsByte3::ResetIntegral);
724  }
725  setRAMSetting8(SettingOffset::OptionsByte3, tmp);
726  }
727 
732  {
733  return getRAMSetting8(SettingOffset::OptionsByte3) >>
734  (uint8_t)JrkG2OptionsByte3::ResetIntegral & 1;
735  }
736 
749  void setCoastWhenOff(bool coast)
750  {
751  uint8_t tmp = getRAMSetting8(SettingOffset::OptionsByte3);
752  if (getLastError()) { return; }
753  if (coast)
754  {
755  tmp |= 1 << (uint8_t)JrkG2OptionsByte3::CoastWhenOff;
756  }
757  else
758  {
759  tmp &= ~(1 << (uint8_t)JrkG2OptionsByte3::CoastWhenOff);
760  }
761  setRAMSetting8(SettingOffset::OptionsByte3, tmp);
762  }
763 
768  {
769  return getRAMSetting8(SettingOffset::OptionsByte3) >>
770  (uint8_t)JrkG2OptionsByte3::CoastWhenOff & 1;
771  }
772 
795  void setProportionalCoefficient(uint16_t multiplier, uint8_t exponent)
796  {
797  setPIDCoefficient(SettingOffset::ProportionalMultiplier, multiplier, exponent);
798  }
799 
805  {
806  return getRAMSetting16(SettingOffset::ProportionalMultiplier);
807  }
808 
814  {
815  return getRAMSetting8(SettingOffset::ProportionalExponent);
816  }
817 
834  void setIntegralCoefficient(uint16_t multiplier, uint8_t exponent)
835  {
836  setPIDCoefficient(SettingOffset::IntegralMultiplier, multiplier, exponent);
837  }
838 
844  {
845  return getRAMSetting16(SettingOffset::IntegralMultiplier);
846  }
847 
853  {
854  return getRAMSetting8(SettingOffset::IntegralExponent);
855  }
856 
873  void setDerivativeCoefficient(uint16_t multiplier, uint8_t exponent)
874  {
875  setPIDCoefficient(SettingOffset::DerivativeMultiplier, multiplier, exponent);
876  }
877 
883  {
884  return getRAMSetting16(SettingOffset::DerivativeMultiplier);
885  }
886 
892  {
893  return getRAMSetting8(SettingOffset::DerivativeExponent);
894  }
895 
908  void setPIDPeriod(uint16_t period)
909  {
910  setRAMSetting16(SettingOffset::PIDPeriod, period);
911  }
912 
916  uint16_t getPIDPeriod()
917  {
918  return getRAMSetting16(SettingOffset::PIDPeriod);
919  }
920 
932  void setIntegralLimit(uint16_t limit)
933  {
934  setRAMSetting16(SettingOffset::IntegralLimit, limit);
935  }
936 
940  uint16_t getIntegralLimit()
941  {
942  return getRAMSetting16(SettingOffset::IntegralLimit);
943  }
944 
954  {
955  setRAMSetting16(SettingOffset::MaxDutyCycleWhileFeedbackOutOfRange, duty);
956  }
957 
963  {
964  return getRAMSetting16(SettingOffset::MaxDutyCycleWhileFeedbackOutOfRange);
965  }
966 
976  void setMaxAccelerationForward(uint16_t accel)
977  {
978  setRAMSetting16(SettingOffset::MaxAccelerationForward, accel);
979  }
980 
986  {
987  return getRAMSetting16(SettingOffset::MaxAccelerationForward);
988  }
989 
999  void setMaxAccelerationReverse(uint16_t accel)
1000  {
1001  setRAMSetting16(SettingOffset::MaxAccelerationReverse, accel);
1002  }
1003 
1009  {
1010  return getRAMSetting16(SettingOffset::MaxAccelerationReverse);
1011  }
1012 
1022  void setMaxAcceleration(uint16_t accel)
1023  {
1024  setRAMSetting16x2(SettingOffset::MaxAccelerationForward, accel, accel);
1025  }
1026 
1036  void setMaxDecelerationForward(uint16_t decel)
1037  {
1038  setRAMSetting16(SettingOffset::MaxDecelerationForward, decel);
1039  }
1040 
1046  {
1047  return getRAMSetting16(SettingOffset::MaxDecelerationForward);
1048  }
1049 
1059  void setMaxDecelerationReverse(uint16_t decel)
1060  {
1061  setRAMSetting16(SettingOffset::MaxDecelerationReverse, decel);
1062  }
1063 
1069  {
1070  return getRAMSetting16(SettingOffset::MaxDecelerationReverse);
1071  }
1072 
1082  void setMaxDeceleration(uint16_t decel)
1083  {
1084  setRAMSetting16x2(SettingOffset::MaxDecelerationForward, decel, decel);
1085  }
1086 
1095  void setMaxDutyCycleForward(uint16_t duty)
1096  {
1097  setRAMSetting16(SettingOffset::MaxDutyCycleForward, duty);
1098  }
1099 
1105  {
1106  return getRAMSetting16(SettingOffset::MaxDutyCycleForward);
1107  }
1108 
1117  void setMaxDutyCycleReverse(uint16_t duty)
1118  {
1119  setRAMSetting16(SettingOffset::MaxDutyCycleReverse, duty);
1120  }
1121 
1127  {
1128  return getRAMSetting16(SettingOffset::MaxDutyCycleReverse);
1129  }
1130 
1139  void setMaxDutyCycle(uint16_t duty)
1140  {
1141  setRAMSetting16x2(SettingOffset::MaxDutyCycleForward, duty, duty);
1142  }
1143 
1156  void setEncodedHardCurrentLimitForward(uint16_t encoded_limit)
1157  {
1158  setRAMSetting16(SettingOffset::EncodedHardCurrentLimitForward,
1159  encoded_limit);
1160  }
1161 
1170  {
1171  return getRAMSetting16(SettingOffset::EncodedHardCurrentLimitForward);
1172  }
1173 
1186  void setEncodedHardCurrentLimitReverse(uint16_t encoded_limit)
1187  {
1188  setRAMSetting16(SettingOffset::EncodedHardCurrentLimitReverse, encoded_limit);
1189  }
1190 
1199  {
1200  return getRAMSetting16(SettingOffset::EncodedHardCurrentLimitReverse);
1201  }
1202 
1216  void setEncodedHardCurrentLimit(uint16_t encoded_limit)
1217  {
1218  setRAMSetting16x2(SettingOffset::EncodedHardCurrentLimitForward,
1219  encoded_limit, encoded_limit);
1220  }
1221 
1230  void setBrakeDurationForward(uint8_t duration)
1231  {
1232  setRAMSetting8(SettingOffset::BrakeDurationForward, duration);
1233  }
1234 
1240  {
1241  return getRAMSetting8(SettingOffset::BrakeDurationForward);
1242  }
1243 
1252  void setBrakeDurationReverse(uint8_t duration)
1253  {
1254  setRAMSetting8(SettingOffset::BrakeDurationReverse, duration);
1255  }
1256 
1262  {
1263  return getRAMSetting8(SettingOffset::BrakeDurationReverse);
1264  }
1265 
1274  void setBrakeDuration(uint8_t duration)
1275  {
1276  setRAMSetting8x2(SettingOffset::BrakeDurationForward, duration, duration);
1277  }
1278 
1287  void setSoftCurrentLimitForward(uint16_t current)
1288  {
1289  setRAMSetting16(SettingOffset::SoftCurrentLimitForward, current);
1290  }
1291 
1297  {
1298  return getRAMSetting16(SettingOffset::SoftCurrentLimitForward);
1299  }
1300 
1309  void setSoftCurrentLimitReverse(uint16_t current)
1310  {
1311  setRAMSetting16(SettingOffset::SoftCurrentLimitReverse, current);
1312  }
1313 
1319  {
1320  return getRAMSetting16(SettingOffset::SoftCurrentLimitReverse);
1321  }
1322 
1332  void setSoftCurrentLimit(uint16_t current)
1333  {
1334  setRAMSetting16x2(SettingOffset::SoftCurrentLimitForward, current, current);
1335  }
1336 
1337  // TODO: add functions to get and set the soft current regulation level
1338 
1340 
1343 
1357  void getEEPROMSettings(uint8_t offset, uint8_t length, uint8_t * buffer)
1358  {
1359  segmentRead(JrkG2Command::GetEEPROMSettings, offset, length, buffer);
1360  }
1361 
1379  void getRAMSettings(uint8_t offset, uint8_t length, uint8_t * buffer)
1380  {
1381  segmentRead(JrkG2Command::GetRAMSettings, offset, length, buffer);
1382  }
1383 
1404  void setRAMSettings(uint8_t offset, uint8_t length, uint8_t * buffer)
1405  {
1406  segmentWrite(JrkG2Command::SetRAMSettings, offset, length, buffer);
1407  }
1408 
1427  void getVariables(uint8_t offset, uint8_t length, uint8_t * buffer)
1428  {
1429  segmentRead(JrkG2Command::GetVariables, offset, length, buffer);
1430  }
1431 
1433 
1434 protected:
1437  uint8_t _lastError = 0;
1438 
1439 private:
1440  enum VarOffset
1441  {
1442  Input = 0x00, // uint16_t
1443  Target = 0x02, // uint16_t
1444  Feedback = 0x04, // uint16_t
1445  ScaledFeedback = 0x06, // uint16_t
1446  Integral = 0x08, // int16_t
1447  DutyCycleTarget = 0x0A, // int16_t
1448  DutyCycle = 0x0C, // int16_t
1449  CurrentLowRes = 0x0E, // uint8_t
1450  PIDPeriodExceeded = 0x0F, // uint8_t
1451  PIDPeriodCount = 0x10, // uint16_t
1452  ErrorFlagsHalting = 0x12, // uint16_t
1453  ErrorFlagsOccurred = 0x14, // uint16_t
1454 
1455  FlagByte1 = 0x16, // uint8_t
1456  VinVoltage = 0x17, // uint16_t
1457  Current = 0x19, // uint16_t
1458 
1459  // variables above can be read with single-byte commands (GetVariable)
1460  // variables below must be read with segment read (GetVariables)
1461 
1462  DeviceReset = 0x1F, // uint8_t
1463  UpTime = 0x20, // uint32_t
1464  RCPulseWidth = 0x24, // uint16_t
1465  FBTReading = 0x26, // uint16_t
1466  AnalogReadingSDA = 0x28, // uint16_t
1467  AnalogReadingFBA = 0x2A, // uint16_t
1468  DigitalReadings = 0x2C, // uint8_t
1469  RawCurrent = 0x2D, // uint16_t
1470  EncodedHardCurrentLimit = 0x2F, // uint16_t
1471  LastDutyCycle = 0x31, // int16_t
1472  CurrentChoppingConsecutiveCount = 0x33, // uint8_t
1473  CurrentChoppingOccurrenceCount = 0x34, // uint8_t; read with dedicated command
1474  };
1475 
1476  enum SettingOffset
1477  {
1478  OptionsByte1 = 0x01, // uint8_t
1479  OptionsByte2 = 0x02, // uint8_t
1480  InputMode = 0x03, // uint8_t
1481  InputErrorMinimum = 0x04, // uint16_t,
1482  InputErrorMaximum = 0x06, // uint16_t,
1483  InputMinimum = 0x08, // uint16_t,
1484  InputMaximum = 0x0A, // uint16_t,
1485  InputNeutralMinimum = 0x0C, // uint16_t,
1486  InputNeutralMaximum = 0x0E, // uint16_t,
1487  OutputMinimum = 0x10, // uint16_t,
1488  OutputNeutral = 0x12, // uint16_t,
1489  OutputMaximum = 0x14, // uint16_t,
1490  InputScalingDegree = 0x16, // uint8_t,
1491  InputAnalogSamplesExponent = 0x17, // uint8_t,
1492  FeedbackMode = 0x18, // uint8_t,
1493  FeedbackErrorMinimum = 0x19, // uint16_t,
1494  FeedbackErrorMaximum = 0x1B, // uint16_t,
1495  FeedbackMinimum = 0x1D, // uint16_t,
1496  FeedbackMaximum = 0x1F, // uint16_t,
1497  FeedbackDeadZone = 0x21, // uint8_t,
1498  FeedbackAnalogSamplesExponent = 0x22, // uint8_t,
1499  SerialMode = 0x23, // uint8_t,
1500  SerialBaudRateGenerator = 0x24, // uint16_t,
1501  SerialTimeout = 0x26, // uint16_t,
1502  SerialDeviceNumber = 0x28, // uint16_t,
1503  ErrorEnable = 0x2A, // uint16_t
1504  ErrorLatch = 0x2C, // uint16_t
1505  ErrorHard = 0x2E, // uint16_t
1506  VinCalibration = 0x30, // uint16_t
1507  PwmFrequency = 0x32, // uint8_t
1508  CurrentSamplesExponent = 0x33, // uint8_t
1509  HardOvercurrentThreshold = 0x34, // uint8_t
1510  CurrentOffsetCalibration = 0x35, // uint16_t
1511  CurrentScaleCalibration = 0x37, // uint16_t
1512  FBTMethod = 0x39, // uint8_t
1513  FBTOptions = 0x3A, // uint8_t
1514  FBTTimingTimeout = 0x3B, // uint16_t
1515  FBTSamples = 0x3D, // uint8_t
1516  FBTDividerExponent = 0x3E, // uint8_t
1517  IntegralDividerExponent = 0x3F, // uint8_t
1518  SoftCurrentRegulationLevelForward = 0x40, // uint16_t
1519  SoftCurrentRegulationLevelReverse = 0x42, // uint16_t
1520  OptionsByte3 = 0x50, // uint8_t
1521  ProportionalMultiplier = 0x51, // uint16_t
1522  ProportionalExponent = 0x53, // uint8_t
1523  IntegralMultiplier = 0x54, // uint16_t
1524  IntegralExponent = 0x56, // uint8_t
1525  DerivativeMultiplier = 0x57, // uint16_t
1526  DerivativeExponent = 0x59, // uint8_t
1527  PIDPeriod = 0x5A, // uint16_t
1528  IntegralLimit = 0x5C, // uint16_t
1529  MaxDutyCycleWhileFeedbackOutOfRange = 0x5E, // uint16_t
1530  MaxAccelerationForward = 0x60, // uint16_t
1531  MaxAccelerationReverse = 0x62, // uint16_t
1532  MaxDecelerationForward = 0x64, // uint16_t
1533  MaxDecelerationReverse = 0x66, // uint16_t
1534  MaxDutyCycleForward = 0x68, // uint16_t
1535  MaxDutyCycleReverse = 0x6A, // uint16_t
1536  EncodedHardCurrentLimitForward = 0x6C, // uint16_t
1537  EncodedHardCurrentLimitReverse = 0x6E, // uint16_t
1538  BrakeDurationForward = 0x70, // uint8_t
1539  BrakeDurationReverse = 0x71, // uint8_t
1540  SoftCurrentLimitForward = 0x72, // uint16_t
1541  SoftCurrentLimitReverse = 0x74, // uint16_t
1542  };
1543 
1544  uint8_t getVar8SingleByte(uint8_t offset)
1545  {
1546  return commandR8((uint8_t)JrkG2Command::GetVariable8 | (offset + 1));
1547  }
1548 
1549  uint16_t getVar16SingleByte(uint8_t offset)
1550  {
1551  return commandR16((uint8_t)JrkG2Command::GetVariable16 | (offset + 1));
1552  }
1553 
1554  uint8_t getVar8(uint8_t offset)
1555  {
1556  uint8_t result;
1557  segmentRead(JrkG2Command::GetVariables, offset, 1, &result);
1558  return result;
1559  }
1560 
1561  uint16_t getVar16(uint8_t offset)
1562  {
1563  uint8_t buffer[2];
1564  segmentRead(JrkG2Command::GetVariables, offset, 2, buffer);
1565  return ((uint16_t)buffer[0] << 0) | ((uint16_t)buffer[1] << 8);
1566  }
1567 
1568  uint32_t getVar32(uint8_t offset)
1569  {
1570  uint8_t buffer[4];
1571  segmentRead(JrkG2Command::GetVariables, offset, 4, buffer);
1572  return ((uint32_t)buffer[0] << 0) |
1573  ((uint32_t)buffer[1] << 8) |
1574  ((uint32_t)buffer[2] << 16) |
1575  ((uint32_t)buffer[3] << 24);
1576  }
1577 
1578  void setRAMSetting8(uint8_t offset, uint8_t val)
1579  {
1580  segmentWrite(JrkG2Command::SetRAMSettings, offset, 1, &val);
1581  }
1582 
1583  void setRAMSetting16(uint8_t offset, uint16_t val)
1584  {
1585  uint8_t buffer[2] = {(uint8_t)val, (uint8_t)(val >> 8)};
1586  segmentWrite(JrkG2Command::SetRAMSettings, offset, 2, buffer);
1587  }
1588 
1589  void setRAMSetting8x2(uint8_t offset, uint8_t val1, uint8_t val2)
1590  {
1591  uint8_t buffer[2] = {val1, val2};
1592  segmentWrite(JrkG2Command::SetRAMSettings, offset, 2, buffer);
1593  }
1594 
1595  void setRAMSetting16x2(uint8_t offset, uint16_t val1, uint16_t val2)
1596  {
1597  uint8_t buffer[4] = {(uint8_t)val1, (uint8_t)(val1 >> 8),
1598  (uint8_t)val2, (uint8_t)(val2 >> 8)};
1599  segmentWrite(JrkG2Command::SetRAMSettings, offset, 4, buffer);
1600  }
1601 
1602  // set multiplier and exponent together in one segment write
1603  // (slightly faster than separate calls to getRAMSetting16() and getRAMSetting8())
1604  void setPIDCoefficient(uint8_t offset, uint16_t multiplier, uint8_t exponent)
1605  {
1606  uint8_t buffer[3] = {(uint8_t)multiplier, (uint8_t)(multiplier >> 8), exponent};
1607  segmentWrite(JrkG2Command::SetRAMSettings, offset, 3, buffer);
1608  }
1609 
1610  uint8_t getRAMSetting8(uint8_t offset)
1611  {
1612  uint8_t result;
1613  segmentRead(JrkG2Command::GetRAMSettings, offset, 1, &result);
1614  return result;
1615  }
1616 
1617  uint16_t getRAMSetting16(uint8_t offset)
1618  {
1619  uint8_t buffer[2];
1620  segmentRead(JrkG2Command::GetRAMSettings, offset, 2, buffer);
1621  return ((uint16_t)buffer[0] << 0) | ((uint16_t)buffer[1] << 8);
1622  }
1623 
1624  // Convenience functions that take care of casting a JrkG2Command to a uint8_t.
1625 
1626  void commandQuick(JrkG2Command cmd)
1627  {
1628  commandQuick((uint8_t)cmd);
1629  }
1630 
1631  void commandW7(JrkG2Command cmd, uint8_t val)
1632  {
1633  commandW7((uint8_t)cmd, val);
1634  }
1635 
1636  void commandWs14(JrkG2Command cmd, int16_t val)
1637  {
1638  commandWs14((uint8_t)cmd, val);
1639  }
1640 
1641  uint8_t commandR8(JrkG2Command cmd)
1642  {
1643  return commandR8((uint8_t)cmd);
1644  }
1645 
1646  uint16_t commandR16(JrkG2Command cmd)
1647  {
1648  return commandR16((uint8_t)cmd);
1649  }
1650 
1651  void segmentRead(JrkG2Command cmd, uint8_t offset,
1652  uint8_t length, uint8_t * buffer)
1653  {
1654  segmentRead((uint8_t)cmd, offset, length, buffer);
1655  }
1656 
1657  void segmentWrite(JrkG2Command cmd, uint8_t offset,
1658  uint8_t length, uint8_t * buffer)
1659  {
1660  segmentWrite((uint8_t)cmd, offset, length, buffer);
1661  }
1662 
1663  // Low-level functions implemented by the serial/I2C subclasses.
1664 
1665  virtual void commandQuick(uint8_t cmd) = 0;
1666  virtual void commandW7(uint8_t cmd, uint8_t val) = 0;
1667  virtual void commandWs14(uint8_t cmd, int16_t val) = 0;
1668  virtual uint8_t commandR8(uint8_t cmd) = 0;
1669  virtual uint16_t commandR16(uint8_t cmd) = 0;
1670  virtual void segmentRead(uint8_t cmd, uint8_t offset,
1671  uint8_t length, uint8_t * buffer) = 0;
1672  virtual void segmentWrite(uint8_t cmd, uint8_t offset,
1673  uint8_t length, uint8_t * buffer) = 0;
1674 };
1675 
1679 class JrkG2Serial : public JrkG2Base
1680 {
1681 public:
1711  JrkG2Serial(Stream & stream, uint8_t deviceNumber = 255) :
1712  _stream(&stream),
1713  _deviceNumber(deviceNumber)
1714  {
1715  }
1716 
1718  uint8_t getDeviceNumber() { return _deviceNumber; }
1719 
1720 private:
1721  Stream * const _stream;
1722  const uint8_t _deviceNumber;
1723 
1724  void commandQuick(uint8_t cmd) { sendCommandHeader(cmd); }
1725  void commandW7(uint8_t cmd, uint8_t val);
1726  void commandWs14(uint8_t cmd, int16_t val);
1727  uint8_t commandR8(uint8_t cmd);
1728  uint16_t commandR16(uint8_t cmd);
1729  void segmentRead(uint8_t cmd, uint8_t offset,
1730  uint8_t length, uint8_t * buffer);
1731  void segmentWrite(uint8_t cmd, uint8_t offset,
1732  uint8_t length, uint8_t * buffer);
1733 
1734  void sendCommandHeader(uint8_t cmd);
1735  void serialW7(uint8_t val) { _stream->write(val & 0x7F); }
1736 };
1737 
1741 class JrkG2I2C : public JrkG2Base
1742 {
1743 public:
1753  JrkG2I2C(uint8_t address = 11) : _address(address & 0x7F)
1754  {
1755  }
1756 
1757  // TODO: support Wire1 on Arduino Due, and bit-banging I2C on any board?
1758 
1760  uint8_t getAddress() { return _address; }
1761 
1762 private:
1763  const uint8_t _address;
1764 
1765  void commandQuick(uint8_t cmd);
1766  void commandW7(uint8_t cmd, uint8_t val);
1767  void commandWs14(uint8_t cmd, int16_t val);
1768  uint8_t commandR8(uint8_t cmd);
1769  uint16_t commandR16(uint8_t cmd);
1770  void segmentRead(uint8_t cmd, uint8_t offset,
1771  uint8_t length, uint8_t * buffer);
1772  void segmentWrite(uint8_t cmd, uint8_t offset,
1773  uint8_t length, uint8_t * buffer) ;
1774 };
uint16_t getEncodedHardCurrentLimit()
Definition: JrkG2.h:653
uint16_t getMaxDutyCycleWhileFeedbackOutOfRange()
Definition: JrkG2.h:962
const uint16_t JrkG2InputNull
Definition: JrkG2.h:19
JrkG2ForceMode
Definition: JrkG2.h:73
void setEncodedHardCurrentLimit(uint16_t encoded_limit)
Definition: JrkG2.h:1216
uint16_t getVinVoltage()
Definition: JrkG2.h:511
JrkG2ForceMode getForceMode()
Definition: JrkG2.h:500
void setMaxDecelerationReverse(uint16_t decel)
Definition: JrkG2.h:1059
void setMaxAccelerationReverse(uint16_t accel)
Definition: JrkG2.h:999
uint16_t getMaxDecelerationForward()
Definition: JrkG2.h:1045
uint16_t getRawCurrent()
Definition: JrkG2.h:641
uint16_t getMaxDutyCycleReverse()
Definition: JrkG2.h:1126
int16_t getDutyCycle()
Definition: JrkG2.h:400
void setSoftCurrentLimitReverse(uint16_t current)
Definition: JrkG2.h:1309
uint16_t getPIDPeriodCount()
Definition: JrkG2.h:428
uint16_t getPIDPeriod()
Definition: JrkG2.h:916
void setCoastWhenOff(bool coast)
Definition: JrkG2.h:749
void setMaxDeceleration(uint16_t decel)
Definition: JrkG2.h:1082
uint8_t getDerivativeExponent()
Definition: JrkG2.h:891
uint8_t getDeviceNumber()
Gets the serial device number this object is using.
Definition: JrkG2.h:1718
uint16_t getSoftCurrentLimitReverse()
Definition: JrkG2.h:1318
uint16_t getMaxDutyCycleForward()
Definition: JrkG2.h:1104
uint16_t getMaxAccelerationReverse()
Definition: JrkG2.h:1008
void getRAMSettings(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: JrkG2.h:1379
void setProportionalCoefficient(uint16_t multiplier, uint8_t exponent)
Definition: JrkG2.h:795
void setMaxDecelerationForward(uint16_t decel)
Definition: JrkG2.h:1036
JrkG2Pin
This enum defines the Jrk G2&#39;s control and feedback pins.
Definition: JrkG2.h:96
uint16_t getDerivativeMultiplier()
Definition: JrkG2.h:882
int16_t getDutyCycleTarget()
Definition: JrkG2.h:384
void stopMotor()
Definition: JrkG2.h:289
void setMaxDutyCycle(uint16_t duty)
Definition: JrkG2.h:1139
JrkG2OptionsByte3
Definition: JrkG2.h:112
void setMaxDutyCycleForward(uint16_t duty)
Definition: JrkG2.h:1095
uint16_t getSoftCurrentLimitForward()
Definition: JrkG2.h:1296
uint8_t getCurrentChoppingConsecutiveCount()
Definition: JrkG2.h:673
void setSoftCurrentLimit(uint16_t current)
Definition: JrkG2.h:1332
uint8_t getAddress()
Gets the I2C address this object is using.
Definition: JrkG2.h:1760
uint8_t getLastError()
Definition: JrkG2.h:128
void forceDutyCycleTarget(int16_t dutyCycle)
Definition: JrkG2.h:238
uint8_t getBrakeDurationForward()
Definition: JrkG2.h:1239
void setDerivativeCoefficient(uint16_t multiplier, uint8_t exponent)
Definition: JrkG2.h:873
JrkG2I2C(uint8_t address=11)
Definition: JrkG2.h:1753
void getEEPROMSettings(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: JrkG2.h:1357
void getVariables(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: JrkG2.h:1427
uint16_t getErrorFlagsOccurred()
Definition: JrkG2.h:483
void setMaxAccelerationForward(uint16_t accel)
Definition: JrkG2.h:976
uint8_t getIntegralExponent()
Definition: JrkG2.h:852
uint8_t getCurrentChoppingOccurrenceCount()
Definition: JrkG2.h:688
uint16_t getScaledFeedback()
Definition: JrkG2.h:352
uint16_t getIntegralMultiplier()
Definition: JrkG2.h:843
void setTargetLowResFwd(uint8_t target)
Definition: JrkG2.h:209
JrkG2Error
Definition: JrkG2.h:29
const uint8_t JrkG2CommReadError
Definition: JrkG2.h:23
void setBrakeDurationForward(uint8_t duration)
Definition: JrkG2.h:1230
uint8_t getBrakeDurationReverse()
Definition: JrkG2.h:1261
bool getPIDPeriodExceeded()
Definition: JrkG2.h:420
int16_t getIntegral()
Definition: JrkG2.h:363
JrkG2Command
Definition: JrkG2.h:50
uint32_t getUpTime()
Definition: JrkG2.h:544
void setBrakeDuration(uint8_t duration)
Definition: JrkG2.h:1274
uint16_t getAnalogReading(JrkG2Pin pin)
Definition: JrkG2.h:602
JrkG2Reset getDeviceReset()
Definition: JrkG2.h:532
bool getDigitalReading(JrkG2Pin pin)
Definition: JrkG2.h:628
void setRAMSettings(uint8_t offset, uint8_t length, uint8_t *buffer)
Definition: JrkG2.h:1404
uint16_t getFeedback()
Definition: JrkG2.h:341
uint16_t getEncodedHardCurrentLimitReverse()
Definition: JrkG2.h:1198
void setMaxDutyCycleWhileFeedbackOutOfRange(uint16_t duty)
Definition: JrkG2.h:953
void setIntegralCoefficient(uint16_t multiplier, uint8_t exponent)
Definition: JrkG2.h:834
void setMaxAcceleration(uint16_t accel)
Definition: JrkG2.h:1022
void setMaxDutyCycleReverse(uint16_t duty)
Definition: JrkG2.h:1117
void forceDutyCycle(int16_t dutyCycle)
Definition: JrkG2.h:270
uint16_t getInput()
Definition: JrkG2.h:312
void setBrakeDurationReverse(uint8_t duration)
Definition: JrkG2.h:1252
uint16_t getRCPulseWidth()
Definition: JrkG2.h:562
void setTargetLowResRev(uint8_t target)
Definition: JrkG2.h:182
uint16_t getTarget()
Definition: JrkG2.h:324
uint16_t getMaxDecelerationReverse()
Definition: JrkG2.h:1068
JrkG2Reset
Definition: JrkG2.h:84
void setTarget(uint16_t target)
Definition: JrkG2.h:152
void setResetIntegral(bool reset)
Definition: JrkG2.h:713
uint16_t getMaxAccelerationForward()
Definition: JrkG2.h:985
uint16_t getProportionalMultiplier()
Definition: JrkG2.h:804
uint16_t getErrorFlagsHalting()
Definition: JrkG2.h:454
uint16_t getIntegralLimit()
Definition: JrkG2.h:940
uint8_t getCurrentLowRes()
Definition: JrkG2.h:410
void setIntegralLimit(uint16_t limit)
Definition: JrkG2.h:932
uint16_t getEncodedHardCurrentLimitForward()
Definition: JrkG2.h:1169
int16_t getLastDutyCycle()
Definition: JrkG2.h:664
void setSoftCurrentLimitForward(uint16_t current)
Definition: JrkG2.h:1287
bool getResetIntegral()
Definition: JrkG2.h:731
bool getCoastWhenOff()
Definition: JrkG2.h:767
uint16_t getFBTReading()
Definition: JrkG2.h:581
void setEncodedHardCurrentLimitForward(uint16_t encoded_limit)
Definition: JrkG2.h:1156
void setEncodedHardCurrentLimitReverse(uint16_t encoded_limit)
Definition: JrkG2.h:1186
void setPIDPeriod(uint16_t period)
Definition: JrkG2.h:908
JrkG2Serial(Stream &stream, uint8_t deviceNumber=255)
Definition: JrkG2.h:1711
uint8_t getProportionalExponent()
Definition: JrkG2.h:813
uint16_t getCurrent()
Definition: JrkG2.h:518