1 /*
2  * Author: Jon Trulson <jtrulson@ics.com>
3  * Copyright (c) 2015 Intel Corporation.
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.
23  */
24 #pragma once
25 
26 #include <stdint.h>
27 #include <sys/time.h>
28 
29 #include <mraa/gpio.h>
30 #include <mraa/pwm.h>
31 
32 // in milliseconds
33 #define L298_DEFAULT_PWM_PERIOD 4
34 
35 namespace upm {
36   /**
37    * @brief L298 Dual H-Bridge Motor Driver library
38    * @defgroup l298 libupm-l298
39    * @ingroup seeed sparkfun gpio pwm motor
40    */
41 
42   /**
43    * @library l298
44    * @sensor l298
45    * @comname L298 Dual H-Bridge Motor Driver
46    * @type motor
47    * @man seeed sparkfun
48    * @web https://www.sparkfun.com/products/9670
49    * @con gpio pwm
50    *
51    * @brief API for the L298 Dual H-Bridge Motor Driver
52    *
53    * It was developed using the RobotBase Dual H-Bridge module.
54    *
55    * This module can support 2 DC motors, or one 2-phase stepper motor.
56    * It requires 3 pins per DC motor (or H-bridge), or 4 pins for
57    * the stepper motor (uses both H-bridges).
58    *
59    * @image html l298.jpg
60    * <br><em>L298 Dual H-Bridge Motor Driver image provided by SparkFun* under
61    * <a href=https://creativecommons.org/licenses/by-nc-sa/3.0/>
62    * CC BY-NC-SA-3.0</a>.</em>
63    *
64    * Example driving a DC motor
65    * @snippet l298.cxx Interesting
66    * Example driving a stepper motor
67    * @snippet l298-stepper.cxx Interesting
68    */
69   class L298 {
70   public:
71 
72     /**
73      * Enum to specify the direction of a motor
74      */
75     typedef enum {
76       DIR_NONE = 0x00,
77       DIR_CW   = 0x01,
78       DIR_CCW  = 0x02
79     } L298_DIRECTION_T;
80 
81     /**
82      * L298 constructor for DC motor(s) connected.
83      *
84      * @param pwm Digital pin to use for a DC motor - must be PWM-capable
85      * @param dir1 Digital pin to use for motor direction pin 1
86      * @param dir2 Digital pin to use for motor direction pin 2
87      */
88     L298(int pwm, int dir1, int dir2);
89 
90     /**
91      * L298 constructor for a 4-wire stepper motor
92      *
93      * @param stepsPerRev Number of steps per full revolution
94      * @param en Enables the pin
95      * @param i1 Digital pin to use for stepper input 1
96      * @param i2 Digital pin to use for stepper input 2
97      * @param i3 Digital pin to use for stepper input 3
98      * @param i4 Digital pin to use for stepper input 4
99      */
100     L298(int stepsPerRev, int en, int i1, int i2, int i3, int i4);
101 
102     /**
103      * L298 destructor
104      */
105     ~L298();
106 
107     /**
108      * Returns the number of milliseconds elapsed since initClock()
109      * was last called.
110      *
111      * @return Elapsed milliseconds
112      */
113     uint32_t getMillis();
114 
115     /**
116      * Resets the clock
117      *
118      */
119     void initClock();
120 
121     /**
122      * Sets the period in milliseconds
123      *
124      * @param ms Period in milliseconds
125      */
126     void setPeriodMS(int ms);
127 
128     /**
129      * Enables the PWM output for a motor
130      *
131      * @param enable Enables the PWM output if true, disables if false
132      */
133     void enable(bool enable);
134 
135     /**
136      * Sets the speed of a DC or stepper motor. For a DC motor, values
137      * can range from 0 (off) to 100 (full speed). For a stepper
138      * motor, specify the desired RPM.
139      *
140      * @param speed Speed to set the motor to
141      */
142     void setSpeed(int speed);
143 
144     /**
145      * Sets the direction of the motor, clockwise or counterclockwise
146      *
147      * @param dir Direction to set the motor to
148      */
149     void setDirection(L298_DIRECTION_T dir);
150 
151     /**
152      * Steps the stepper motor a specified number of steps
153      *
154      * @param steps Number of steps to move the stepper motor
155      */
156     void stepperSteps(unsigned int steps);
157 
158   private:
159     // DC motor mode enabled
160     bool m_motor;
161     // stepper mode enabled
162     bool m_stepper;
163 
164     struct timeval m_startTime;
165 
166     // DC motor
167     mraa_pwm_context m_pwm;
168     mraa_gpio_context m_dir1;
169     mraa_gpio_context m_dir2;
170 
171     // stepper (4-wire)
172     mraa_gpio_context m_stepEnable;
173     mraa_gpio_context m_stepI1;
174     mraa_gpio_context m_stepI2;
175     mraa_gpio_context m_stepI3;
176     mraa_gpio_context m_stepI4;
177 
178     // steps per revolution
179     int m_stepsPerRev;
180     int m_currentStep;
181     uint32_t m_stepDelay;
182 
183     /**
184      * Steps the motor one tick
185      *
186      */
187     void stepperStep();
188 
189     // step direction: - 1 = forward, -1 = backward
190     int m_stepDirection;
191   };
192 }
193 
194 
195