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 
27 #include <iostream>
28 #include <string>
29 #include <stdexcept>
30 
31 #include "grove.h"
32 #include "math.h"
33 
34 using namespace upm;
35 
36 //// GroveLed ////
37 
GroveLed(int pin)38 GroveLed::GroveLed(int pin)
39 {
40     if ( !(m_gpio = mraa_gpio_init(pin)) ) {
41         throw std::invalid_argument(std::string(__FUNCTION__) +
42                                     ": mraa_gpio_init() failed, invalid pin?");
43         return;
44     }
45     mraa_gpio_dir(m_gpio, MRAA_GPIO_OUT);
46     m_name = "LED Socket";
47 }
48 
~GroveLed()49 GroveLed::~GroveLed()
50 {
51     mraa_gpio_close(m_gpio);
52 }
53 
write(int value)54 mraa_result_t GroveLed::write(int value)
55 {
56     if (value >= 1) {
57         return mraa_gpio_write(m_gpio, 1);
58     }
59     return mraa_gpio_write(m_gpio, 0);
60 }
61 
on()62 mraa_result_t GroveLed::on()
63 {
64     return write(1);
65 }
66 
off()67 mraa_result_t GroveLed::off()
68 {
69     return write(0);
70 }
71 
72 //// GroveRelay ////
73 
GroveRelay(unsigned int pin)74 GroveRelay::GroveRelay(unsigned int pin)
75 {
76     if ( !(m_gpio = mraa_gpio_init(pin)) ) {
77         throw std::invalid_argument(std::string(__FUNCTION__) +
78                                     ": mraa_gpio_init() failed, invalid pin?");
79         return;
80     }
81     mraa_gpio_dir(m_gpio, MRAA_GPIO_OUT);
82     m_name = "Relay Switch";
83 }
84 
~GroveRelay()85 GroveRelay::~GroveRelay()
86 {
87     mraa_gpio_close(m_gpio);
88 }
89 
on()90 mraa_result_t GroveRelay::on()
91 {
92     return mraa_gpio_write(m_gpio, 1);
93 }
94 
off()95 mraa_result_t GroveRelay::off()
96 {
97     return mraa_gpio_write(m_gpio, 0);
98 }
99 
isOn()100 bool GroveRelay::isOn()
101 {
102     return mraa_gpio_read(m_gpio) == 1;
103 }
104 
isOff()105 bool GroveRelay::isOff()
106 {
107     return mraa_gpio_read(m_gpio) == 0;
108 }
109 
110 //// GroveTemp ////
111 
GroveTemp(unsigned int pin)112 GroveTemp::GroveTemp(unsigned int pin)
113 {
114     if ( !(m_aio = mraa_aio_init(pin)) ) {
115         throw std::invalid_argument(std::string(__FUNCTION__) +
116                                     ": mraa_aio_init() failed, invalid pin?");
117         return;
118     }
119     m_name = "Temperature Sensor";
120 }
121 
~GroveTemp()122 GroveTemp::~GroveTemp()
123 {
124     mraa_aio_close(m_aio);
125 }
126 
value()127 int GroveTemp::value ()
128 {
129     int a = mraa_aio_read(m_aio);
130     float r = (float)(1023.0-a)*10000.0/a;
131     float t = 1.0/(log(r/10000.0)/3975.0 + 1.0/298.15)-273.15;
132     return (int) round(t);
133 }
134 
raw_value()135 float GroveTemp::raw_value()
136 {
137     return (float) mraa_aio_read(m_aio);
138 }
139 
140 //// GroveLight ////
141 
GroveLight(unsigned int pin)142 GroveLight::GroveLight(unsigned int pin)
143 {
144     if ( !(m_aio = mraa_aio_init(pin)) ) {
145         throw std::invalid_argument(std::string(__FUNCTION__) +
146                                     ": mraa_aio_init() failed, invalid pin?");
147         return;
148     }
149     m_name = "Light Sensor";
150 }
151 
~GroveLight()152 GroveLight::~GroveLight()
153 {
154     mraa_aio_close(m_aio);
155 }
156 
value()157 int GroveLight::value()
158 {
159     // rough conversion to lux, using formula from Grove Starter Kit booklet
160     float a = (float) mraa_aio_read(m_aio);
161     a = 10000.0/pow(((1023.0-a)*10.0/a)*15.0,4.0/3.0);
162     return (int) round(a);
163 }
164 
raw_value()165 float GroveLight::raw_value()
166 {
167     return (float) mraa_aio_read(m_aio);
168 }
169 
170 //// GroveRotary ////
171 
GroveRotary(unsigned int pin)172 GroveRotary::GroveRotary(unsigned int pin)
173 {
174     if ( !(m_aio = mraa_aio_init(pin)) ) {
175         throw std::invalid_argument(std::string(__FUNCTION__) +
176                                     ": mraa_aio_init() failed, invalid pin?");
177         return;
178     }
179     m_name = "Rotary Angle Sensor";
180 }
181 
~GroveRotary()182 GroveRotary::~GroveRotary()
183 {
184     mraa_aio_close(m_aio);
185 }
186 
abs_value()187 float GroveRotary::abs_value()
188 {
189     return (float) mraa_aio_read(m_aio);
190 }
191 
abs_deg()192 float GroveRotary::abs_deg()
193 {
194     return GroveRotary::abs_value() * (float) m_max_angle / 1023.0;
195 }
196 
abs_rad()197 float GroveRotary::abs_rad()
198 {
199     return GroveRotary::abs_deg() * M_PI / 180.0;
200 }
201 
rel_value()202 float GroveRotary::rel_value()
203 {
204     return GroveRotary::abs_value() - 512.0;
205 }
206 
rel_deg()207 float GroveRotary::rel_deg()
208 {
209     return GroveRotary::rel_value() * (float) m_max_angle / 1023.0;
210 }
211 
rel_rad()212 float GroveRotary::rel_rad()
213 {
214     return GroveRotary::rel_deg() * M_PI / 180.0;
215 }
216 
217 //// GroveSlide ////
218 
GroveSlide(unsigned int pin,float ref_voltage)219 GroveSlide::GroveSlide(unsigned int pin, float ref_voltage)
220 {
221     if ( !(m_aio = mraa_aio_init(pin)) ) {
222         throw std::invalid_argument(std::string(__FUNCTION__) +
223                                     ": mraa_aio_init() failed, invalid pin?");
224         return;
225     }
226     m_ref_voltage = ref_voltage;
227     m_name = "Slide Potentiometer";
228 }
229 
~GroveSlide()230 GroveSlide::~GroveSlide()
231 {
232     mraa_aio_close(m_aio);
233 }
234 
raw_value()235 float GroveSlide::raw_value()
236 {
237     return (float) mraa_aio_read(m_aio);
238 }
239 
voltage_value()240 float GroveSlide::voltage_value()
241 {
242     // conversion to Volts
243     float a = GroveSlide::raw_value();
244     a = m_ref_voltage * a / 1023.0 ;
245     return a;
246 }
247 
ref_voltage()248 float GroveSlide::ref_voltage()
249 {
250     return m_ref_voltage;
251 }
252 
253 //// GroveButton ////
254 
GroveButton(unsigned int pin)255 GroveButton::GroveButton(unsigned int pin)
256 {
257     if ( !(m_gpio = mraa_gpio_init(pin)) ) {
258         throw std::invalid_argument(std::string(__FUNCTION__) +
259                                     ": mraa_gpio_init() failed, invalid pin?");
260         return;
261     }
262     mraa_gpio_dir(m_gpio, MRAA_GPIO_IN);
263     m_name = "Button Sensor";
264 }
265 
~GroveButton()266 GroveButton::~GroveButton()
267 {
268     mraa_gpio_close(m_gpio);
269 }
270 
name()271 std::string GroveButton::name()
272 {
273     return m_name;
274 }
275 
value()276 int GroveButton::value()
277 {
278     return mraa_gpio_read(m_gpio);
279 }
280 
281 #ifdef JAVACALLBACK
installISR(mraa::Edge level,IsrCallback * cb)282 void GroveButton::installISR(mraa::Edge level, IsrCallback *cb)
283 {
284   installISR(level, generic_callback_isr, cb);
285 }
286 #endif
287 
installISR(mraa::Edge level,void (* isr)(void *),void * arg)288 void GroveButton::installISR(mraa::Edge level, void (*isr)(void *), void *arg)
289 {
290   if (m_isrInstalled)
291     uninstallISR();
292 
293   // install our interrupt handler
294   mraa_gpio_isr(m_gpio, (mraa_gpio_edge_t) level, isr, arg);
295   m_isrInstalled = true;
296 }
297 
uninstallISR()298 void GroveButton::uninstallISR()
299 {
300   mraa_gpio_isr_exit(m_gpio);
301   m_isrInstalled = false;
302 }
303