1 /*
2  * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3  * Copyright (c) 2014 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 <string>
27 #include <mraa/pwm.h>
28 
29 namespace upm {
30 
31 #define MIN_PULSE_WIDTH             600
32 #define MAX_PULSE_WIDTH             2500
33 #define PERIOD                      20000
34 
35 #define HIGH                        1
36 #define LOW                         0
37 
38 #define DEFAULT_WAIT_DISABLE_PWM    0
39 
40 /**
41  * @brief Servo library
42  *
43  * The base Servo class provides routines for setting the angle of the shaft
44  * as well as setting and getting the minimum and maximum pulse width and
45  * the maximum period.
46  *
47  * @defgroup servo libupm-servo
48  * @ingroup seeed emax pwm servos gsk
49  */
50 class Servo {
51     public:
52         /**
53          * Instantiates a Servo object
54          *
55          * @param pin Servo pin number
56          */
57         Servo (int pin);
58 
59         /**
60          * Instantiates a Servo object
61          *
62          * @param pin Servo pin number
63          * @param minPulseWidth Minimum pulse width, in microseconds
64          * @param maxPulseWidth Maximum pulse width, in microseconds
65          */
66         Servo (int pin, int minPulseWidth, int maxPulseWidth);
67 
68         /**
69          * Instantiates a Servo object
70          *
71          * @param pin Servo pin number
72          * @param minPulseWidth Minimum pulse width, in microseconds
73          * @param maxPulseWidth Maximum pulse width, in microseconds
74          * @param waitAndDisablePwm If 1, PWM is enabled only during the setAngle() execution
75          * for a period of 1 second, and then turned back off. If 0, PWM remains on afterward.
76          */
77         Servo (int pin, int minPulseWidth, int maxPulseWidth, int waitAndDisablePwm);
78 
79         /**
80          * Servo object destructor
81          */
82         ~Servo();
83 
84         /**
85          * Sets the angle of the servo engine.
86          *
87          * @param angle Number between 0 and 180
88          * @return 0 if successful, non-zero otherwise
89          */
90         mraa_result_t setAngle (int angle);
91 
92         /**
93          * Halts PWM for this servo and allows it to move freely.
94          */
95         mraa_result_t haltPwm ();
96 
97         /**
98          * Returns the name of the component
99          *
100          * @return Name of the component
101          */
name()102         std::string name()
103         {
104             return m_name;
105         }
106 
107         /**
108          * Sets the minimum pulse width
109          *
110          * @param width Minimum HIGH signal width
111          */
112         void setMinPulseWidth (int width);
113 
114         /**
115          * Sets the maximum pulse width
116          *
117          * @param width Maximum HIGH signal width
118          */
119         void setMaxPulseWidth (int width);
120 
121         /**
122          * Sets the maximum period width
123          *
124          * @param period PWM period width
125          */
126         void setPeriod (int period);
127 
128         /**
129          * Returns the minimum pulse width
130          *
131          * @return Minimum pulse width
132          */
133         int getMinPulseWidth ();
134 
135         /**
136          * Returns the maximum pulse width
137          *
138          * @return Maximum pulse width
139          */
140         int getMaxPulseWidth ();
141 
142         /**
143          * Returns the maximum PWM period width
144          *
145          * @return Maximum PWM period width
146          */
147         int getPeriod ();
148 
149     protected:
150         int calcPulseTraveling (int value);
151 
152         std::string         m_name;
153         int                 m_servoPin;
154         float               m_maxAngle;
155         mraa_pwm_context    m_pwmServoContext;
156         int                 m_currAngle;
157 
158         int                 m_minPulseWidth;
159         int                 m_maxPulseWidth;
160         int                 m_period;
161 
162         int                 m_waitAndDisablePwm;
163 
164     private:
165         void init (int pin, int minPulseWidth, int maxPulseWidth, int waitAndDisablePwm);
166 };
167 
168 }
169