/* * The MIT License (MIT) * * Author: Oussema Harbi * Copyright (c) <2016> * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ #pragma once #include //We can use direct integer IDs, //or we can use the typedef here to help limit the error cases //and still support extension to support more Motors in the future //But when using typedef, we need to cast these when sending them in i2c bus #define SmartDrive_Motor_ID_1 0x01 #define SmartDrive_Motor_ID_2 0x02 #define SmartDrive_Motor_ID_BOTH 0x03 #define SmartDrive_Dir_Reverse 0x00 #define SmartDrive_Dir_Forward 0x01 #define SmartDrive_Action_Float 0x00 //stop and let the motor coast. #define SmartDrive_Action_Brake 0x01 //apply brakes, and resist change to tachometer #define SmartDrive_Action_BrakeHold 0x02 //apply brakes, and restore externally forced change to tachometer //Next action (upon completion of current action) #define SmartDrive_Completion_Wait_For 0x01 #define SmartDrive_Completion_Dont_Wait 0x00 #define SmartDrive_DefaultAddress 0x1b #define SmartDrive_VOLTAGE_MULTIPLIER 212.7 //Commonly used speed constants, these are just convenience constants //You can use any value between 0 and 100. #define SmartDrive_Speed_Full 90 #define SmartDrive_Speed_Medium 60 #define SmartDrive_Speed_Slow 25 //Different commands #define SmartDrive_CONTROL_SPEED 0x01 #define SmartDrive_CONTROL_RAMP 0x02 #define SmartDrive_CONTROL_RELATIVE 0x04 #define SmartDrive_CONTROL_TACHO 0x08 #define SmartDrive_CONTROL_BRK 0x10 #define SmartDrive_CONTROL_ON 0x20 #define SmartDrive_CONTROL_TIME 0x40 #define SmartDrive_CONTROL_GO 0x80 #define SmartDrive_COMMAND 0x41 #define SmartDrive_SETPT_M1 0x42 #define SmartDrive_SPEED_M1 0x46 #define SmartDrive_TIME_M1 0x47 #define SmartDrive_CMD_B_M1 0x48 #define SmartDrive_CMD_A_M1 0x49 #define SmartDrive_SETPT_M2 0x4A #define SmartDrive_SPEED_M2 0x4E #define SmartDrive_TIME_M2 0x4F #define SmartDrive_CMD_B_M2 0x50 #define SmartDrive_CMD_A_M2 0x51 //Read registers. #define SmartDrive_POSITION_M1 0x52 #define SmartDrive_POSITION_M2 0x56 #define SmartDrive_STATUS_M1 0x5A #define SmartDrive_STATUS_M2 0x5B #define SmartDrive_TASKS_M1 0x5C #define SmartDrive_TASKS_M2 0x5D //PID control registers #define SmartDrive_P_Kp 0x5E //proportional gain-position #define SmartDrive_P_Ki 0x60 //integral gain-position #define SmartDrive_P_Kd 0x62 //derivative gain-position #define SmartDrive_S_Kp 0x64 //proportional gain-speed #define SmartDrive_S_Ki 0x66 //integral gain-speed #define SmartDrive_S_Kd 0x68 //derivative gain-speed #define SmartDrive_PASSCOUNT 0x6A #define SmartDrive_PASSTOLERANCE 0x6B #define SmartDrive_CHKSUM 0x6C //Power data registers #define SmartDrive_BATT_VOLTAGE 0x6E #define SmartDrive_RESETSTATUS 0x6F #define SmartDrive_CURRENT_M1 0x70 #define SmartDrive_CURRENT_M2 0x72 //Supported I2C commands #define CMD_R 0x52 #define CMD_S 0x53 #define CMD_a 0x61 #define CMD_b 0x62 #define CMD_c 0x63 #define CMD_A 0x41 #define CMD_B 0x42 #define CMD_C 0x43 //Motor Status Masks #define SmartDrive_MOTOR_CONTROL_ON 0x1 #define SmartDrive_MOTOR_IS_RAMPING 0x2 #define SmartDrive_MOTOR_IS_POWERED 0x4 #define SmartDrive_MOTOR_POS_CTRL_ON 0x8 #define SmartDrive_MOTOR_IN_BRAKE_MODE 0x10 #define SmartDrive_MOTOR_OVERLOADED 0x20 #define SmartDrive_MOTOR_IN_TIME_MODE 0x40 #define SmartDrive_MOTOR_IS_STALLED 0x80 namespace upm { /** * @brief SmartDrive library * @defgroup smartdrive libupm-smartdrive * @ingroup i2c motor openelectrons */ /** * @library smartdrive * @sensor smartdrive * @comname SmartDrive advanced motor controller * @altname smartdrive * @type motor * @man openelectrons * @con i2c * * @brief API for the SmartDrive advanced motor controller from OpenElectronis * * SmartDrive is a multiplexer to control high current DC motors * * This module has been tested on the SmartDrive. * * @snippet smartdrive.cxx Interesting */ //Class definition class SmartDrive { public: /** * Initialize the class with the i2c address of your SmartDrive * @param SmartDrive_address Address of your SmartDrive. */ SmartDrive(int i2c_bus, int address = SmartDrive_DefaultAddress); /** * Writes a specified command on the command register of the SmartDrive * @param cmd The command you wish the SmartDrive to execute. */ void command(uint8_t cmd); /** * Reads the battery voltage. Multiplier constant not yet verified */ float GetBattVoltage(); /** * Reads the tacheometer position of the specified motor * @param motor_id Number of the motor you wish to read. */ uint32_t ReadTachometerPosition(int motor_id); /** * Turns the specified motor(s) forever * @param motor_id Number of the motor(s) you wish to turn. * @param direction The direction you wish to turn the motor(s). * @param speed The speed at which you wish to turn the motor(s). */ void Run_Unlimited(int motor_id, int direction, uint8_t speed); /** * Stops the specified motor(s) * @param motor_id Number of the motor(s) you wish to turn. * @param next_action How you wish to stop the motor(s). */ void StopMotor(int motor_id, int next_action ); /** * Turns the specified motor(s) for a given amount of seconds * @param motor_id Number of the motor(s) you wish to turn. * @param direction The direction you wish to turn the motor(s). * @param speed The speed at which you wish to turn the motor(s). * @param duration The time in seconds you wish to turn the motor(s). * @param wait_for_completion Tells the program when to handle the next line of code. * @param next_action How you wish to stop the motor(s). */ void Run_Seconds(int motor_id, int direction, uint8_t speed, uint8_t duration, bool wait_for_completion, int next_action ); /** * Waits until the specified time for the motor(s) to run is completed * @param motor_id Number of the motor(s) to wait for. */ void WaitUntilTimeDone(int motor_id); /** * Checks to ensure the specified time for the motor(s) to run is completed. * @param motor_id Number of the motor(s) to check. */ bool IsTimeDone(int motor_id); /** * Turns the specified motor(s) for given relative tacheometer count * @param motor_id Number of the motor(s) you wish to turn. * @param direction The direction you wish to turn the motor(s). * @param speed The speed at which you wish to turn the motor(s). * @param degrees The relative tacheometer count you wish to turn the motor(s). * @param wait_for_completion Tells the program when to handle the next line of code. * @param next_action How you wish to stop the motor(s). */ void Run_Degrees(int motor_id, int direction, uint8_t speed, uint32_t degrees, bool wait_for_completion, int next_action); /** * Turns the specified motor(s) for given relative tacheometer count * @param motor_id Number of the motor(s) you wish to turn. * @param direction The direction you wish to turn the motor(s). * @param speed The speed at which you wish to turn the motor(s). * @param rotations The relative amount of rotations you wish to turn the motor(s). * @param wait_for_completion Tells the program when to handle the next line of code. * @param next_action How you wish to stop the motor(s). */ void Run_Rotations(int motor_id, int direction, uint8_t speed, uint32_t rotations, bool wait_for_completion, int next_action); /** * Turns the specified motor(s) for given absolute tacheometer count * @param motor_id Number of the motor(s) you wish to turn. * @param direction The direction you wish to turn the motor(s). * @param speed The speed at which you wish to turn the motor(s). * @param tacho_count The absolute tacheometer count you wish to turn the motor(s). * @param wait_for_completion Tells the program when to handle the next line of code. * @param next_action How you wish to stop the motor(s). */ void Run_Tacho(int motor_id, uint8_t speed, uint32_t tacho_count, bool wait_for_completion, int next_action); /** * Waits until the specified tacheomter count for the motor(s) to run is reached. * @param motor_id Number of the motor(s) to wait for. */ void WaitUntilTachoDone(int motor_id); /** * Checks to ensure the specified tacheomter count for the motor(s) to run is reached. * @param motor_id Number of the motor(s) to check. */ bool IsTachoDone(int motor_id); /** * Writes user specified values to the PID control registers * @param Kp_tacho Proportional-gain of the tacheometer position of the motor. * @param Ki_tacho Integral-gain of the tacheometer position of the motor. * @param Kd_tacho Derivative-gain of the tacheometer position of the motor. * @param Kp_speed Proportional-gain of the speed of the motor. * @param Ki_speed Integral-gain of the speed of the motor. * @param Kd_speed Derivative-gain of the speed of the motor. */ void SetPerformanceParameters( uint16_t Kp_tacho, uint16_t Ki_tacho, uint16_t Kd_tacho, uint16_t Kp_speed, uint16_t Ki_speed, uint16_t Kd_speed, uint8_t passcount, uint8_t tolerance); /** * Reads the values of the PID control registers */ void ReadPerformanceParameters(); /** * Read the status of a motor, and return it in a uint8_t * param motor_id Number fo the motor to check */ uint8_t GetMotorStatus(int motor_id); /** * Print the detailed status of the motor * @param motor_id Number fo the motor to check */ void PrintMotorStatus(int motor_id); private: void writeByte(uint8_t addr, uint8_t value); void writeArray(uint8_t* array, uint8_t len); uint8_t readByte(uint8_t addr); uint16_t readInteger(uint8_t addr); uint32_t readLongSigned(uint8_t addr); private: int m_smartdrive_control_address; mraa::I2c m_i2c_smartdrive_control; }; }