diff --git a/examples/c++/cjq4435.cxx b/examples/c++/cjq4435.cxx index 79d34951..fe9fd882 100644 --- a/examples/c++/cjq4435.cxx +++ b/examples/c++/cjq4435.cxx @@ -33,45 +33,45 @@ int shouldRun = true; void sig_handler(int signo) { - if (signo == SIGINT) - shouldRun = false; + if (signo == SIGINT) + shouldRun = false; } int main () { - signal(SIGINT, sig_handler); + signal(SIGINT, sig_handler); //! [Interesting] - // Instantiate a CJQ4435 MOSFET on a PWM capable digital pin D3 - upm::CJQ4435* mosfet = new upm::CJQ4435(3); - - mosfet->setPeriodMS(10); - mosfet->enable(true); + // Instantiate a CJQ4435 MOSFET on a PWM capable digital pin D3 + upm::CJQ4435* mosfet = new upm::CJQ4435(3); - while (shouldRun) + mosfet->setPeriodMS(10); + mosfet->enable(true); + + while (shouldRun) { - // start with a duty cycle of 0.0 (off) and increment to 1.0 (on) - for (float i=0.0; i <= 1.0; i+=0.1) + // start with a duty cycle of 0.0 (off) and increment to 1.0 (on) + for (float i=0.0; i <= 1.0; i+=0.1) { - mosfet->setDutyCycle(i); - usleep(100000); + mosfet->setDutyCycle(i); + usleep(100000); } - sleep(1); - // Now take it back down - // start with a duty cycle of 1.0 (on) and decrement to 0.0 (off) - for (float i=1.0; i >= 0.0; i-=0.1) + sleep(1); + // Now take it back down + // start with a duty cycle of 1.0 (on) and decrement to 0.0 (off) + for (float i=1.0; i >= 0.0; i-=0.1) { - mosfet->setDutyCycle(i); - usleep(100000); + mosfet->setDutyCycle(i); + usleep(100000); } - sleep(1); + sleep(1); } //! [Interesting] - cout << "Exiting..." << endl; + cout << "Exiting..." << endl; - delete mosfet; - return 0; + delete mosfet; + return 0; } diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index ed185585..6fd7466d 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -144,6 +144,7 @@ add_example (mb704x) add_example (mcp2515) add_example (max30100) add_example (speaker) +add_example (cjq4435) # Custom examples add_custom_example (nmea_gps_i2c-example-c nmea_gps_i2c.c nmea_gps) diff --git a/examples/c/cjq4435.c b/examples/c/cjq4435.c new file mode 100644 index 00000000..db52a1fb --- /dev/null +++ b/examples/c/cjq4435.c @@ -0,0 +1,82 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2017 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include +#include "cjq4435.h" + +int shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + + +int main () +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + // Instantiate a CJQ4435 MOSFET on a PWM capable digital pin D3 + cjq4435_context mosfet = cjq4435_init(3); + + if (!mosfet) + { + printf("cjq4435_init() failed.\n"); + return 1; + } + + cjq4435_set_period_ms(mosfet, 10); + cjq4435_enable(mosfet, true); + + while (shouldRun) + { + // start with a duty cycle of 0.0 (off) and increment to 1.0 (on) + for (float i=0.0; i <= 1.0; i+=0.1) + { + cjq4435_set_duty_cycle(mosfet, i); + upm_delay_ms(100); + } + upm_delay(1); + + // Now bring it back down + // start with a duty cycle of 1.0 (on) and decrement to 0.0 (off) + for (float i=1.0; i >= 0.0; i-=0.1) + { + cjq4435_set_duty_cycle(mosfet, i); + upm_delay_ms(100); + } + upm_delay(1); + } + + printf("Exiting...\n"); + + cjq4435_close(mosfet); +//! [Interesting] + return 0; +} diff --git a/src/cjq4435/CMakeLists.txt b/src/cjq4435/CMakeLists.txt index 99ad396d..394317eb 100644 --- a/src/cjq4435/CMakeLists.txt +++ b/src/cjq4435/CMakeLists.txt @@ -1,5 +1,8 @@ -set (libname "cjq4435") -set (libdescription "Cjq4435 MOSFET module") -set (module_src ${libname}.cxx) -set (module_hpp ${libname}.hpp) -upm_module_init() +upm_mixed_module_init (NAME cjq4435 + DESCRIPTION "MOSFET module" + C_HDR cjq4435.h + C_SRC cjq4435.c + CPP_HDR cjq4435.hpp + CPP_SRC cjq4435.cxx + CPP_WRAPS_C + REQUIRES upmc-utilities mraa) diff --git a/src/cjq4435/cjq4435.c b/src/cjq4435/cjq4435.c new file mode 100644 index 00000000..140b1268 --- /dev/null +++ b/src/cjq4435/cjq4435.c @@ -0,0 +1,174 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2017 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include + +#include "cjq4435.h" + + +cjq4435_context cjq4435_init(int pin) +{ + // make sure MRAA is initialized + int mraa_rv; + if ((mraa_rv = mraa_init()) != MRAA_SUCCESS) + { + printf("%s: mraa_init() failed (%d).\n", __FUNCTION__, mraa_rv); + return NULL; + } + + cjq4435_context dev = + (cjq4435_context)malloc(sizeof(struct _cjq4435_context)); + + if (!dev) + return NULL; + + // zero out context + memset((void *)dev, 0, sizeof(struct _cjq4435_context)); + + if ( !(dev->pwm = mraa_pwm_init(pin)) ) + { + printf("%s: mraa_pwm_init() failed.\n", __FUNCTION__); + + cjq4435_close(dev); + return NULL; + } + + dev->enabled = false; + + return dev; +} + +void cjq4435_close(const cjq4435_context dev) +{ + assert(dev != NULL); + + if (dev->pwm) + { + if (dev->enabled) + mraa_pwm_enable(dev->pwm, 0); + + mraa_pwm_close(dev->pwm); + } + + free(dev); +} + +upm_result_t cjq4435_set_period_us(const cjq4435_context dev, int us) +{ + assert(dev != NULL); + + if (mraa_pwm_period_us(dev->pwm, us)) + { + printf("%s: period specified is not supported\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +upm_result_t cjq4435_set_period_ms(const cjq4435_context dev, int ms) +{ + assert(dev != NULL); + + if (mraa_pwm_period_ms(dev->pwm, ms)) + { + printf("%s: period specified is not supported\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +upm_result_t cjq4435_set_period_seconds(const cjq4435_context dev, + float seconds) +{ + assert(dev != NULL); + + if (mraa_pwm_period(dev->pwm, seconds)) + { + printf("%s: period specified is not supported\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +upm_result_t cjq4435_enable(const cjq4435_context dev, bool enable) +{ + assert(dev != NULL); + + dev->enabled = enable; + if (mraa_pwm_enable(dev->pwm, ((enable) ? 1 : 0))) + { + printf("%s: mraa_pwm_enable() failed\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +upm_result_t cjq4435_set_duty_cycle(const cjq4435_context dev, + float dutyCycle) +{ + assert(dev != NULL); + + if (dutyCycle < 0.0) + dutyCycle = 0.0; + + if (dutyCycle > 1.0) + dutyCycle = 1.0; + + if (mraa_pwm_write(dev->pwm, dutyCycle)) + { + printf("%s: mraa_pwm_write() failed\n", __FUNCTION__); + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +void cjq4435_on(const cjq4435_context dev) +{ + assert(dev != NULL); + + // set a 1 millisecond period, with 100% duty cycle + + cjq4435_enable(dev, false); + cjq4435_set_period_us(dev, 1000); + cjq4435_set_duty_cycle(dev, 1.0); + cjq4435_enable(dev, true); +} + +void cjq4435_off(const cjq4435_context dev) +{ + assert(dev != NULL); + + // set a 1 millisecond period, with 100% duty cycle + + cjq4435_enable(dev, false); + cjq4435_set_period_us(dev, 1000); + cjq4435_set_duty_cycle(dev, 0.0); + cjq4435_enable(dev, true); +} diff --git a/src/cjq4435/cjq4435.cxx b/src/cjq4435/cjq4435.cxx index d730624c..0e04e726 100644 --- a/src/cjq4435/cjq4435.cxx +++ b/src/cjq4435/cjq4435.cxx @@ -1,6 +1,6 @@ /* * Author: Jon Trulson - * Copyright (c) 2015 Intel Corporation. + * Copyright (c) 2015-2017 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -31,81 +31,61 @@ using namespace upm; using namespace std; -CJQ4435::CJQ4435(int pin) +CJQ4435::CJQ4435(int pin) : + m_cjq4435(cjq4435_init(pin)) { - if ( !(m_pwm = mraa_pwm_init(pin)) ) - { - throw std::invalid_argument(std::string(__FUNCTION__) + - ": mraa_pwm_init() failed, invalid pin?"); - return; - } - - m_enabled = false; + if (!m_cjq4435) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_init() failed"); } CJQ4435::~CJQ4435() { - if (m_enabled) - mraa_pwm_enable(m_pwm, 0); - - mraa_pwm_close(m_pwm); + cjq4435_close(m_cjq4435); } void CJQ4435::setPeriodUS(int us) { - if (mraa_pwm_period_us(m_pwm, us) != MRAA_SUCCESS) - cerr << __FUNCTION__ << ": period specified is not supported" - << endl; + if (cjq4435_set_period_us(m_cjq4435, us)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_set_period_us() failed"); } void CJQ4435::setPeriodMS(int ms) { - if (mraa_pwm_period_ms(m_pwm, ms) != MRAA_SUCCESS) - cerr << __FUNCTION__ << ": period specified is not supported" - << endl; + if (cjq4435_set_period_ms(m_cjq4435, ms)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_set_period_ms() failed"); } void CJQ4435::setPeriodSeconds(float seconds) { - if (mraa_pwm_period(m_pwm, seconds) != MRAA_SUCCESS) - cerr << __FUNCTION__ << ": period specified is not supported" - << endl; + if (cjq4435_set_period_seconds(m_cjq4435, seconds)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_set_period_seconds() failed"); } void CJQ4435::enable(bool enable) { - m_enabled = enable; - mraa_pwm_enable(m_pwm, ((enable) ? 1 : 0)); + if (cjq4435_enable(m_cjq4435, enable)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_enable() failed"); } void CJQ4435::setDutyCycle(float dutyCycle) { - if (dutyCycle < 0.0) - dutyCycle = 0.0; - - if (dutyCycle > 1.0) - dutyCycle = 1.0; - - mraa_pwm_write(m_pwm, dutyCycle); + if (cjq4435_set_duty_cycle(m_cjq4435, dutyCycle)) + throw std::runtime_error(std::string(__FUNCTION__) + + ": cjq4435_set_duty_cycle() failed"); } void CJQ4435::on() { - // set a 1 second period, with 100% duty cycle - - enable(false); - setPeriodUS(1000); - setDutyCycle(1.0); - enable(true); + cjq4435_on(m_cjq4435); } void CJQ4435::off() { - // set a 1 second period, with 0% duty cycle - - enable(false); - setPeriodUS(1000); - setDutyCycle(0.0); - enable(true); + cjq4435_off(m_cjq4435); } diff --git a/src/cjq4435/cjq4435.h b/src/cjq4435/cjq4435.h new file mode 100644 index 00000000..fdc32cc6 --- /dev/null +++ b/src/cjq4435/cjq4435.h @@ -0,0 +1,136 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2017 Intel Corporation. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#pragma once + +#include +#include +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * @file cjq4435.h + * @library cjq4435 + * @brief API CJQ4435 MOSFET + * + * @include cjq4435.c + */ + + /** + * Device context + */ + typedef struct _cjq4435_context { + mraa_pwm_context pwm; + + bool enabled; + } *cjq4435_context; + + /** + * CJQ4435 initializer + * + * @param pin Digital pin to use; this pin must be PWM-capable + * @return Initialized device context, or NULL on error. + */ + cjq4435_context cjq4435_init(int pin); + + /** + * CJQ4435 destructor + * + * @param dev Device context + */ + void cjq4435_close(cjq4435_context dev); + + /** + * Sets a period in microseconds + * + * @param dev Device context + * @param us Period in microseconds + * @return UPM result + */ + upm_result_t cjq4435_set_period_us(const cjq4435_context dev, int us); + + /** + * Sets a period in milliseconds + * + * @param dev Device context + * @param ms Period in milliseconds + * @return UPM result + */ + upm_result_t cjq4435_set_period_ms(const cjq4435_context dev, int us); + + /** + * Sets a period in seconds + * + * @param dev Device context + * @param seconds Period in seconds + * @return UPM result + */ + upm_result_t cjq4435_set_period_seconds(const cjq4435_context dev, + float seconds); + + /** + * Enables output + * + * @param dev Device context + * @param enable Enables PWM output if true, disables otherwise + * @return UPM result + */ + upm_result_t cjq4435_enable(const cjq4435_context dev, bool enable); + + /** + * Sets a duty cycle. Duty cycle is a floating-point number + * between 0.0 (always off) and 1.0 (always on). It represents a + * proportion of time, per period, during which the output is + * driven high. + * + * @param dev Device context + * @param dutyCycle Duty cycle to use + * @return UPM result + */ + upm_result_t cjq4435_set_duty_cycle(const cjq4435_context dev, + float dutyCycle); + + /** + * Shortcut to turn the output to continuous on (high) + * + * @param dev Device context + */ + void cjq4435_on(const cjq4435_context dev); + + /** + * Shortcut to turn the output to continuous off (low) + * + * @param dev Device context + */ + void cjq4435_off(const cjq4435_context dev); + + +#ifdef __cplusplus +} +#endif diff --git a/src/cjq4435/cjq4435.hpp b/src/cjq4435/cjq4435.hpp index 025cafc4..955c35d1 100644 --- a/src/cjq4435/cjq4435.hpp +++ b/src/cjq4435/cjq4435.hpp @@ -1,6 +1,6 @@ /* * Author: Jon Trulson - * Copyright (c) 2015 Intel Corporation. + * Copyright (c) 2015-2017 Intel Corporation. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -23,103 +23,104 @@ */ #pragma once -#include +#include "cjq4435.h" namespace upm { - /** - * @brief CJQ4435 MOSFET library - * @defgroup cjq4435 libupm-cjq4435 - * @ingroup seeed gpio pwm electric robok - */ - - /** - * @library cjq4435 - * @sensor cjq4435 - * @comname Grove MOSFET - * @altname CJQ4435 - * @type electric - * @man seeed - * @con gpio pwm - * @kit robok - * - * @brief API for the CJQ4435 MOSFET - * - * UPM module for the CJQ4435 MOSFET. It was developed using the - * Grove MOSFET module. A MOSFET is like a switch, but it can - * switch much faster than a mechanical relay. Here, we implement - * support via MRAA pulse width modulation (PWM) functions. - * Note: available periods vary depending on - * the capabilities of your device. - * - * @image html cjq4435.jpg - * @snippet cjq4435.cxx Interesting - */ - class CJQ4435 { - public: /** - * CJQ4435 constructor + * @brief CJQ4435 MOSFET library + * @defgroup cjq4435 libupm-cjq4435 + * @ingroup seeed gpio pwm electric robok + */ + + /** + * @library cjq4435 + * @sensor cjq4435 + * @comname Grove MOSFET + * @altname CJQ4435 + * @type electric + * @man seeed + * @con gpio pwm + * @kit robok * - * @param pin Digital pin to use; this pin must be PWM-capable - */ - CJQ4435(int pin); - - /** - * CJQ4435 destructor - */ - ~CJQ4435(); - - /** - * Sets a period in microseconds + * @brief API for the CJQ4435 MOSFET * - * @param us Period in microseconds - */ - void setPeriodUS(int us); - - /** - * Sets a period in milliseconds + * UPM module for the CJQ4435 MOSFET. It was developed using the + * Grove MOSFET module, but could be used with any MOSFET. A + * MOSFET is like a switch, but it can switch much faster than a + * mechanical relay. Here, we implement support via MRAA pulse + * width modulation (PWM) functions. Note: available periods vary + * depending on the capabilities of your platform. * - * @param ms Period in milliseconds + * @image html cjq4435.jpg + * @snippet cjq4435.cxx Interesting */ - void setPeriodMS(int ms); + class CJQ4435 { + public: + /** + * CJQ4435 constructor + * + * @param pin Digital pin to use; this pin must be PWM-capable + */ + CJQ4435(int pin); - /** - * Sets a period in seconds - * - * @param seconds Period in seconds - */ - void setPeriodSeconds(float seconds); + /** + * CJQ4435 destructor + */ + ~CJQ4435(); - /** - * Enables output - * - * @param enable Enables PWM output if true, disables otherwise - */ - void enable(bool enable); + /** + * Sets a period in microseconds + * + * @param us Period in microseconds + */ + void setPeriodUS(int us); - /** - * Sets a duty cycle. Duty cycle is a floating-point number - * between 0.0 (always off) and 1.0 (always on). It represents a - * proportion of time, per period, during which the output is - * driven high. - * - * @param dutyCycle Duty cycle to use - */ - void setDutyCycle(float dutyCycle); + /** + * Sets a period in milliseconds + * + * @param ms Period in milliseconds + */ + void setPeriodMS(int ms); - /** - * Shortcut to turn the output to continuous on (high) - */ - void on(); + /** + * Sets a period in seconds + * + * @param seconds Period in seconds + */ + void setPeriodSeconds(float seconds); - /** - * Shortcut to turn the output to continuous off (low) - */ - void off(); + /** + * Enables output + * + * @param enable Enables PWM output if true, disables otherwise + */ + void enable(bool enable); - private: - bool m_enabled; - mraa_pwm_context m_pwm; - }; + /** + * Sets a duty cycle. Duty cycle is a floating-point number + * between 0.0 (always off) and 1.0 (always on). It represents a + * proportion of time, per period, during which the output is + * driven high. + * + * @param dutyCycle Duty cycle to use + */ + void setDutyCycle(float dutyCycle); + + /** + * Shortcut to turn the output to continuous on (high) + */ + void on(); + + /** + * Shortcut to turn the output to continuous off (low) + */ + void off(); + + protected: + cjq4435_context m_cjq4435; + + private: + }; }