diff --git a/examples/c++/CMakeLists.txt b/examples/c++/CMakeLists.txt index 80320315..a76f3a0d 100644 --- a/examples/c++/CMakeLists.txt +++ b/examples/c++/CMakeLists.txt @@ -276,6 +276,7 @@ add_example (bmx055) add_example (ms5611) add_example (vk2828u7) add_example (mma7361) +add_example (bh1750) # These are special cases where you specify example binary, source file and module(s) include_directories (${PROJECT_SOURCE_DIR}/src) diff --git a/examples/c++/bh1750.cxx b/examples/c++/bh1750.cxx new file mode 100644 index 00000000..fb804605 --- /dev/null +++ b/examples/c++/bh1750.cxx @@ -0,0 +1,65 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2015 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 "bh1750.hpp" + +using namespace std; + +bool shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + + // Instantiate a BH1750 sensor using defaults (I2C bus (0), using + // the default I2C address (0x23), and setting the mode to highest + // resolution, lowest power mode). + upm::BH1750 *sensor = new upm::BH1750(); + + // Every second, sample the BH1750 and output the measured lux value + + while (shouldRun) + { + cout << "Detected Light Level (lux): " << sensor->getLux() << endl; + sleep(1); + } + +//! [Interesting] + + cout << "Exiting" << endl; + + delete sensor; + return 0; +} diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 36f43448..82d7de75 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -89,3 +89,4 @@ link_directories (${MRAA_LIBDIR}) add_example (dfrph) add_example (vk2828u7) add_example (mma7361) +add_example (bh1750) diff --git a/examples/c/bh1750.c b/examples/c/bh1750.c new file mode 100644 index 00000000..ce0b8a50 --- /dev/null +++ b/examples/c/bh1750.c @@ -0,0 +1,75 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "bh1750.h" + +bool shouldRun = true; + +void sig_handler(int signo) +{ + if (signo == SIGINT) + shouldRun = false; +} + +int main() +{ + signal(SIGINT, sig_handler); + +//! [Interesting] + + // Instantiate a BH1750 sensor on default I2C bus (0), using the + // default I2C address (0x23), and setting the mode to highest + // resolution, lowest power mode. + bh1750_context sensor = bh1750_init(BH1750_DEFAULT_I2C_BUS, + BH1750_DEFAULT_I2C_ADDR, + BH1750_OPMODE_H2_ONCE); + + if (!sensor) + { + printf("bh1750_init() failed.\n"); + return 1; + } + + // Every second, sample the BH1750 and output the measured lux value + + while (shouldRun) + { + float lux; + + bh1750_get_lux(sensor, &lux); + printf("Detected Light Level (lux): %f\n", lux); + sleep(1); + } + +//! [Interesting] + + printf("Exiting\n"); + + bh1750_close(sensor); + + return 0; +} diff --git a/examples/java/BH1750_Example.java b/examples/java/BH1750_Example.java new file mode 100644 index 00000000..47d235e5 --- /dev/null +++ b/examples/java/BH1750_Example.java @@ -0,0 +1,52 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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. + */ + +import upm_bh1750.BH1750; + +public class BH1750_Example +{ + public static void main(String[] args) throws InterruptedException + { +// ! [Interesting] + System.out.println("Initializing..."); + + // Instantiate a BH1750 sensor using defaults (I2C bus (0), using + // the default I2C address (0x23), and setting the mode to highest + // resolution, lowest power mode). + BH1750 sensor = new BH1750(); + + // Every second, sample the BH1750 and output the measured lux + // value + + while (true) + { + System.out.println("Detected Light Level (lux): " + + sensor.getLux()); + + Thread.sleep(1000); + } + +// ! [Interesting] + } +} diff --git a/examples/java/CMakeLists.txt b/examples/java/CMakeLists.txt index 21e1e177..ef87f8b9 100644 --- a/examples/java/CMakeLists.txt +++ b/examples/java/CMakeLists.txt @@ -133,6 +133,7 @@ add_example(BNO055_Example bno055) add_example(BMX055_Example bmx055) add_example(VK2828U7_Example vk2828u7) add_example(MMA7361_Example mma7361) +add_example(BH1750_Example bh1750) add_example_with_path(Jhd1313m1_lcdSample lcd i2clcd) add_example_with_path(Jhd1313m1Sample lcd i2clcd) diff --git a/examples/javascript/bh1750.js b/examples/javascript/bh1750.js new file mode 100644 index 00000000..483eee6d --- /dev/null +++ b/examples/javascript/bh1750.js @@ -0,0 +1,51 @@ +/*jslint node:true, vars:true, bitwise:true, unparam:true */ +/*jshint unused:true */ + +/* + * Author: Jon Trulson + * Copyright (c) 2016 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. + */ + +var sensorObj = require('jsupm_bh1750'); + +// Instantiate a BH1750 sensor using defaults (I2C bus (0), using +// the default I2C address (0x23), and setting the mode to highest +// resolution, lowest power mode). +var sensor = new sensorObj.BH1750(); + +// Every second, sample the BH1750 and output the measured lux value + +setInterval(function() +{ + console.log("Detected Light Level (lux): " + sensor.getLux()); +}, 1000); + +// exit on ^C +process.on('SIGINT', function() +{ + sensor = null; + sensorObj.cleanUp(); + sensorObj = null; + console.log("Exiting."); + process.exit(0); +}); + diff --git a/examples/python/bh1750.py b/examples/python/bh1750.py new file mode 100644 index 00000000..ca680e98 --- /dev/null +++ b/examples/python/bh1750.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# Author: Jon Trulson +# Copyright (c) 2016 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. + +import time, sys, signal, atexit +import pyupm_bh1750 as sensorObj + +# Instantiate a BH1750 sensor using defaults (I2C bus (0), using +# the default I2C address (0x23), and setting the mode to highest +# resolution, lowest power mode). +sensor = sensorObj.BH1750() + +## Exit handlers ## +# This function stops python from printing a stacktrace when you hit control-C +def SIGINTHandler(signum, frame): + raise SystemExit + +# This function lets you run code on exit +def exitHandler(): + print "Exiting" + sys.exit(0) + +# Register exit handlers +atexit.register(exitHandler) +signal.signal(signal.SIGINT, SIGINTHandler) + +# Every second, sample the BH1750 and output the measured lux value + +while (True): + print "Detected Light Level (lux):", sensor.getLux() + time.sleep(1) diff --git a/src/bh1750/CMakeLists.txt b/src/bh1750/CMakeLists.txt new file mode 100644 index 00000000..6fdf7eee --- /dev/null +++ b/src/bh1750/CMakeLists.txt @@ -0,0 +1,9 @@ +upm_mixed_module_init (NAME bh1750 + DESCRIPTION "upm dfrobot BH1750 I2C Digital Light Sensor" + C_HDR bh1750.h + C_SRC bh1750.c + CPP_HDR bh1750.hpp + CPP_SRC bh1750.cxx + FTI_SRC bh1750_fti.c + CPP_WRAPS_C + REQUIRES upmc-utilities mraa) diff --git a/src/bh1750/bh1750.c b/src/bh1750/bh1750.c new file mode 100644 index 00000000..70eee2b0 --- /dev/null +++ b/src/bh1750/bh1750.c @@ -0,0 +1,298 @@ +/* + * Authors: Jon Trulson + * Copyright (c) 2016 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 "bh1750.h" + +bh1750_context bh1750_init(int bus, uint8_t addr, BH1750_OPMODES_T mode) +{ + bh1750_context dev = + (bh1750_context)malloc(sizeof(struct _bh1750_context)); + + if (!dev) + { + printf("%s: context allocation failed.\n", __FUNCTION__); + + return NULL; + } + + dev->bus = bus; + dev->is_continuous = false; + + // init the i2c context + if (!(dev->i2c = mraa_i2c_init(dev->bus))) + { + printf("%s: mraa_i2c_init failed.\n", __FUNCTION__); + free(dev); + + return NULL; + } + + // now check the address... + if (mraa_i2c_address(dev->i2c, addr) != MRAA_SUCCESS) + { + printf("%s: mraa_i2c_address failed.\n", __FUNCTION__); + + bh1750_close(dev); + + return NULL; + } + + // set the mode + if (bh1750_set_opmode(dev, mode) != UPM_SUCCESS) + { + printf("%s: bh1750_set_mode failed.\n", __FUNCTION__); + + bh1750_close(dev); + + return NULL; + } + + return dev; +} + +void bh1750_close(const bh1750_context dev) +{ + assert(dev != NULL); + + if (dev->i2c) + mraa_i2c_stop(dev->i2c); + + free(dev); +} + +upm_result_t bh1750_get_lux(const bh1750_context dev, float* lux) +{ + assert(dev != NULL); + + // from the datasheet, page 7 + static const float coeff = 1.2; + + uint16_t raw_lux = 0; + + upm_result_t rv; + if ((rv = bh1750_read_data(dev, &raw_lux)) != UPM_SUCCESS) + { + printf("%s: bh1750_read_data failed.\n", __FUNCTION__); + + return rv; + } + + *lux = (float)raw_lux; + *lux /= coeff; + + return rv; +} + +bool bh1750_power_up(const bh1750_context dev) +{ + assert(dev != NULL); + + if (bh1750_send_command(dev, BH1750_CMD_POWER_UP)) + { + printf("%s: bh1750_send_command failed.\n", __FUNCTION__); + + return false; + } + + return true; +} + +bool bh1750_power_down(const bh1750_context dev) +{ + assert(dev != NULL); + + if (bh1750_send_command(dev, BH1750_CMD_POWER_DOWN)) + { + printf("%s: bh1750_send_command failed.\n", __FUNCTION__); + + return false; + } + + return true; +} + +bool bh1750_reset(const bh1750_context dev) +{ + assert(dev != NULL); + + if (bh1750_send_command(dev, BH1750_CMD_RESET)) + { + printf("%s: bh1750_send_command failed.\n", __FUNCTION__); + + return false; + } + + return true; +} + +upm_result_t bh1750_send_command(const bh1750_context dev, uint8_t cmd) +{ + assert(dev != NULL); + + if (mraa_i2c_write_byte(dev->i2c, cmd)) + { + printf("%s: mraa_i2c_write_byte failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + + return UPM_SUCCESS; +} + +upm_result_t bh1750_read_data(const bh1750_context dev, uint16_t* data) +{ + assert(dev != NULL); + + // if we are in a non-continuous mode, we need to power up the + // device and send the measurement mode command we are interested + // in. After the measurement has been read, the device will then + // power down again. + + if (!dev->is_continuous) + { + // power up + if (!bh1750_power_up(dev)) + { + printf("%s: bh1750_power_up failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + + // send the command, and delay appropriately + if (bh1750_send_command(dev, dev->opmode)) + { + printf("%s: bh1750_send_command failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + + upm_delay_ms(dev->delayms); + } + + // now get our data... + const int num_bytes = 2; + uint8_t bytes[num_bytes]; + + int bytes_read = 0; + if ((bytes_read = mraa_i2c_read(dev->i2c, bytes, num_bytes)) != num_bytes) + { + printf("%s: mraa_i2c_read failed.\n", __FUNCTION__); + + return UPM_ERROR_NO_DATA; + } + + // uncompensated, raw data + *data = (bytes[0] << 8) | bytes[1]; + + return UPM_SUCCESS; +} + +upm_result_t bh1750_set_opmode(const bh1750_context dev, + BH1750_OPMODES_T mode) +{ + assert(dev != NULL); + + switch(mode) + { + case BH1750_OPMODE_H1_CONT: + dev->is_continuous = true; + dev->delayms = BH1750_MAX_MEAS_TIME_H; + dev->opmode = BH1750_CMD_CONT_H_RES_MODE1; + break; + + case BH1750_OPMODE_H2_CONT: + dev->is_continuous = true; + dev->delayms = BH1750_MAX_MEAS_TIME_H; + dev->opmode = BH1750_CMD_CONT_H_RES_MODE2; + break; + + case BH1750_OPMODE_H1_ONCE: + dev->is_continuous = false; + dev->delayms = BH1750_MAX_MEAS_TIME_H; + dev->opmode = BH1750_CMD_ONETIME_H_RES_MODE1; + break; + + case BH1750_OPMODE_H2_ONCE: + dev->is_continuous = false; + dev->delayms = BH1750_MAX_MEAS_TIME_H; + dev->opmode = BH1750_CMD_ONETIME_H_RES_MODE2; + break; + + case BH1750_OPMODE_L_CONT: + dev->is_continuous = true; + dev->delayms = BH1750_MAX_MEAS_TIME_L; + dev->opmode = BH1750_CMD_CONT_L_RES_MODE; + break; + + case BH1750_OPMODE_L_ONCE: + dev->is_continuous = false; + dev->delayms = BH1750_MAX_MEAS_TIME_L; + dev->opmode = BH1750_CMD_ONETIME_L_RES_MODE; + break; + + default: + printf("%s: Invalid mode.\n", __FUNCTION__); + return UPM_ERROR_INVALID_PARAMETER; + } + + // If we are in a continuous mode, power on the device and start + // measuring. + + if (dev->is_continuous) + { + if (!bh1750_power_up(dev)) + { + printf("%s: bh1750_power_up failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + + if (bh1750_send_command(dev, dev->opmode)) + { + printf("%s: bh1750_send_command failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + + upm_delay_ms(dev->delayms); + } + else + { + // if we are not in a continuous mode, power the device off + if (!bh1750_power_down(dev)) + { + printf("%s: bh1750_power_down failed.\n", __FUNCTION__); + + return UPM_ERROR_OPERATION_FAILED; + } + } + + return UPM_SUCCESS; +} + + + diff --git a/src/bh1750/bh1750.cxx b/src/bh1750/bh1750.cxx new file mode 100644 index 00000000..112e2f6c --- /dev/null +++ b/src/bh1750/bh1750.cxx @@ -0,0 +1,99 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 "bh1750.hpp" + +using namespace upm; +using namespace std; + +BH1750::BH1750(int bus, int addr, BH1750_OPMODES_T mode) : + m_bh1750(bh1750_init(bus, addr, mode)) +{ + if (!m_bh1750) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_init() failed"); +} + +BH1750::~BH1750() +{ + bh1750_close(m_bh1750); +} + +void BH1750::reset() +{ + bh1750_reset(m_bh1750); +} + +float BH1750::getLux() +{ + float lux = 0.0; + + if (bh1750_get_lux(m_bh1750, &lux) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_get_lux() failed"); + + return lux; +} + +void BH1750::powerUp() +{ + if (bh1750_power_up(m_bh1750) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_power_up() failed"); +} + +void BH1750::powerDown() +{ + if (bh1750_power_down(m_bh1750) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_power_down() failed"); +} + +void BH1750::setOpmode(BH1750_OPMODES_T mode) +{ + if (bh1750_set_opmode(m_bh1750, mode) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_set_opmode() failed"); +} + +void BH1750::sendCommand(uint8_t cmd) +{ + if (bh1750_send_command(m_bh1750, cmd) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_send_command() failed"); +} + +uint16_t BH1750::readData() +{ + uint16_t data = 0; + + if (bh1750_read_data(m_bh1750, &data) != UPM_SUCCESS) + throw std::runtime_error(string(__FUNCTION__) + + ": bh1750_read_data() failed"); + + return data; +} diff --git a/src/bh1750/bh1750.h b/src/bh1750/bh1750.h new file mode 100644 index 00000000..9d04df0f --- /dev/null +++ b/src/bh1750/bh1750.h @@ -0,0 +1,181 @@ +/* + * Authors: Jon Trulson + * Copyright (c) 2016 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 "mraa/i2c.h" + +#include "upm.h" +#include "upm_types.h" + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * @brief UPM C API for the DFRobot I2C BH1750 Light Sensor + * + * This driver was developed with the DFRobot Light Sensor based on + * the BH1750. It has a sensitivity of .5 10 65535 Lux. It supports + * voltages from 3-5vdc and is connected via I2C. + * + * @snippet bh1750.c Interesting + */ + +#define BH1750_DEFAULT_I2C_BUS 0 +#define BH1750_DEFAULT_I2C_ADDR 0x23 + +// BH1750 commands + +#define BH1750_CMD_POWER_DOWN 0x00 +#define BH1750_CMD_POWER_UP 0x01 + +#define BH1750_CMD_RESET 0x07 + +// continuous modes +#define BH1750_CMD_CONT_H_RES_MODE1 0x10 // 1 lx resolution +#define BH1750_CMD_CONT_H_RES_MODE2 0x11 // .5 lx resolution +#define BH1750_CMD_CONT_L_RES_MODE 0x13 // 4 lx resolution + +// one-time modes +#define BH1750_CMD_ONETIME_H_RES_MODE1 0x20 +#define BH1750_CMD_ONETIME_H_RES_MODE2 0x21 +#define BH1750_CMD_ONETIME_L_RES_MODE 0x23 + +// max measurement time in ms (for H modes) +#define BH1750_MAX_MEAS_TIME_H 180 + +// max measurement time in ms (for L modes) +#define BH1750_MAX_MEAS_TIME_L 30 + +// an enum for the operating mode to pass to init +typedef enum { + BH1750_OPMODE_H1_CONT, // continuous 1 lx high resolution + BH1750_OPMODE_H2_CONT, // continuous .5 lx high resolution + BH1750_OPMODE_L_CONT, // continuous 4 lx low resolution + BH1750_OPMODE_H1_ONCE, // onetime 1 lx high resolution + BH1750_OPMODE_H2_ONCE, // onetime .5 lx high resolution + BH1750_OPMODE_L_ONCE, // onetime 4 lx low resolution +} BH1750_OPMODES_T; + +/** + * device context + */ +typedef struct _bh1750_context +{ + int bus; + mraa_i2c_context i2c; + + // these are set by bh1750_set_opmode() + uint8_t opmode; + bool is_continuous; + int delayms; +} *bh1750_context; + +/** + * Initialize the BH1750 + * + * @param bus I2C bus + * @param addr I2C address + * @param mode operating mode, one of the BH1750_OPMODES_T values + * @return bh1750_context for the new device context + */ +bh1750_context bh1750_init(int bus, uint8_t addr, BH1750_OPMODES_T mode); + +/** + * Sensor destructor function. Frees any allocated resources. + * + * @param dev The device context + */ +void bh1750_close(const bh1750_context dev); + +/** + * Gets the Lux value. + * + * @param dev The device context + * @param lux float pointer in which to store the lux value + * @return upm_result_t UPM success/error code + */ +upm_result_t bh1750_get_lux(const bh1750_context dev, float* lux); + +/** + * Power up the device. + * + * @param dev The device context + * @return true if the command was successful, false otherwise + */ +bool bh1750_power_up(const bh1750_context dev); + +/** + * Power down the device. + * + * @param dev The device context + * @return true if the command was successful, false otherwise + */ +bool bh1750_power_down(const bh1750_context dev); + +/** + * Reset the device. This doesn't really have much purpose. The + * device must be powered up for this command to work. In addition, + * this command will simply clear the measurement register to 0. + * + * @param dev The device context + * @return true if the command was successful, false otherwise + */ +bool bh1750_reset(const bh1750_context dev); + +/** + * Write a command to the device via I2C. + * + * @param dev The device context + * @param cmd The command to write, one of the BH1750_CMD* values + * @return upm_result_t UPM success/error code + */ +upm_result_t bh1750_send_command(const bh1750_context dev, uint8_t cmd); + +/** + * Read the 2 result bytes from the device via I2C. + * + * @param dev The device context + * @param data Data read in from the device as a uint16_t + * @return upm_result_t UPM success/error code + */ +upm_result_t bh1750_read_data(const bh1750_context dev, uint16_t* data); + +/** + * Setup the device context parameters and the device to match the + * selected operating mode. + * + * @param dev The device context + * @param mode operating mode, one of the BH1750_OPMODES_T values + * @return upm_result_t UPM success/error code + */ +upm_result_t bh1750_set_opmode(const bh1750_context dev, + BH1750_OPMODES_T mode); + +#ifdef __cplusplus +} +#endif // __cplusplus diff --git a/src/bh1750/bh1750.hpp b/src/bh1750/bh1750.hpp new file mode 100644 index 00000000..0014b4cc --- /dev/null +++ b/src/bh1750/bh1750.hpp @@ -0,0 +1,134 @@ +/* + * Author: Jon Trulson + * Copyright (c) 2016 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 + +#include "bh1750.h" + +namespace upm { + /** + * @brief DFRobot Light Sensor (BH1750) + * @defgroup bh1750 libupm-bh1750 + * @ingroup dfrobot i2c + */ + + /** + * @library bh1750 + * @sensor bh1750 + * @comname DFRobot Light Sensor + * @type light + * @man dfrobot + * @con i2c + * @web http://www.dfrobot.com/index.php?route=product/product&product_id=531 + * + * @brief UPM C API for the DFRobot I2C BH1750 Light Sensor + * + * This driver was developed with the DFRobot Light Sensor based on + * the BH1750. It has a sensitivity of .5 10 65535 Lux. It supports + * voltages from 3-5vdc and is connected via I2C. + * + * @snippet bh1750.cxx Interesting + */ + + class BH1750 { + public: + + /** + * BH1750 object constructor (Analog mode) + * + * @param bus The I2C bus to use + * @param addr The I2C address of the device + * @param mode The mode to start operation under. One of the + * BH1750_OPMODES_T values. The default is the highest precision, + * lowest power mode. + */ + BH1750(int bus=BH1750_DEFAULT_I2C_BUS, int addr=BH1750_DEFAULT_I2C_ADDR, + BH1750_OPMODES_T mode=BH1750_OPMODE_H2_ONCE); + + /** + * BH1750 object destructor + */ + ~BH1750(); + + /** + * Reset the device. This doesn't really have much purpose. The + * device must be powered up for this command to work. In + * addition, this command will simply clear the measurement + * register to 0. + */ + void reset(); + + /** + * Get the measured light intensity in Lux. + * + * @return The measured light intensity in Lux. + */ + float getLux(); + + /** + * Power up the device. + */ + void powerUp(); + + /** + * Power down the device. + */ + void powerDown(); + + /** + * Setup the device to match the selected operating mode. + * + * @param mode operating mode, one of the BH1750_OPMODES_T values + */ + void setOpmode(BH1750_OPMODES_T mode); + + protected: + // bh1750 device context + bh1750_context m_bh1750; + + /** + * Sends a command to the device via I2C. + * + * @param cmd The command to write, one of the BH1750_CMD* values + */ + void sendCommand(uint8_t cmd); + + /** + * Read the 2 result bytes from the device via I2C. + * + * @return Data read in from the device as a uint16_t + */ + uint16_t readData(); + + private: + }; +} + + diff --git a/src/bh1750/bh1750_fti.c b/src/bh1750/bh1750_fti.c new file mode 100644 index 00000000..f908e440 --- /dev/null +++ b/src/bh1750/bh1750_fti.c @@ -0,0 +1,112 @@ +/* + * Authors: Jon Trulson + * Copyright (c) 2016 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 "bh1750.h" + +#include "upm_fti.h" + +/** + * This file implements the Function Table Interface (FTI) for this device + */ + + +// our descriptor data + +static const char upm_bh1750_name[] = "BH1750"; +static const char upm_bh1750_description[] = "DFRobot Digital Light Sensor"; +static const upm_protocol_t upm_bh1750_protocol[] = {UPM_I2C}; +static const upm_sensor_t upm_bh1750_category[] = {UPM_LIGHT}; + +// Forward declarations +void *upm_bh1750_init_name(); +void upm_bh1750_close(void* dev); +upm_result_t upm_bh1750_get_lux(const void* dev, float* lux); + +static const upm_sensor_descriptor_t usd = { + .name = upm_bh1750_name, + .description = upm_bh1750_description, + .protocol_size = 1, + .protocol = upm_bh1750_protocol, + .category_size = 1, + .category = upm_bh1750_category, +}; + +const upm_sensor_descriptor_t upm_bh1750_get_descriptor() +{ + return usd; +} + +// our generic sensor FT +static const upm_sensor_ft generic_ft = +{ + .upm_sensor_init_name = upm_bh1750_init_name, + .upm_sensor_close = upm_bh1750_close, + .upm_sensor_get_descriptor = upm_bh1750_get_descriptor, +}; + +// our generic light FT +static const upm_light_ft light_ft = +{ + .upm_light_get_value = upm_bh1750_get_lux, +}; + +const void *upm_bh1750_get_ft(upm_sensor_t sensor_type) +{ + switch (sensor_type) + { + case UPM_SENSOR: + return &generic_ft; + + case UPM_LIGHT: + return &light_ft; + + default: + return NULL; + } +} + +void *upm_bh1750_init_name() +{ + // not implemented, for now call the driver init + printf("init_name not implemented, calling bh1750_init() with defaults\n"); + return bh1750_init(BH1750_DEFAULT_I2C_BUS, BH1750_DEFAULT_I2C_ADDR, + BH1750_OPMODE_H2_ONCE); +} + +void upm_bh1750_close(void* dev) +{ + bh1750_close((bh1750_context)dev); +} + +// sensor specific + +upm_result_t upm_bh1750_get_lux(const void* dev, float* lux) +{ + return bh1750_get_lux((bh1750_context)dev, lux); +} + + + + + diff --git a/src/bh1750/javaupm_bh1750.i b/src/bh1750/javaupm_bh1750.i new file mode 100644 index 00000000..98646f66 --- /dev/null +++ b/src/bh1750/javaupm_bh1750.i @@ -0,0 +1,21 @@ +%module javaupm_bh1750 +%include "../upm.i" +%include "std_string.i" + +%{ + #include "bh1750.hpp" +%} + +%include "bh1750.hpp" + + +%pragma(java) jniclasscode=%{ + static { + try { + System.loadLibrary("javaupm_bh1750"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. \n" + e); + System.exit(1); + } + } +%} diff --git a/src/bh1750/jsupm_bh1750.i b/src/bh1750/jsupm_bh1750.i new file mode 100644 index 00000000..8250f8cd --- /dev/null +++ b/src/bh1750/jsupm_bh1750.i @@ -0,0 +1,10 @@ +%module jsupm_bh1750 +%include "../upm.i" +%include "std_string.i" + +%{ + #include "bh1750.hpp" +%} + +%include "bh1750.hpp" + diff --git a/src/bh1750/pyupm_bh1750.i b/src/bh1750/pyupm_bh1750.i new file mode 100644 index 00000000..0a8a283a --- /dev/null +++ b/src/bh1750/pyupm_bh1750.i @@ -0,0 +1,13 @@ +// Include doxygen-generated documentation +%include "pyupm_doxy2swig.i" +%module pyupm_bh1750 +%include "../upm.i" +%include "std_string.i" + +%feature("autodoc", "3"); + +%{ + #include "bh1750.hpp" +%} +%include "bh1750.hpp" +