├── TB6612FNG-master_V1.zip ├── keywords.txt ├── .github └── FUNDING.yml ├── LICENSE.txt ├── TB6612FNG.h ├── README.md ├── examples └── TB6612FNG │ └── TB6612FNG.ino └── TB6612FNG.cpp /TB6612FNG-master_V1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheDIYGuy999/TB6612FNG/HEAD/TB6612FNG-master_V1.zip -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For TB6612FNG 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | TB6612FNG KEYWORD 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | begin KEYWORD2 16 | drive KEYWORD2 17 | brakeActive KEYWORD2 -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: TheDIYGuy999 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: "https://paypal.me/thediyguy999" 13 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 - 2017 TheDIYGuy999 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /TB6612FNG.h: -------------------------------------------------------------------------------- 1 | /* 2 | TB6612FNG.h - Library for the Toshiba TB6612FNG motor driver. 3 | Created by TheDIYGuy999 June - November 2016 4 | Released into the public domain. 5 | 6 | This is Version 1.2 7 | 8 | Change history: 9 | 10 | V1.1: 11 | The pin configuration was moved to the separate begin() function. 12 | Change your existing programs in accordance with the provided example 13 | 14 | V1.2: 15 | minPWM input variable added to the drive() function. 16 | Allows to eliminate the backlash in self balancing applications 17 | */ 18 | 19 | 20 | #ifndef TB6612FNG_h 21 | #define TB6612FNG_h 22 | 23 | #include "Arduino.h" 24 | 25 | // Class definition (header) ======================================================================== 26 | class TB6612FNG { 27 | public: 28 | TB6612FNG(); 29 | void begin(int pin1, int pin2, int pwmPin, int minInput, int maxInput, int neutralWidth, boolean invert); 30 | boolean drive(int controlValue, int minPWM, int maxPWM, int rampTime, boolean neutralBrake); 31 | boolean brakeActive(); 32 | 33 | private: 34 | int _pin1; 35 | int _pin2; 36 | int _pwmPin; 37 | int _minInput; 38 | int _maxInput; 39 | int _minNeutral; 40 | int _maxNeutral; 41 | int _controlValue; 42 | int _controlValueRamp; 43 | int _minPWM; 44 | int _maxPWM; 45 | int _rampTime; 46 | boolean _neutralBrake; 47 | boolean _invert; 48 | unsigned long _previousMillis = 0; 49 | unsigned long _previousMillisBrake = 0; 50 | byte _state = 0; 51 | byte _forward; 52 | byte _reverse; 53 | byte _upwards; 54 | byte _downwards; 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advanced Arduino H-Bridge control library 2 | 3 | This is an Arduino library for the Toshiba TB6612FNG DC motor driver 4 | 5 | ## Features: 6 | - Adjustable fader for smooth speed changes 7 | - brake active or not in neutral mode 8 | - selectable input signal range (e.g. 0 - 100, 0 - 1023, -255 - 255 etc.) 9 | - selectable neutral position width. This allows you to optimize it for your joystick 10 | - the motor rotation direction is reversible in software, so you don't have to switch your motor wires, if the direction is reversed 11 | - The end-speed is adjustable during runtime. This allows you to simulate different gear ratios 12 | - drive function returns true while driving or false while in neutral 13 | - brakeActive function returns true, while the vehicle is getting slower. Used to control brake lights 14 | - Backlash compensation for self balancing applications 15 | 16 | New in V 1.1: 17 | - Pin configuration moved to begin() function. This change was necessary due to new requirements in my new "Micro RC Receiver" V1.7 software revision 18 | - If you've used the previous version in a project, you will have to change the pin configuration in accordance with the provided example. The archived V1.0 is enclosed and will not be maintained anymore. 19 | 20 | New in V1.2: 21 | - minPWM input variable added to the drive() function. Allows to eliminate the backlash in self balancing applications 22 | - IMPORTANT!! You have to add this new input variable to your existing sketches! Ohtherwise it will not compile. 23 | 24 | 25 | ## Usage 26 | 27 | See [example](https://github.com/TheDIYGuy999/TB6612FNG/blob/master/examples/TB6612FNG/TB6612FNG.ino). 28 | 29 | 30 | (c) 2016 - 2017 TheDIYGuy999 31 | -------------------------------------------------------------------------------- /examples/TB6612FNG/TB6612FNG.ino: -------------------------------------------------------------------------------- 1 | // This example was cuccessfully tested on an Sparkfun Pro Micro in 8MHz version 2 | // It also works on a Pro Mini, but only, if you don't change the PWM frequency 3 | 4 | // Version 1.2 5 | 6 | // 7 | // ======================================================================================================= 8 | // INCLUDE LIRBARIES 9 | // ======================================================================================================= 10 | // 11 | #include // https://github.com/TheDIYGuy999/TB6612FNG 12 | 13 | // Optional for motor PWM frequency adjustment: 14 | //#include // https://github.com/kiwisincebirth/Arduino/tree/master/libraries/PWMFrequency 15 | 16 | // 17 | // ======================================================================================================= 18 | // CREATE MOTOR OBJECTS 19 | // ======================================================================================================= 20 | // 21 | 22 | // define motor pin numbers 23 | #define motor1_in1 2 24 | #define motor1_in2 4 25 | #define motor1_pwm 5 26 | 27 | #define motor2_in1 7 28 | #define motor2_in2 8 29 | #define motor2_pwm 6 30 | 31 | // Create motor objects 32 | TB6612FNG Motor1; // Motor 1 33 | TB6612FNG Motor2; // Motor 2 34 | 35 | // 36 | // ======================================================================================================= 37 | // LIGHTS 38 | // ======================================================================================================= 39 | // 40 | 41 | void lights() { 42 | if (Motor1.brakeActive()) { // if braking detected from TB6612FNG motor driver 43 | //digitalWrite(BRAKELIGHTS, HIGH); 44 | } 45 | else { 46 | //digitalWrite(BRAKELIGHTS, LOW); 47 | } 48 | } 49 | 50 | // 51 | // ======================================================================================================= 52 | // MAIN ARDUINO SETUP (1x during startup) 53 | // ======================================================================================================= 54 | // 55 | void setup() { 56 | 57 | // Motor pin setup 58 | // SYNTAX: IN1, IN2, PWM, min. input value, max. input value, neutral position width 59 | // invert rotation direction true or false 60 | Motor1.begin(motor1_in1, motor1_in2, motor1_pwm, 0, 1023, 60, false); // Motor 1 61 | Motor2.begin(motor2_in1, motor2_in2, motor2_pwm, 0, 1023, 60, false); // Motor 2 62 | 63 | // Optional: Motor PWM frequency (Requires the PWMFrequency.h library) 64 | /*setPWMPrescaler(motor1_pwm, 1); // 123Hz = 256, 492Hz = 64, 3936Hz = 8, 31488Hz = 1 65 | setPWMPrescaler(motor2_pwm, 1);*/ 66 | } 67 | 68 | // 69 | // ======================================================================================================= 70 | // DRIVE MOTOR 71 | // ======================================================================================================= 72 | // 73 | 74 | void driveMotor() { 75 | 76 | int speed1 = 512; 77 | int speed2 = 512; 78 | 79 | // Read Potentiometer 80 | speed1 = analogRead(A0); // 0 - 1023 81 | speed2 = analogRead(A1); // 0 - 1023 82 | 83 | // ***************** Note! The ramptime is intended to protect the gearbox! ******************* 84 | // SYNTAX: Input value, min PWM, max PWM, ramptime in ms per 1 PWM increment 85 | // false = brake in neutral position inactive 86 | if (Motor1.drive(speed1, 0, 255, 7, false) ) { // Motor 1 87 | // returns true, if motor is running, so we can do other stuff here! 88 | } 89 | Motor2.drive(speed2, 0, 255, 1, false); // Motor 2 90 | } 91 | 92 | // 93 | // ======================================================================================================= 94 | // MAIN LOOP 95 | // ======================================================================================================= 96 | // 97 | 98 | void loop() { 99 | // Drive the main motor 100 | driveMotor(); 101 | 102 | //Light control 103 | lights(); 104 | } 105 | -------------------------------------------------------------------------------- /TB6612FNG.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TB6612FNG.h - Library for the Toshiba TB6612FNG motor driver. 3 | Created by TheDIYGuy999 June - November 2016 4 | Released into the public domain. 5 | 6 | This is Version 1.2 7 | 8 | The pin configuration was moved to the separate begin() function. 9 | Change your existing programs in accordance with the provided example 10 | */ 11 | 12 | #include "Arduino.h" 13 | #include "TB6612FNG.h" 14 | 15 | // Member definition (code) ======================================================================== 16 | 17 | TB6612FNG::TB6612FNG() { // Constructor 18 | _state = 0; 19 | _previousMillis = 0; 20 | } 21 | 22 | // Begin function ************************************************************ 23 | 24 | // NOTE: The first pin must always be PWM capable, the second only, if the last parameter is set to "true" 25 | // SYNTAX: IN1, IN2, min. input value, max. input value, neutral position width 26 | // invert rotation direction, true = both pins are PWM capable 27 | void TB6612FNG::begin(int pin1, int pin2, int pwmPin, int minInput, int maxInput, int neutralWidth, boolean invert) { 28 | _pin1 = pin1; 29 | _pin2 = pin2; 30 | _pwmPin = pwmPin; 31 | _minInput = minInput; 32 | _maxInput = maxInput; 33 | _minNeutral = (_maxInput + _minInput) / 2 - (neutralWidth / 2); 34 | _maxNeutral = (_maxInput + _minInput) / 2 + (neutralWidth / 2); 35 | _controlValueRamp = (_minNeutral + _maxNeutral) / 2; 36 | _invert = invert; 37 | 38 | pinMode(_pin1, OUTPUT); 39 | pinMode(_pin2, OUTPUT); 40 | pinMode(_pwmPin, OUTPUT); 41 | digitalWrite(_pin1, LOW); 42 | digitalWrite(_pin2, LOW); 43 | digitalWrite(_pwmPin, HIGH); 44 | } 45 | 46 | // Drive function ************************************************************ 47 | 48 | // SYNTAX: Input value, max PWM, ramptime in ms per 1 PWM increment 49 | // true = brake active, false = brake in neutral position inactive 50 | boolean TB6612FNG::drive(int controlValue, int minPWM, int maxPWM, int rampTime, boolean neutralBrake) { 51 | _controlValue = controlValue; 52 | _minPWM = minPWM; 53 | _maxPWM = maxPWM; 54 | _rampTime = rampTime; 55 | _neutralBrake = neutralBrake; 56 | 57 | 58 | 59 | if (_invert) { 60 | _controlValue = map (_controlValue, _minInput, _maxInput, _maxInput, _minInput); // invert driving direction 61 | } 62 | 63 | // Fader (allows to ramp the motor speed slowly up & down) -------------------- 64 | if (_rampTime >= 1) { 65 | unsigned long _currentMillis = millis(); 66 | if (_currentMillis - _previousMillis >= _rampTime) { 67 | // Increase 68 | if (_controlValue > _controlValueRamp && _controlValueRamp < _maxInput) { 69 | _controlValueRamp++; 70 | _upwards = true; 71 | _downwards = false; 72 | } 73 | // Decrease 74 | else if (_controlValue < _controlValueRamp && _controlValueRamp > _minInput) { 75 | _controlValueRamp--; 76 | _upwards = false; 77 | _downwards = true; 78 | } 79 | else { 80 | _upwards = false; 81 | _downwards = false; 82 | } 83 | _previousMillis = _currentMillis; 84 | } 85 | } 86 | else { 87 | _controlValueRamp = _controlValue; 88 | _upwards = false; 89 | _downwards = false; 90 | } 91 | 92 | // H bridge controller ------------------- 93 | if (_controlValueRamp >= _maxNeutral) { // Forward 94 | digitalWrite(_pin1, HIGH); 95 | digitalWrite(_pin2, LOW); 96 | analogWrite(_pwmPin, map(_controlValueRamp, _maxNeutral, _maxInput, _minPWM, _maxPWM)); 97 | _forward = true; 98 | _reverse = false; 99 | return true; 100 | } 101 | else if (_controlValueRamp <= _minNeutral) { // Reverse 102 | digitalWrite(_pin1, LOW); 103 | digitalWrite(_pin2, HIGH); 104 | analogWrite(_pwmPin, map(_controlValueRamp, _minNeutral, _minInput, _minPWM, _maxPWM)); 105 | _forward = false; 106 | _reverse = true; 107 | return true; 108 | } 109 | else { // Neutral 110 | if (_neutralBrake) { 111 | digitalWrite(_pin1, HIGH); // Brake in neutral position active 112 | digitalWrite(_pin2, HIGH); 113 | } 114 | else { 115 | digitalWrite(_pin1, LOW); // Brake in neutral position inactive 116 | digitalWrite(_pin2, LOW); 117 | digitalWrite(_pwmPin, HIGH); 118 | } 119 | _forward = false; 120 | _reverse = false; 121 | return false; 122 | } 123 | } 124 | 125 | // Brakelight detection function ************************************************************ 126 | boolean TB6612FNG::brakeActive() { 127 | 128 | unsigned long _currentMillisBrake = millis(); 129 | 130 | // Reset delay timer, if vehicle isn't decelerating 131 | if ( (!(_upwards && _reverse)) && (!(_downwards && _forward)) ) { 132 | _previousMillisBrake = _currentMillisBrake; 133 | } 134 | 135 | if (_currentMillisBrake - _previousMillisBrake >= 100) { 136 | return true; 137 | } 138 | else { 139 | return false; 140 | } 141 | } 142 | 143 | --------------------------------------------------------------------------------