Library for BH1750 I2C light sensor. Supports autoranging! True to datasheet. (beware: calls are blocking at the moment)

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BH1750.cpp Source File

BH1750.cpp

00001 #include "BH1750.h"
00002 
00003 
00004 BH1750::BH1750(I2C & i2c_inst, bool autoRange, bool addressPinState): _i2c_inst(i2c_inst) {
00005     if (addressPinState == true)   _address = ADDRESS_HIGH;
00006     else _address = ADDRESS_LOW;
00007 
00008     _autoModeAdjustSwitch = autoRange;
00009 }
00010 
00011 
00012 void BH1750::_sendCommand(char toSend) {
00013     char toSendPseudoArray[] = {toSend};
00014     _i2c_inst.write(_address << 1, toSendPseudoArray, 1);
00015 }
00016 
00017 unsigned int BH1750::_readRaw() {
00018     unsigned int measurement;
00019     char measurement_intermediate [2];
00020     _i2c_inst.read(_address << 1, measurement_intermediate, 2);
00021     measurement = (measurement_intermediate[0] << 8) +  measurement_intermediate[1];
00022     return measurement;
00023 }
00024 bool BH1750::_autoModeAdjust(float measurement) { // returns if adjusted or left alone
00025 //        printf("\tcurrentMode: %d\r\n", _currentMode);
00026     char previousMode = _currentMode;
00027     char previousMtreg = _currentMtreg;
00028     bool changed = false;
00029 
00030     if (measurement < 5.0 ) {
00031         if (_currentMode != CONTINOUS_H2_RES_CMD ) {
00032             setMode(CONTINOUS_H2_RES_CMD);
00033             setMtreg(254); //maximum
00034             changed = true;
00035         }
00036     } else if (measurement < 1000.0) {
00037         if (_currentMode != CONTINOUS_H_RES_CMD ) {
00038 
00039             setMtreg(DEFAULTMTREG);
00040             setMode(CONTINOUS_H_RES_CMD);
00041             changed = true;
00042         }
00043     } else if (_currentMode != CONTINOUS_L_RES_CMD) {
00044         setMtreg(DEFAULTMTREG);
00045         setMode(CONTINOUS_L_RES_CMD);
00046         changed = true;
00047     }
00048     
00049     if (changed) {
00050         wait_ms(_waitForMeasurement); // one more wait in PREVIOUS state. guarantees valid values on state transitions
00051         return true;
00052     } else
00053         return false;
00054 }
00055 
00056 float BH1750::_readSingle() {
00057     float measurement;
00058     // measurement switch
00059     switch(_currentMode) {
00060         case ONETIME_L_RES_CMD:
00061             _sendCommand(_currentMode);
00062             _waitForMeasurement = L_RES_MEASUREMENT_TIME;
00063             break;
00064         case ONETIME_H_RES_CMD:
00065             _sendCommand(_currentMode);
00066             _waitForMeasurement = H_RES_MEASUREMENT_TIME;
00067             break;
00068         case ONETIME_H2_RES_CMD:
00069             _sendCommand(_currentMode);
00070             _waitForMeasurement = H_RES_MEASUREMENT_TIME;
00071             break;
00072         case CONTINOUS_L_RES_CMD:
00073             _waitForMeasurement = L_RES_MEASUREMENT_TIME;
00074             break;
00075         case CONTINOUS_H_RES_CMD:
00076             _waitForMeasurement = H_RES_MEASUREMENT_TIME;
00077             break;
00078         case CONTINOUS_H2_RES_CMD:
00079             _waitForMeasurement = H_RES_MEASUREMENT_TIME;
00080             break;
00081     }
00082 
00083     _waitForMeasurement *= (unsigned int) ((float) _currentMtreg / (float) DEFAULTMTREG); // a bit too late, but nevermind
00084     wait_ms(_waitForMeasurement);
00085     measurement = (float)_readRaw();
00086 
00087     // post-measurement switch
00088     switch(_currentMode) {
00089         case ONETIME_L_RES_CMD:
00090         case ONETIME_H_RES_CMD:
00091         case ONETIME_H2_RES_CMD:
00092             break;
00093 
00094         case CONTINOUS_L_RES_CMD:
00095             break;
00096         case CONTINOUS_H_RES_CMD:
00097             break;
00098         case CONTINOUS_H2_RES_CMD:
00099             measurement /= 2.0;
00100             break;
00101     }
00102 
00103 //        printf("wait for meas value: %d\r\n", _waitForMeasurement);
00104 
00105     measurement = measurement / 1.2 * (float) DEFAULTMTREG / (float) _currentMtreg;
00106     return measurement;
00107 }
00108 
00109 void BH1750::power(bool state) {
00110     if (state == true) {// power on
00111         _sendCommand(powerOn_cmd);
00112     } else { // power off}
00113         _sendCommand(powerDown_cmd);
00114     }
00115 }
00116 
00117 float BH1750::read() {
00118         float measurement;
00119         do {
00120             measurement = _readSingle();
00121 //            printf("measurement do while: %.1f\r\n", measurement);
00122             if (!_autoModeAdjustSwitch) break;
00123             // else continue
00124 //            wait_ms(1.3*_waitForMeasurement);
00125         } while(_autoModeAdjust(measurement));
00126         return measurement;
00127 }
00128 
00129 void BH1750::setMode(const char mode) {
00130     _sendCommand(mode);
00131     _currentMode = mode;
00132     wait(.01);
00133 }
00134 
00135 void BH1750::setMtreg(char newMtreg) {
00136     // min. 31
00137     // default 69
00138     // max. 254
00139     if (newMtreg >= 31 && newMtreg <= 254) {
00140         _sendCommand((0b01000 << 3) | (newMtreg >> 5));
00141         _sendCommand((0b011 << 5 )  | (newMtreg & 0b111));
00142         _currentMtreg = newMtreg;
00143     }
00144 }