1 /*
2  * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3  * Contributions: Mihai Tudor Panu <mihai.tudor.panu@intel.com>
4  * Contributions: Sarah Knepper <sarah.knepper@intel.com>
5  * Copyright (c) 2014 Intel Corporation.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining
8  * a copy of this software and associated documentation files (the
9  * "Software"), to deal in the Software without restriction, including
10  * without limitation the rights to use, copy, modify, merge, publish,
11  * distribute, sublicense, and/or sell copies of the Software, and to
12  * permit persons to whom the Software is furnished to do so, subject to
13  * the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  */
26 #pragma once
27 
28 #include <string>
29 #include <mraa/aio.hpp>
30 #include <mraa/gpio.hpp>
31 
32 #ifdef JAVACALLBACK
33 #include "../IsrCallback.h"
34 #endif
35 
36 namespace upm {
37 
38 /**
39  * @brief Generic library for basic Grove sensors
40  * @defgroup grove libupm-grove
41  * @ingroup seeed gpio pwm ainput button led light relay temp touch gsk eak hak
42  */
43 class Grove {
44     public:
~Grove()45         virtual ~Grove() {}
name()46         std::string name()
47         {
48             return m_name;
49         }
50     protected:
51         std::string m_name;
52 };
53 
54 /**
55  * @brief API for the Grove LED
56  *
57  * UPM module for the Grove LED (or other similar light-emitting diodes).
58  * An LED is a small lightbulb that emits light in
59  * response to a small current. The longer wire of an LED connects
60  * to the positive seat (anode); the shorter wire connects to the
61  * negative seat (cathode). The flat side of the bulb corresponds
62  * to the cathode, while the rounded side corresponds to the anode.
63  *
64  * @ingroup grove gpio
65  * @snippet groveled.cxx Interesting
66  * @snippet groveled-multi.cxx Interesting
67  * @image html groveled.jpg
68  */
69 class GroveLed: public Grove {
70     public:
71         /**
72          * Grove LED constructor
73          *
74          * @param gpio Pin to use
75          */
76         GroveLed(int pin);
77         /**
78          * Grove LED destructor
79          */
80         ~GroveLed();
81         /**
82          * Turns the LED on or off, depending on the value.
83          * If the value is positive (greater than or equal
84          * to 1), the LED is turned on.  Otherwise, for 0
85          * or negative values, the LED is turned off.
86          *
87          * @param value Tells the LED to turn on (for values >=1)
88          * or off (for values <1)
89          *
90          * @return 0 if successful, non-zero otherwise
91          */
92         mraa_result_t write(int value);
93         /**
94          * Turns the LED off
95          *
96          * @return 0 if successful, non-zero otherwise
97          */
98         mraa_result_t off();
99         /**
100          * Turns the LED on
101          *
102          * @return 0 if successful, non-zero otherwise
103          */
104         mraa_result_t on();
105     private:
106         mraa_gpio_context m_gpio;
107 };
108 
109 /**
110  * @brief API for the Grove Relay
111  *
112  * UPM module for the Grove relay switch. Grove relay is a
113  * digital normally-open switch that uses low voltage or current to
114  * control a higher voltage and/or higher current.  When closed,
115  * the indicator LED lights up and current is allowed to flow.
116  *
117  * @ingroup grove gpio
118  * @snippet groverelay.cxx Interesting
119  * @image html groverelay.jpg
120  */
121 class GroveRelay: public Grove {
122     public:
123         /**
124          * Grove relay constructor
125          *
126          * @param gpio Pin to use
127          */
128         GroveRelay(unsigned int pin);
129         /**
130          * Grove relay destructor
131          */
132         ~GroveRelay();
133         /**
134          * Sets the relay switch to on (closed). This allows current
135          * to flow and lights up the indicator LED.
136          *
137          * @return 0 if successful, non-zero otherwise
138          */
139         mraa_result_t on();
140         /**
141          * Sets the relay switch to off (open). This stops current
142          * from flowing and the indicator LED is not lit.
143          *
144          * @return 0 if successful, non-zero otherwise
145          */
146         mraa_result_t off();
147         /**
148          * Defines whether the relay switch is closed.
149          *
150          * @return True if the switch is on (closed), false otherwise
151          */
152         bool isOn();
153         /**
154          * Defines whether the relay switch is open.
155          *
156          * @return True if the switch is off (open), false otherwise
157          */
158         bool isOff();
159     private:
160         mraa_gpio_context m_gpio;
161 };
162 
163 /**
164  * @brief API for the Grove Temperature Sensor
165  *
166  * Basic UPM module for the Grove temperature sensor on analog
167  *
168  * @ingroup grove analog
169  * @snippet grovetemp.cxx Interesting
170  * @image html grovetemp.jpg
171  */
172 class GroveTemp: public Grove {
173     public:
174         /**
175          * Grove analog temperature sensor constructor
176          *
177          * @param pin Analog pin to use
178          */
179         GroveTemp(unsigned int pin);
180         /**
181          * GroveTemp destructor
182          */
183         ~GroveTemp();
184         /**
185          * Gets the raw value from the AIO pin
186          *
187          * @return Raw value from the ADC
188          */
189         float raw_value();
190         /**
191          * Gets the temperature in Celsius from the sensor
192          *
193          * @return Normalized temperature in Celsius
194          */
195         int value();
196     private:
197         mraa_aio_context m_aio;
198 };
199 
200 /**
201  * @brief API for the Grove Light Sensor
202  *
203  * The Grove light sensor detects the intensity of the ambient light.
204  * As the light intensity of the environment increases, the resistance
205  * of the sensor decreases. This means the raw value from the
206  * analog pin is greater in bright light and smaller in the dark.
207  * An approximate lux value can also be returned.
208  *
209  * @ingroup grove analog
210  * @snippet grovelight.cxx Interesting
211  * @image html grovelight.jpg
212  */
213 class GroveLight: public Grove {
214     public:
215         /**
216          * Grove analog light sensor constructor
217          *
218          * @param pin Analog pin to use
219          */
220         GroveLight(unsigned int pin);
221         /**
222          * GroveLight destructor
223          */
224         ~GroveLight();
225         /**
226          * Gets the raw value from the AIO pin
227          *
228          * @return Raw value from the ADC
229          */
230         float raw_value();
231         /**
232          * Gets an approximate light value, in lux, from the sensor
233          *
234          * @return Normalized light reading in lux
235          */
236         int value();
237     private:
238         mraa_aio_context m_aio;
239 };
240 
241 /**
242  * @brief API for the Grove Rotary Angle Sensor (Knob)
243  *
244  * Basic UPM module for the Grove rotary angle sensor (knob) on analog. Provides
245  * a set of functions to read the absolute pin value, degrees or radians, and another set
246  * to do the same relative to the center of the knob range.
247  *
248  * @ingroup grove analog
249  * @snippet groverotary.cxx Interesting
250  * @image html groverotary.jpeg
251  */
252 class GroveRotary: public Grove {
253     public:
254         /**
255          * Grove rotary angle sensor constructor
256          *
257          * @param pin Number of the analog pin to use
258          */
259         GroveRotary(unsigned int pin);
260         /**
261          * GroveRotary destructor
262          */
263         ~GroveRotary();
264         /**
265          * Gets the absolute raw value from the AIO pin
266          *
267          * @return Unsigned value from the ADC
268          */
269         float abs_value();
270         /**
271          * Gets absolute raw degrees from the AIO pin
272          *
273          * @return Unsigned degrees from the ADC
274          */
275         float abs_deg();
276         /**
277          * Gets absolute raw radians from the AIO pin
278          *
279          * @return Unsigned radians from the ADC
280          */
281         float abs_rad();
282         /**
283          * Gets the relative value from the AIO pin
284          *
285          * @return Signed value from the ADC
286          */
287         float rel_value();
288         /**
289          * Gets relative degrees from the AIO pin
290          *
291          * @return Signed degrees from the ADC
292          */
293         float rel_deg();
294         /**
295          * Gets relative radians from the AIO pin
296          *
297          * @return Signed radians from the ADC
298          */
299         float rel_rad();
300     private:
301         mraa_aio_context m_aio;
302         static const int m_max_angle = 300;
303 };
304 
305 /**
306  * @brief API for the Grove Slide Potentiometer
307  *
308  * Basic UPM module for the Grove slide potentiometer on analog that
309  * returns either a raw value or a scaled voltage value.
310  *
311  * @ingroup grove analog
312  * @snippet groveslide.cxx Interesting
313  * @image html groveslide.jpeg
314  */
315 class GroveSlide: public Grove {
316     public:
317         /**
318          * Grove analog slide potentiometer constructor
319          *
320          * @param pin Number of the analog pin to use
321          *
322          * @param ref_voltage Reference voltage the board is set to, as a floating-point value; default is 5.0V
323          */
324         GroveSlide(unsigned int pin, float ref_voltage = 5.0);
325         /**
326          * GroveSlide destructor
327          */
328         ~GroveSlide();
329         /**
330          * Gets the raw value from the AIO pin
331          *
332          * @return Raw value from the ADC
333          */
334         float raw_value();
335         /**
336          * Gets the voltage value from the pin
337          *
338          * @return Voltage reading based on the reference voltage
339          */
340         float voltage_value();
341         /**
342          * Gets the board's reference voltage passed on object initialization
343          *
344          * @return Reference voltage the class was set for
345          */
346         float ref_voltage();
347     private:
348         mraa_aio_context m_aio;
349         float m_ref_voltage;
350 };
351 
352 /**
353  * @brief API for the Grove Button
354  *
355  * Basic UPM module for the Grove button
356  *
357  * @ingroup grove gpio
358  * @snippet grovebutton.cxx Interesting
359  * @image html grovebutton.jpg
360  */
361 class GroveButton: public Grove {
362     public:
363         /**
364          * Grove button constructor
365          *
366          * @param gpio Pin to use
367          */
368         GroveButton(unsigned int pin);
369         /**
370          * Grove button destructor
371          */
372         ~GroveButton();
373         /**
374          * Gets the name of the sensor
375          *
376          * @return Name of this sensor
377          */
378         std::string name();
379         /**
380          * Gets the value from the GPIO pin
381          *
382          * @return Value from the GPIO pin
383          */
384         int value();
385 
386         /**
387          * Installs an interrupt service routine (ISR) to be called when
388          * the button is activated or deactivated.
389          *
390          * @param fptr Pointer to a function to be called on interrupt
391          * @param arg Pointer to an object to be supplied as an
392          * argument to the ISR.
393          */
394 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
395         void installISR(mraa::Edge level, IsrCallback *cb);
396 #else
397         void installISR(mraa::Edge level, void (*isr)(void *), void *arg);
398 #endif
399         /**
400          * Uninstalls the previously installed ISR
401          *
402          */
403         void uninstallISR();
404 
405     private:
406 #if defined(SWIGJAVA) || defined(JAVACALLBACK)
407         void installISR(mraa::Edge level, void (*isr)(void *), void *arg);
408 #endif
409         bool m_isrInstalled;
410         std::string m_name;
411         mraa_gpio_context m_gpio;
412 };
413 
414 }
415