i2c driver for PiBorg PicoBorgReverse

Dependents:   TheBubbleWorks_MicroBorg

Committer:
waynek
Date:
Tue Feb 09 15:31:10 2016 +0000
Revision:
2:cecfacbc2048
Parent:
0:f8a6d1cc7fa8
Child:
5:7f64fd1d1c8b
removed microbit dependancy

Who changed what in which revision?

UserRevisionLine numberNew contents of line
waynek 0:f8a6d1cc7fa8 1 // PicoBorg Reverse i2c based Motor driver controller
waynek 0:f8a6d1cc7fa8 2 // Wayne Keenan
waynek 0:f8a6d1cc7fa8 3
waynek 0:f8a6d1cc7fa8 4 // Based on https://www.piborg.org/comment/498#comment-498
waynek 0:f8a6d1cc7fa8 5
waynek 2:cecfacbc2048 6 #include "mbed.h"
waynek 2:cecfacbc2048 7 #include "MyDebug.h"
waynek 0:f8a6d1cc7fa8 8
waynek 0:f8a6d1cc7fa8 9 /**************************************/
waynek 0:f8a6d1cc7fa8 10 /***** PicoBorg Reverse Constants *****/
waynek 0:f8a6d1cc7fa8 11 /**************************************/
waynek 0:f8a6d1cc7fa8 12
waynek 0:f8a6d1cc7fa8 13 // Commands
waynek 0:f8a6d1cc7fa8 14 // GET commands sent should be followed by a read for the result
waynek 0:f8a6d1cc7fa8 15 // All other commands are send only (no reply)
waynek 0:f8a6d1cc7fa8 16 #define PBR_COMMAND_SET_LED (1) // Set the LED status
waynek 0:f8a6d1cc7fa8 17 #define PBR_COMMAND_GET_LED (2) // Get the LED status
waynek 0:f8a6d1cc7fa8 18 #define PBR_COMMAND_SET_A_FWD (3) // Set motor 2 PWM rate in a forwards direction
waynek 0:f8a6d1cc7fa8 19 #define PBR_COMMAND_SET_A_REV (4) // Set motor 2 PWM rate in a reverse direction
waynek 0:f8a6d1cc7fa8 20 #define PBR_COMMAND_GET_A (5) // Get motor 2 direction and PWM rate
waynek 0:f8a6d1cc7fa8 21 #define PBR_COMMAND_SET_B_FWD (6) // Set motor 1 PWM rate in a forwards direction
waynek 0:f8a6d1cc7fa8 22 #define PBR_COMMAND_SET_B_REV (7) // Set motor 1 PWM rate in a reverse direction
waynek 0:f8a6d1cc7fa8 23 #define PBR_COMMAND_GET_B (8) // Get motor 1 direction and PWM rate
waynek 0:f8a6d1cc7fa8 24 #define PBR_COMMAND_ALL_OFF (9) // Switch everything off
waynek 0:f8a6d1cc7fa8 25 #define PBR_COMMAND_RESET_EPO (10) // Resets the EPO flag, use after EPO has been tripped and switch is now clear
waynek 0:f8a6d1cc7fa8 26 #define PBR_COMMAND_GET_EPO (11) // Get the EPO latched flag
waynek 0:f8a6d1cc7fa8 27 #define PBR_COMMAND_SET_EPO_IGNORE (12) // Set the EPO ignored flag, allows the system to run without an EPO
waynek 0:f8a6d1cc7fa8 28 #define PBR_COMMAND_GET_EPO_IGNORE (13) // Get the EPO ignored flag
waynek 0:f8a6d1cc7fa8 29 #define PBR_COMMAND_GET_DRIVE_FAULT (14) // Get the drive fault flag, indicates faults such as short-circuits and under voltage
waynek 0:f8a6d1cc7fa8 30 #define PBR_COMMAND_SET_ALL_FWD (15) // Set all motors PWM rate in a forwards direction
waynek 0:f8a6d1cc7fa8 31 #define PBR_COMMAND_SET_ALL_REV (16) // Set all motors PWM rate in a reverse direction
waynek 0:f8a6d1cc7fa8 32 #define PBR_COMMAND_SET_FAILSAFE (17) // Set the failsafe flag, turns the motors off if communication is interrupted
waynek 0:f8a6d1cc7fa8 33 #define PBR_COMMAND_GET_FAILSAFE (18) // Get the failsafe flag
waynek 0:f8a6d1cc7fa8 34 #define PBR_COMMAND_SET_ENC_MODE (19) // Set the board into encoder or speed mode
waynek 0:f8a6d1cc7fa8 35 #define PBR_COMMAND_GET_ENC_MODE (20) // Get the boards current mode, encoder or speed
waynek 0:f8a6d1cc7fa8 36 #define PBR_COMMAND_MOVE_A_FWD (21) // Move motor 2 forward by n encoder ticks
waynek 0:f8a6d1cc7fa8 37 #define PBR_COMMAND_MOVE_A_REV (22) // Move motor 2 reverse by n encoder ticks
waynek 0:f8a6d1cc7fa8 38 #define PBR_COMMAND_MOVE_B_FWD (23) // Move motor 1 forward by n encoder ticks
waynek 0:f8a6d1cc7fa8 39 #define PBR_COMMAND_MOVE_B_REV (24) // Move motor 1 reverse by n encoder ticks
waynek 0:f8a6d1cc7fa8 40 #define PBR_COMMAND_MOVE_ALL_FWD (25) // Move all motors forward by n encoder ticks
waynek 0:f8a6d1cc7fa8 41 #define PBR_COMMAND_MOVE_ALL_REV (26) // Move all motors reverse by n encoder ticks
waynek 0:f8a6d1cc7fa8 42 #define PBR_COMMAND_GET_ENC_MOVING (27) // Get the status of encoders moving
waynek 0:f8a6d1cc7fa8 43 #define PBR_COMMAND_SET_ENC_SPEED (28) // Set the maximum PWM rate in encoder mode
waynek 0:f8a6d1cc7fa8 44 #define PBR_COMMAND_GET_ENC_SPEED (29) // Get the maximum PWM rate in encoder mode
waynek 0:f8a6d1cc7fa8 45 #define PBR_COMMAND_GET_ID (0x99) // Get the board identifier
waynek 0:f8a6d1cc7fa8 46 #define PBR_COMMAND_SET_I2C_ADD (0xAA) // Set a new I2C address
waynek 0:f8a6d1cc7fa8 47
waynek 0:f8a6d1cc7fa8 48 // Values
waynek 0:f8a6d1cc7fa8 49 // These are the corresponding numbers for states used by the above commands
waynek 0:f8a6d1cc7fa8 50 #define PBR_COMMAND_VALUE_FWD (1) // I2C value representing forward
waynek 0:f8a6d1cc7fa8 51 #define PBR_COMMAND_VALUE_REV (2) // I2C value representing reverse
waynek 0:f8a6d1cc7fa8 52 #define PBR_COMMAND_VALUE_ON (1) // I2C value representing on
waynek 0:f8a6d1cc7fa8 53 #define PBR_COMMAND_VALUE_OFF (0) // I2C value representing off
waynek 0:f8a6d1cc7fa8 54 #define PBR_I2C_ID_PICOBORG_REV (0x15) // I2C values returned when calling the GET_ID command
waynek 0:f8a6d1cc7fa8 55 #define PBR_DEFAULT_I2C_ADDRESS (0x44) // I2C address set by default (before using SET_I2C_ADD)
waynek 0:f8a6d1cc7fa8 56 #define PBR_ERROR_READING (888) // Returned from GetMotor commands when value failed to read
waynek 0:f8a6d1cc7fa8 57
waynek 0:f8a6d1cc7fa8 58 // Limits
waynek 0:f8a6d1cc7fa8 59 // These define the maximums that the PicoBorg Reverse will accept
waynek 0:f8a6d1cc7fa8 60 #define PBR_I2C_MAX_LEN (4) // Maximum number of bytes in an I2C message
waynek 0:f8a6d1cc7fa8 61 #define PBR_PWM_MAX (255) // Maximum I2C value for speed settings (represents 100% drive)
waynek 0:f8a6d1cc7fa8 62 #define PBR_MINIMUM_I2C_ADDRESS (0x03) // Minimum allowed value for the I2C address
waynek 0:f8a6d1cc7fa8 63 #define PBR_MAXIMUM_I2C_ADDRESS (0x77) // Maximum allowed value for the I2C address
waynek 0:f8a6d1cc7fa8 64
waynek 2:cecfacbc2048 65 extern Serial serial;
waynek 0:f8a6d1cc7fa8 66
waynek 0:f8a6d1cc7fa8 67 class PicoBorgReverse
waynek 0:f8a6d1cc7fa8 68 {
waynek 0:f8a6d1cc7fa8 69 public:
waynek 2:cecfacbc2048 70 PicoBorgReverse(I2C* _i2c) : addr(PBR_DEFAULT_I2C_ADDRESS << 1), i2c(_i2c) {
waynek 0:f8a6d1cc7fa8 71 }
waynek 0:f8a6d1cc7fa8 72
waynek 0:f8a6d1cc7fa8 73 /**************************************/
waynek 0:f8a6d1cc7fa8 74 /***** PicoBorg Reverse Functions *****/
waynek 0:f8a6d1cc7fa8 75 /**************************************/
waynek 0:f8a6d1cc7fa8 76 // All motor drive levels are from +PBR_PWM_MAX to -PBR_PWM_MAX
waynek 0:f8a6d1cc7fa8 77 // Positive values indicate forwards motion
waynek 0:f8a6d1cc7fa8 78 // Negative values indicate reverse motion
waynek 0:f8a6d1cc7fa8 79 // 0 indicates stationary
waynek 0:f8a6d1cc7fa8 80 // Values outside PBR_PWM_MAX will be capped to PBR_PWM_MAX (100%)
waynek 0:f8a6d1cc7fa8 81
waynek 0:f8a6d1cc7fa8 82
waynek 0:f8a6d1cc7fa8 83
waynek 0:f8a6d1cc7fa8 84 /***** Motor functions *****/
waynek 0:f8a6d1cc7fa8 85
waynek 0:f8a6d1cc7fa8 86 // Sets the drive level for motor 2
waynek 0:f8a6d1cc7fa8 87 void setMotor2(int power);
waynek 0:f8a6d1cc7fa8 88
waynek 0:f8a6d1cc7fa8 89 // Gets the drive level for motor 2
waynek 0:f8a6d1cc7fa8 90 int getMotor2(void);
waynek 0:f8a6d1cc7fa8 91
waynek 0:f8a6d1cc7fa8 92 // Sets the drive level for motor 1
waynek 0:f8a6d1cc7fa8 93 void setMotor1(int power);
waynek 0:f8a6d1cc7fa8 94
waynek 0:f8a6d1cc7fa8 95 // Gets the drive level for motor 1
waynek 0:f8a6d1cc7fa8 96 int getMotor1(void);
waynek 0:f8a6d1cc7fa8 97
waynek 0:f8a6d1cc7fa8 98 // Sets the drive level for all motors
waynek 0:f8a6d1cc7fa8 99 void setMotors(int power);
waynek 0:f8a6d1cc7fa8 100
waynek 0:f8a6d1cc7fa8 101 // Sets all motors to stopped, useful when ending a program
waynek 0:f8a6d1cc7fa8 102 void motorsOff(void);
waynek 0:f8a6d1cc7fa8 103
waynek 0:f8a6d1cc7fa8 104 /***** General functions *****/
waynek 0:f8a6d1cc7fa8 105
waynek 0:f8a6d1cc7fa8 106 // Reads the board identifier and checks it is a PicoBorg Reverse, false for incorrect, true for correct
waynek 0:f8a6d1cc7fa8 107 bool checkId(void);
waynek 0:f8a6d1cc7fa8 108
waynek 0:f8a6d1cc7fa8 109 // Sets the current state of the LED, false for off, true for on
waynek 0:f8a6d1cc7fa8 110 void setLed(bool state);
waynek 0:f8a6d1cc7fa8 111
waynek 0:f8a6d1cc7fa8 112 // Reads the current state of the LED, false for off, true for on
waynek 0:f8a6d1cc7fa8 113 bool getLed(void);
waynek 0:f8a6d1cc7fa8 114
waynek 0:f8a6d1cc7fa8 115 // Resets the EPO latch state, use to allow movement again after the EPO has been tripped
waynek 0:f8a6d1cc7fa8 116 void resetEpo(void);
waynek 0:f8a6d1cc7fa8 117
waynek 0:f8a6d1cc7fa8 118 // Reads the system EPO latch state.
waynek 0:f8a6d1cc7fa8 119 // If false the EPO has not been tripped, and movement is allowed.
waynek 0:f8a6d1cc7fa8 120 // If true the EPO has been tripped, movement is disabled if the EPO is not ignored (see PbrSetEpoIgnore)
waynek 0:f8a6d1cc7fa8 121 // Movement can be re-enabled by calling PbrResetEpo.
waynek 0:f8a6d1cc7fa8 122 bool getEpo(void);
waynek 0:f8a6d1cc7fa8 123
waynek 0:f8a6d1cc7fa8 124 // Sets the system to ignore or use the EPO latch, set to false if you have an EPO switch, true if you do not
waynek 0:f8a6d1cc7fa8 125 void setEpoIgnore(bool state);
waynek 0:f8a6d1cc7fa8 126
waynek 0:f8a6d1cc7fa8 127 // Reads the system EPO ignore state, False for using the EPO latch, True for ignoring the EPO latch
waynek 0:f8a6d1cc7fa8 128 bool getEpoIgnore(void);
waynek 0:f8a6d1cc7fa8 129
waynek 0:f8a6d1cc7fa8 130 // Sets the system to enable or disable the communications failsafe
waynek 0:f8a6d1cc7fa8 131 // The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second
waynek 0:f8a6d1cc7fa8 132 // Set to True to enable this failsafe, set to False to disable this failsafe
waynek 0:f8a6d1cc7fa8 133 // The failsafe is disabled at power on
waynek 0:f8a6d1cc7fa8 134 void setCommsFailsafe(bool state);
waynek 0:f8a6d1cc7fa8 135
waynek 0:f8a6d1cc7fa8 136 // Read the current system state of the communications failsafe, true for enabled, false for disabled
waynek 0:f8a6d1cc7fa8 137 // The failsafe will turn the motors off unless it is commanded at least once every 1/4 of a second
waynek 0:f8a6d1cc7fa8 138 bool getCommsFailsafe(void);
waynek 0:f8a6d1cc7fa8 139
waynek 0:f8a6d1cc7fa8 140 // Reads the system drive fault state, False for no problems, True for a fault has been detected
waynek 0:f8a6d1cc7fa8 141 // Faults may indicate power problems, such as under-voltage (not enough power), and may be cleared by setting a lower drive power
waynek 0:f8a6d1cc7fa8 142 // If a fault is persistent, it repeatably occurs when trying to control the board, this may indicate a wiring problem such as:
waynek 0:f8a6d1cc7fa8 143 // * The supply is not powerful enough for the motors
waynek 0:f8a6d1cc7fa8 144 // The board has a bare minimum requirement of 6V to operate correctly
waynek 0:f8a6d1cc7fa8 145 // A recommended minimum supply of 7.2V should be sufficient for smaller motors
waynek 0:f8a6d1cc7fa8 146 // * The + and - connections for either motor are connected to each other
waynek 0:f8a6d1cc7fa8 147 // * Either + or - is connected to ground (GND, also known as 0V or earth)
waynek 0:f8a6d1cc7fa8 148 // * Either + or - is connected to the power supply (V+, directly to the battery or power pack)
waynek 0:f8a6d1cc7fa8 149 // * One of the motors may be damaged
waynek 0:f8a6d1cc7fa8 150 // Faults will self-clear, they do not need to be reset, however some faults require both motors to be moving at less than 100% to clear
waynek 0:f8a6d1cc7fa8 151 // The easiest way to check is to put both motors at a low power setting which is high enough for them to rotate easily, such as 30%
waynek 0:f8a6d1cc7fa8 152 // Note that the fault state may be true at power up, this is normal and should clear when both motors have been driven
waynek 0:f8a6d1cc7fa8 153 // If there are no faults but you cannot make your motors move check PbrGetEpo to see if the safety switch has been tripped
waynek 0:f8a6d1cc7fa8 154 // For more details check the website at www.piborg.org/picoborgrev and double check the wiring instructions
waynek 0:f8a6d1cc7fa8 155 bool getDriveFault(void);
waynek 0:f8a6d1cc7fa8 156
waynek 0:f8a6d1cc7fa8 157 private:
waynek 0:f8a6d1cc7fa8 158
waynek 0:f8a6d1cc7fa8 159 void i2c_write(char b1)
waynek 0:f8a6d1cc7fa8 160 {
waynek 0:f8a6d1cc7fa8 161 char data[1] = {b1};
waynek 2:cecfacbc2048 162 this->i2c->write(addr, data, 1);
waynek 0:f8a6d1cc7fa8 163
waynek 0:f8a6d1cc7fa8 164 }
waynek 0:f8a6d1cc7fa8 165 void i2c_write(char b1, char b2)
waynek 0:f8a6d1cc7fa8 166 {
waynek 0:f8a6d1cc7fa8 167 char data[2] = {b1, b2};
waynek 2:cecfacbc2048 168 this->i2c->write(addr, data, 2);
waynek 2:cecfacbc2048 169 }
waynek 2:cecfacbc2048 170
waynek 2:cecfacbc2048 171 int i2c_read(char* buf, int len)
waynek 2:cecfacbc2048 172 {
waynek 2:cecfacbc2048 173 return (this->i2c->read(addr, buf, len));
waynek 0:f8a6d1cc7fa8 174 }
waynek 0:f8a6d1cc7fa8 175
waynek 0:f8a6d1cc7fa8 176 /***************************************/
waynek 0:f8a6d1cc7fa8 177 /***** PicoBorg Reverse Properties *****/
waynek 0:f8a6d1cc7fa8 178 /***************************************/
waynek 0:f8a6d1cc7fa8 179
waynek 0:f8a6d1cc7fa8 180 int addr; // define the I2C Address
waynek 2:cecfacbc2048 181 I2C* i2c;
waynek 0:f8a6d1cc7fa8 182 };