aecd8a5c68ec642174f43f5009d8016441b527d0
[contrib/upm.git] / src / hcsr04 / hcsr04.cxx
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
25 #include <iostream>
26 #include <unistd.h>
27 #include <stdlib.h>
28 #include <functional>
29
30 #include "hcsr04.h"
31
32 using namespace upm;
33
34 HCSR04::HCSR04 (uint8_t triggerPin, uint8_t echoPin, void (*fptr)(void *)) {
35     mraa_result_t error  = MRAA_SUCCESS;
36     m_name              = "HCSR04";
37
38     m_pwmTriggerCtx     = mraa_pwm_init (triggerPin);
39     if (m_pwmTriggerCtx == NULL) {
40         std::cout << "PWM context is NULL" << std::endl;
41         exit (1);
42     }
43
44     mraa_init();
45     m_echoPinCtx = mraa_gpio_init(echoPin);
46     if (m_echoPinCtx == NULL) {
47         fprintf (stderr, "Are you sure that pin%d you requested is valid on your platform?", echoPin);
48         exit (1);
49     }
50
51     mraa_gpio_dir(m_echoPinCtx, MRAA_GPIO_IN);
52     gpio_edge_t edge = MRAA_GPIO_EDGE_BOTH;
53     mraa_gpio_isr (m_echoPinCtx, edge, fptr, NULL);
54 }
55
56 HCSR04::~HCSR04 () {
57     mraa_result_t error = MRAA_SUCCESS;
58
59     mraa_pwm_close (m_pwmTriggerCtx);
60     error = mraa_gpio_close (m_echoPinCtx);
61     if (error != MRAA_SUCCESS) {
62         mraa_result_print (error);
63     }
64 }
65
66 int
67 HCSR04::getDistance () {
68     mraa_pwm_enable (m_pwmTriggerCtx, 1);
69     mraa_pwm_period_us (m_pwmTriggerCtx, MAX_PERIOD);
70     mraa_pwm_pulsewidth_us (m_pwmTriggerCtx, TRIGGER_PULSE);
71     mraa_pwm_enable (m_pwmTriggerCtx, 0);
72
73     m_doWork = 0;
74     m_InterruptCounter = 0;
75     while (!m_doWork) {
76         sleep (1);
77     }
78
79     return m_FallingTimeStamp - m_RisingTimeStamp;
80 }
81
82 void
83 HCSR04::ackEdgeDetected () {
84     struct timeval timer;
85     gettimeofday(&timer, NULL);
86
87     ++m_InterruptCounter;
88     if (!(m_InterruptCounter % 2)) {
89         m_FallingTimeStamp  = 1000000 * timer.tv_sec + timer.tv_usec;
90         m_doWork = 1;
91     } else {
92         m_RisingTimeStamp = 1000000 * timer.tv_sec + timer.tv_usec;
93     }
94 }