210 lines
5.2 KiB
C++
210 lines
5.2 KiB
C++
|
#include "BH1750FVI.h"
|
||
|
//#if ARDUINO >= 100
|
||
|
#include "Arduino.h"
|
||
|
//#else
|
||
|
// #include "WProgram.h"
|
||
|
//#endif
|
||
|
|
||
|
#include <Wire.h>
|
||
|
|
||
|
void BH1750FVI::begin(byte mode, byte addr, double sens, int pin){
|
||
|
if(pin>=0 && pin<55){
|
||
|
pinMode(pin, OUTPUT);
|
||
|
if(addr==BH_AddrL) digitalWrite(pin, LOW);
|
||
|
if(addr==BH_AddrH) digitalWrite(pin, HIGH);
|
||
|
}
|
||
|
byte sensitivity;
|
||
|
if(sens<BH_MinSv){
|
||
|
sens = constrain(sens, ((double)BH_MinSv/(double)BH_DefSv), ((double)BH_MaxSv/(double)BH_DefSv));
|
||
|
sensitivity = (byte)round(sens*(double)BH_DefSv);
|
||
|
}
|
||
|
else{
|
||
|
sensitivity = constrain((byte)sens, BH_MinSv, BH_MaxSv);
|
||
|
}
|
||
|
address = addr;
|
||
|
currentSensitivity = sensitivity;
|
||
|
MTreg_hiByte = BH_MTrHb | (sensitivity >> 5);
|
||
|
MTreg_loByte = BH_MTrLb | (sensitivity & 0b00011111);
|
||
|
switch(mode){
|
||
|
case BH_ContL:
|
||
|
case BH_ContH:
|
||
|
case BH_Conth:
|
||
|
startOngoingSamples(mode);
|
||
|
break;
|
||
|
case BH_SingH:
|
||
|
case BH_Singh:
|
||
|
case BH_SingL:
|
||
|
startSingleSample(mode);
|
||
|
break;
|
||
|
default:
|
||
|
mode = BH_EasyH;
|
||
|
startOngoingSamples(mode);
|
||
|
break;
|
||
|
}
|
||
|
sampleUnseen = false;
|
||
|
lastSampleStart = 0;
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::startOngoingSamples(char mode){
|
||
|
if(mode==BH_NoMod) mode=currentMode;
|
||
|
byte lowLevelMode = mode;
|
||
|
if(lowLevelMode==BH_EasyH) lowLevelMode=BH_ContH;
|
||
|
switch(mode){
|
||
|
case BH_EasyH:
|
||
|
case BH_ContH:
|
||
|
case BH_Conth:
|
||
|
case BH_ContL:
|
||
|
i2cWrite(BH_PowOn);
|
||
|
i2cWrite(MTreg_hiByte);
|
||
|
i2cWrite(MTreg_loByte);
|
||
|
i2cWrite(lowLevelMode);
|
||
|
lastSampleStart = millis();
|
||
|
currentMode = mode;
|
||
|
return setSensitivity(currentSensitivity);
|
||
|
break;
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::startSingleSample(char mode){
|
||
|
if(mode==BH_NoMod){
|
||
|
mode=currentMode;
|
||
|
}
|
||
|
switch(mode){
|
||
|
case BH_SingH:
|
||
|
case BH_Singh:
|
||
|
case BH_SingL:
|
||
|
i2cWrite(BH_PowOn);
|
||
|
i2cWrite(MTreg_hiByte);
|
||
|
i2cWrite(MTreg_loByte);
|
||
|
i2cWrite(mode);
|
||
|
lastSampleStart = millis();
|
||
|
currentMode = mode;
|
||
|
return setSensitivity(currentSensitivity);
|
||
|
break;
|
||
|
default:
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool BH1750FVI::sampleIsFresh(){
|
||
|
if(sampleUnseen) return true;
|
||
|
else if((millis() > (lastSampleStart+currentSamplingTime))){
|
||
|
sampleUnseen = true;
|
||
|
return true;
|
||
|
}
|
||
|
else return false;
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::getLightLevel(char mode){
|
||
|
unsigned long int Intensity_value;
|
||
|
sampleUnseen = false;
|
||
|
Intensity_value = i2cRead();
|
||
|
if(mode!='r'){
|
||
|
Intensity_value = (Intensity_value*5)/6;
|
||
|
if(mode!='c'){
|
||
|
Intensity_value = (Intensity_value*69)/currentSensitivity;
|
||
|
}
|
||
|
/*this next adjustment is not useful in practice. if you're using
|
||
|
a half-scale mode, you want the extra sensitivity. I'm leaving it
|
||
|
here for reference.
|
||
|
switch(currentMode){
|
||
|
case BH_Singh:
|
||
|
case BH_Conth:
|
||
|
Intensity_value /= 2;
|
||
|
}*/
|
||
|
Intensity_value = constrain(Intensity_value, 0, 65535);
|
||
|
}
|
||
|
switch(currentMode){
|
||
|
case BH_ContH:
|
||
|
case BH_Conth:
|
||
|
case BH_ContL:
|
||
|
case BH_EasyH:
|
||
|
//this is a fake previous sample time that will keep pace with
|
||
|
//the actual BH1750FVI's sampling rate, but isn't necessarily
|
||
|
//synchronized to the earliest time each new sample is available.
|
||
|
//if you want true synchronized timing, use a single-sample mode.
|
||
|
lastSampleStart = millis();
|
||
|
}
|
||
|
return (word)Intensity_value;
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::setSensitivity(double sens){
|
||
|
if(sens<((double)(BH_MinSv/2))){
|
||
|
sens = constrain(sens,
|
||
|
((double)BH_MinSv/(double)BH_DefSv),
|
||
|
((double)BH_MaxSv/(double)BH_DefSv)
|
||
|
);
|
||
|
sens = sens*(double)BH_DefSv;
|
||
|
}
|
||
|
else{
|
||
|
sens = constrain(sens, (double)BH_MinSv, (double)BH_MaxSv);
|
||
|
}
|
||
|
return setSensitivity((byte)round(sens));
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::setSensitivity(float sens){
|
||
|
return setSensitivity((double)sens);
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::setSensitivity(int sens){
|
||
|
sens = constrain(sens, 1, BH_MaxSv);
|
||
|
return setSensitivity((byte)sens);
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::setSensitivity(byte sens){
|
||
|
if(sens<(BH_MinSv/2)){
|
||
|
sens = BH_DefSv*(constrain(sens, (byte)1, (byte)3));
|
||
|
}
|
||
|
else{
|
||
|
sens = constrain(sens, BH_MinSv, BH_MaxSv);
|
||
|
}
|
||
|
switch(currentMode){
|
||
|
case BH_ContL:
|
||
|
case BH_SingL:
|
||
|
currentSamplingTime = (word)((BH_FastD*(unsigned long int)sens)/BH_DefSv);
|
||
|
break;
|
||
|
default:
|
||
|
currentSamplingTime = (word)((((unsigned long int)BH_SlowD)*((unsigned long int)sens))/BH_DefSv);
|
||
|
break;
|
||
|
}
|
||
|
MTreg_hiByte = BH_MTrHb | (sens >> 5);
|
||
|
MTreg_loByte = BH_MTrLb | (sens & 0b00011111);
|
||
|
currentSensitivity = sens;
|
||
|
sampleUnseen = false;
|
||
|
return currentSamplingTime;
|
||
|
}
|
||
|
|
||
|
void BH1750FVI::powerDown(){
|
||
|
i2cWrite(BH_PowOf);
|
||
|
}
|
||
|
|
||
|
/*I2C INTERFACE
|
||
|
These two functions were originally based on code written by
|
||
|
https://github.com/claws/ and
|
||
|
https://github.com/Genotronex/
|
||
|
*/
|
||
|
void BH1750FVI::i2cWrite(byte dataToSend){
|
||
|
Wire.beginTransmission(address);
|
||
|
Wire.write(dataToSend);
|
||
|
Wire.endTransmission();
|
||
|
}
|
||
|
|
||
|
word BH1750FVI::i2cRead(){
|
||
|
word value;
|
||
|
Wire.beginTransmission(address);
|
||
|
Wire.requestFrom(address, (byte)2);
|
||
|
if(Wire.available()){
|
||
|
value = Wire.read();
|
||
|
if(Wire.available()){
|
||
|
value <<= 8;
|
||
|
value |= Wire.read();
|
||
|
}
|
||
|
else value=0;
|
||
|
}
|
||
|
else value=0;
|
||
|
Wire.endTransmission();
|
||
|
return value;
|
||
|
}
|