0.2.1 MAX44007

This commit is contained in:
Rob Tillaart 2024-05-22 10:16:00 +02:00
parent 1248e73967
commit dbe75c80d3
18 changed files with 376 additions and 87 deletions

View File

@ -6,6 +6,15 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [0.2.1] - 2024-05-17
- add **getCurrentDivisorRatio()**
- add **getAddress()** convenience
- add **max44007_performance.ino**.
- add **max44007_test_manual_mode.ino**.
- update readme.md
- update keywords.txt
- minor edits.
## [0.2.0] - 2023-10-02
- refactor constructor around I2C interface (simpler)
- remove **configure()**

View File

@ -1,7 +1,7 @@
//
// FILE: Max44007.cpp
// AUTHOR: Rob Tillaart
// VERSION: 0.2.0
// VERSION: 0.2.1
// DATE: 2022-01-04
// PURPOSE: library for Max44007 lux sensor Arduino
// URL: https://github.com/RobTillaart/MAX44007
@ -32,6 +32,12 @@ bool Max44007::isConnected()
}
uint8_t Max44007::getAddress()
{
return _address;
}
float Max44007::getLux(void)
{
uint8_t datahigh = read(MAX44007_LUX_READING_HIGH);
@ -151,6 +157,22 @@ void Max44007::setManualMode(uint8_t CDR, uint8_t TIM)
}
int Max44007::getCurrentDivisorRatio()
{
uint8_t CDR = read(MAX44007_CONFIGURATION) & 0x08;
return CDR >> 3;
}
int Max44007::getIntegrationTime()
{
uint8_t TIM = read(MAX44007_CONFIGURATION) & 0x07;
return 800 >> TIM;
}
// datahigh = [eeee mmmm]
// datalow = [ mmmm]
float Max44007::convertToLux(uint8_t datahigh, uint8_t datalow)
{
uint8_t exponent = datahigh >> 4;
@ -169,7 +191,8 @@ bool Max44007::setThreshold(const uint8_t reg, const float value)
// CHECK RANGE OF VALUE
if ((value < 0.0) || (value > MAX44007_MAX_LUX)) return false;
uint32_t mantissa = round(value * (1.0 / MAX44007_MIN_LUX)); // compile time optimized.
// compile time optimized.
uint32_t mantissa = round(value * (1.0 / MAX44007_MIN_LUX));
uint8_t exponent = 0;
while (mantissa > 255)
{
@ -186,7 +209,8 @@ bool Max44007::setThreshold(const uint8_t reg, const float value)
float Max44007::getThreshold(uint8_t reg)
{
uint8_t datahigh = read(reg);
float lux = convertToLux(datahigh, 0x08); // 0x08 = correction for lost bits
// 0x08 = correction for lost bits
float lux = convertToLux(datahigh, 0x08);
return lux;
}
@ -198,12 +222,12 @@ uint8_t Max44007::read(uint8_t reg)
_error = _wire->endTransmission();
if (_error != MAX44007_OK)
{
return _data; // last value
return _data; // last value
}
if (_wire->requestFrom(_address, (uint8_t) 1) != 1)
{
_error = MAX44007_ERROR_WIRE_REQUEST;
return _data; // last value
return _data; // last value
}
_data = _wire->read();
return _data;

View File

@ -2,13 +2,13 @@
// FILE: Max44007.h
// AUTHOR: Rob Tillaart
// VERSION: 0.2.0
// VERSION: 0.2.1
// DATE: 2022-01-04
// PURPOSE: library for Max44007 lux sensor Arduino
// URL: https://github.com/RobTillaart/MAX44007
// breakout MAX44007
// breakout MAX44007
//
// +--------+
// VCC |o |
@ -18,8 +18,8 @@
// +--------+
//
// ADDRESS:
// 0 = 0x4A
// 1 = 0x4B
// 0 = 0x5A
// 1 = 0x5B
//
// INT:
// Connect the INT pin to an pull up resistor
@ -33,7 +33,7 @@
#include "Arduino.h"
#define MAX44007_LIB_VERSION (F("0.2.0"))
#define MAX44007_LIB_VERSION (F("0.2.1"))
#define MAX44007_DEFAULT_ADDRESS 0x5A
#define MAX44007_ALT_ADDRESS 0x5B
@ -72,10 +72,14 @@ public:
Max44007(const uint8_t address = MAX44007_DEFAULT_ADDRESS, TwoWire *wire = &Wire);
bool isConnected();
uint8_t getAddress();
float getLux();
int getError();
// threshold must be between 0 and 188006
// threshold must be between 0 and 188006
bool setHighThreshold(const float value); // returns false if value out of range
float getHighThreshold(void);
bool setLowThreshold(const float value); // returns false if value out of range
@ -83,30 +87,34 @@ public:
void setThresholdTimer(const uint8_t value); // 2 seems practical minimum
uint8_t getThresholdTimer();
void enableInterrupt() { write(MAX44007_INTERRUPT_ENABLE, 1); };
void disableInterrupt() { write(MAX44007_INTERRUPT_ENABLE, 0); };
bool interruptEnabled() { return read(MAX44007_INTERRUPT_ENABLE) & 0x01; };
uint8_t getInterruptStatus() { return read(MAX44007_INTERRUPT_STATUS) & 0x01; };
// check datasheet for detailed behaviour
void setConfiguration(uint8_t);
uint8_t getConfiguration();
void setAutomaticMode();
void setContinuousMode(); // uses more power
void clrContinuousMode(); // uses less power
// CDR = Current Divisor Ratio
// CDR = 1 ==> only 1/8th is measured
// TIM = Time Integration Measurement (table)
// 000 800ms
// 001 400ms
// 010 200ms
// 011 100ms
// 100 50ms manual only
// 101 25ms manual only
// 110 12.5ms manual only
// 111 6.25ms manual only
// CDR = Current Divisor Ratio
// CDR = 1 ==> only 1/8th is measured
// TIM = Time Integration Measurement (table)
// 000 800ms
// 001 400ms
// 010 200ms
// 011 100ms
// 100 50ms manual only
// 101 25ms manual only
// 110 12.5ms manual only
// 111 6.25ms manual only
void setManualMode(uint8_t CDR, uint8_t TIM);
int getIntegrationTime() { return 800 >> (getConfiguration() & 0x07); }; // ms
int getCurrentDivisorRatio(); // CDR 0/1
int getIntegrationTime(); // TIM in ms (rounded)
// TEST the math
float convertToLux(uint8_t datahigh, uint8_t datalow);
@ -127,5 +135,5 @@ protected:
};
// -- END OF FILE --
// -- END OF FILE --

View File

@ -57,6 +57,51 @@ Note: version 0.2.0 simplified the constructor interface and removed **configure
//
```
## I2C
#### Address
The MAX44009 can have 2 addresses:
- 0x5A = **MAX44009_DEFAULT_ADDRESS**
- 0x5B = **MAX44009_ALT_ADDRESS**
See schema above.
#### I2C multiplexing
Sometimes you need to control more devices than possible with the default
address range the device provides.
This is possible with an I2C multiplexer e.g. TCA9548 which creates up
to eight channels (think of it as I2C subnets) which can use the complete
address range of the device.
Drawback of using a multiplexer is that it takes more administration in
your code e.g. which device is on which channel.
This will slow down the access, which must be taken into account when
deciding which devices are on which channel.
Also note that switching between channels will slow down other devices
too if they are behind the multiplexer.
- https://github.com/RobTillaart/TCA9548
#### I2C Performance
Performance of the getLux function in microseconds.
| Clock | UNO | ESP32 | Notes |
|:--------:|:-------:|:-------:|:-------:|
| 100000 | | |
| 200000 | | |
| 300000 | | |
| 400000 | | |
| 500000 | | |
| 600000 | | |
TODO fill table.
## Interface
@ -69,6 +114,7 @@ Note: version 0.2.0 simplified the constructor interface and removed **configure
- **Max44007(const uint8_t address = MAX44007_DEFAULT_ADDRESS, TwoWire \*wire = &Wire)** Constructor.
Optional address and optional I2C interface.\
- **bool isConnected()** returns true if the device address configured is available on I2C bus.
- **uint8_t getAddress()** returns device address. Convenience function.
NOTE: The user must call **Wire.begin()** or **Wire.begin(SDA, SCL)** in **setup()**.
@ -126,9 +172,9 @@ check datasheet for details
### Configure sample mode
Check datasheet for details
Check datasheet for details.
CCR = Current Divisor Ratio.
CDR = Current Divisor Ratio.
TIM = Integration time.
@ -139,7 +185,10 @@ Advantage is that the latest data is always available fast.
- **void clrContinuousMode()** uses less power so better for LOW power configurations.
- **void setManualMode(uint8_t CDR, uint8_t TIM)** Set the Current Divisor Ratio and the
integration time manually. Effectively disable automatic mode.
- **int getIntegrationTime()** returns the set integration time in milliseconds
- **int getIntegrationTime()** returns the set integration time in milliseconds.
Note these are rounded down (12 == 12.5 and 6 == 6.25) to minimize math.
- **int getCurrentDivisorRatio()** returns the set Current Divisor Ratio.
This is either 0 (full intensity) or 1 (1/8th intensity).
```
CDR = Current Divisor Ratio
@ -160,7 +209,7 @@ integration time manually. Effectively disable automatic mode.
### Test functions
Function for the conversion math, not meant to be used directly,
but by making them public they become testable.
but by making it public the math becomes testable.
- **float convertToLux(uint8_t dataHigh, uint8_t dataLow)** convert intern register
format to a LUX value.
@ -194,12 +243,18 @@ Pull ups on I2C bus are recommended.
#### Must
- follow MAX44009
- improve documentation
- buy hardware
#### Should
- run performance test on UNO and ESP32.
#### Could
- merge MAX44007 / MAX44009 library in the future. (shared base class?)
- read data high and low in one call?
- convertToLux() overflow test, when exponent == 15.
#### Wont

View File

@ -2,12 +2,12 @@
// FILE: Max44007_interrupt.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
#include "Wire.h"
#include "Max44007.h"
Max44007 myLux(0x5A);
uint32_t lastDisplay = 0;
@ -19,8 +19,10 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
myLux.setContinuousMode();
myLux.setHighThreshold(30);
@ -44,22 +46,29 @@ void loop()
{
lastDisplay += interval;
float lux = myLux.getLux();
int err = myLux.getError();
int st = myLux.getInterruptStatus();
if (err != 0)
int error = myLux.getError();
int status = myLux.getInterruptStatus();
if (error != 0)
{
Serial.print("Error:\t");
Serial.println(err);
Serial.println(error);
}
else
{
Serial.print("lux:\t");
Serial.print(lux);
if (st == 1) Serial.println("\tIRQ occurred");
else Serial.println();
if (status == 1)
{
Serial.println("\tIRQ occurred");
}
else
{
Serial.println();
}
}
}
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -0,0 +1,64 @@
//
// FILE: max44007_performance.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of max44007 library
// URL: https://github.com/RobTillaart/MAX44007
//
// This measurement is indicative for the I2C speed
// It might be affected by the intensity.
#include "Max44007.h"
Max44007 myLux(0x4A);
uint32_t lastDisplay = 0;
uint32_t start = 0;
uint32_t stop = 0;
int count = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
myLux.setContinuousMode();
for (uint32_t clock = 100000; clock <= 800000; clock += 100000)
{
delay(1000); // wait for new measurement.
test(clock);
}
}
void test(uint32_t clock)
{
Wire.setClock(clock);
// time the measurement
start = micros();
float lux = myLux.getLux();
stop = micros();
// print results.
Serial.print(clock);
Serial.print("\t");
Serial.print(stop - start);
Serial.print("\t");
Serial.print(lux);
Serial.println();
}
void loop()
{
}
// -- END OF FILE --

View File

@ -2,12 +2,12 @@
// FILE: Max44007_setAutomaticMode.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
#include "Wire.h"
#include "Max44007.h"
Max44007 myLux(0x5A);
uint32_t lastDisplay = 0;
@ -19,6 +19,7 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
@ -33,19 +34,20 @@ void loop()
{
lastDisplay += interval;
float lux = myLux.getLux();
int err = myLux.getError();
int error = myLux.getError();
// in automatic mode TIM & CDR are automatic generated
// and read only (in manual mode they are set by the user
int conf = myLux.getConfiguration();
int CDR = (conf & 0x80) >> 3;
int TIM = (conf & 0x07);
// In automatic mode TIM and CDR are automatic generated
// and read only.
// In manual mode they are set by the user.
int config = myLux.getConfiguration();
int CDR = (config & 0x80) >> 3;
int TIM = (config & 0x07);
int integrationTime = myLux.getIntegrationTime();
if (err != 0)
if (error != 0)
{
Serial.print("Error:\t");
Serial.println(err);
Serial.println(error);
}
else
{
@ -64,4 +66,5 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -2,7 +2,7 @@
// FILE: Max44007_setContinuousMode.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
//
// note that lux values are repeated a number of times
// if read faster than the integration time.
@ -11,9 +11,9 @@
// NB the getLux() call takes a bit more than 1 millisecond
#include "Wire.h"
#include "Max44007.h"
Max44007 myLux(0x5A);
uint32_t lastDisplay = 0;
@ -28,6 +28,7 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
@ -42,14 +43,16 @@ void loop()
{
lastDisplay += interval;
count++;
// time the measurement
start = micros();
float lux = myLux.getLux();
stop = micros();
int err = myLux.getError();
if (err != 0)
int error = myLux.getError();
if (error != 0)
{
Serial.print("Error:\t");
Serial.println(err);
Serial.println(error);
}
else
{
@ -60,7 +63,10 @@ void loop()
Serial.println();
}
}
if (count == 5) myLux.clrContinuousMode();
if (count == 5)
{
myLux.clrContinuousMode();
}
if (count == 10)
{
count = 0;
@ -69,4 +75,5 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -2,11 +2,12 @@
// FILE: Max44007_setManualMode.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
#include "Wire.h"
#include "Max44007.h"
Max44007 myLux;
uint32_t lastDisplay = 0;
@ -22,6 +23,7 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
@ -49,9 +51,9 @@ void loop()
}
}
// Change CDR and TIM every 5 seconds
// Note that the value of getLux() is affected
// for up to about a second.
// Change CDR and TIM every 5 seconds
// Note that the value of getLux() is affected
// for up to about a second.
if (millis() - lastChangeCDRTIM >= 5000)
{
lastChangeCDRTIM += 5000;
@ -70,4 +72,5 @@ void loop()
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -2,12 +2,12 @@
// FILE: Max44007_test01.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
#include "Wire.h"
#include "Max44007.h"
Max44007 myLux(0x5B);
uint32_t lastDisplay = 0;
@ -19,8 +19,10 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
Wire.setClock(100000);
}
@ -33,19 +35,19 @@ void loop()
{
lastDisplay += interval;
float lux = myLux.getLux();
int err = myLux.getError();
if (err != 0)
int error = myLux.getError();
if (error != 0)
{
Serial.print("Error:\t");
Serial.println(err);
Serial.println(error);
}
else
{
Serial.print("lux:\t");
Serial.println(lux);
Serial.println(lux, 3);
}
}
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -1,3 +1,18 @@
platforms:
rpipico:
board: rp2040:rp2040:rpipico
package: rp2040:rp2040
gcc:
features:
defines:
- ARDUINO_ARCH_RP2040
warnings:
flags:
packages:
rp2040:rp2040:
url: https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
compile:
# Choosing to run compilation tests on 2 different Arduino platforms
# ESP32 specific application

View File

@ -3,6 +3,7 @@
// AUTHOR: Moritz Ulmer
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
//
// NOTE: To select the alternative I2C address on the GY-49 breakout board,
// the A0 pin has to be set to 3V3. It is soldered to GND by default.
@ -14,7 +15,7 @@
#include "Max44007.h"
// Don't begin I2C interface (Wire). Will be called in setup()
// Don't begin I2C interface (Wire). Will be called in setup()
Max44007 myLuxA(MAX44007_DEFAULT_ADDRESS, &Wire);
Max44007 myLuxB(MAX44007_ALT_ADDRESS, &Wire);
Max44007 myLuxC(MAX44007_DEFAULT_ADDRESS, &Wire1);
@ -29,6 +30,7 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin(19, 18);
Wire1.begin(22, 23);
@ -48,4 +50,5 @@ void loop() {
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -0,0 +1,81 @@
//
// FILE: max44007_test_manualmode.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of max44007 library
// URL: https://github.com/RobTillaart/MAX44007
#include "Max44007.h"
Max44007 myLux(MAX44007_DEFAULT_ADDRESS, &Wire);
uint32_t lastDisplay = 0;
uint32_t lastChangeCDRTIM = 0;
uint8_t CDR = 0;
uint8_t TIM = 0;
void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
myLux.setManualMode(CDR, TIM);
}
void loop()
{
uint32_t interval = 100;
if (millis() - lastDisplay >= interval)
{
lastDisplay += interval;
float lux = myLux.getLux();
int err = myLux.getError();
if (err != 0)
{
Serial.print("Error:\t");
Serial.println(err);
}
else
{
Serial.print("lux:\t");
Serial.println(lux);
}
}
// Change CDR and TIM every 5 seconds
// Note that the value of getLux() is affected
// for up to about a second.
if (millis() - lastChangeCDRTIM >= 5000)
{
lastChangeCDRTIM += 5000;
TIM++;
if (TIM == 4)
{
TIM = 0;
CDR = (CDR + 1) & 1;
}
myLux.setManualMode(CDR, TIM);
Serial.print("CDR:\t");
Serial.print((int)CDR);
Serial.print("\t");
Serial.print(myLux.getCurrentDivisorRatio()); // read from config
Serial.print("\tTIM:\t");
Serial.print((int)TIM);
Serial.print("\t");
Serial.print(myLux.getIntegrationTime()); // read from config
Serial.print(" ms\n");
}
}
// -- END OF FILE --

View File

@ -2,12 +2,12 @@
// FILE: Max44007_two_sensors.ino
// AUTHOR: Rob Tillaart
// PURPOSE: demo of Max44007 library
// DATE: 2022-01-04
// URL: https://github.com/RobTillaart/MAX44007
#include "Wire.h"
#include "Max44007.h"
Max44007 LuxA(0x5A);
Max44007 LuxB(0x5B);
@ -21,8 +21,10 @@ void setup()
Serial.println(__FILE__);
Serial.print("MAX44007_LIB_VERSION: ");
Serial.println(MAX44007_LIB_VERSION);
Serial.println();
Wire.begin();
Wire.setClock(100000);
Serial.print("\n\tCOUNT\tLUXA\tLUXB\n");
@ -46,18 +48,19 @@ void loop()
Serial.print('\t');
float lux = LuxA.getLux();
int err = LuxA.getError();
if (err != 0) Serial.print(err);
else Serial.print(lux);
int error = LuxA.getError();
if (error != 0) Serial.print(error);
else Serial.print(lux);
Serial.print('\t');
lux = LuxB.getLux();
err = LuxB.getError();
if (err != 0) Serial.print(err);
else Serial.print(lux);
error = LuxB.getError();
if (error != 0) Serial.print(error);
else Serial.print(lux);
Serial.println();
}
}
// -- END OF FILE --
// -- END OF FILE --

View File

@ -6,6 +6,8 @@ Max44007 KEYWORD1
# Methods and Functions (KEYWORD2)
isConnected KEYWORD2
getAddress() KEYWORD2
getLux KEYWORD2
getError KEYWORD2
@ -25,10 +27,11 @@ setConfiguration KEYWORD2
getConfiguration KEYWORD2
setAutomaticMode KEYWORD2
setContinuousMode KEYWORD2
setManualMode KEYWORD2
clrContinuousMode KEYWORD2
getIntegrationTime KEYWORD2
setManualMode KEYWORD2
getIntegrationTime KEYWORD2
getCurrentDivisorRatio KEYWORD2
# Instances (KEYWORD2)

View File

@ -15,7 +15,7 @@
"type": "git",
"url": "https://github.com/RobTillaart/Max44007.git"
},
"version": "0.2.0",
"version": "0.2.1",
"license": "MIT",
"frameworks": "*",
"platforms": "*",

View File

@ -1,5 +1,5 @@
name=Max44007
version=0.2.0
version=0.2.1
author=Rob Tillaart <rob.tillaart@gmail.com>
maintainer=Rob Tillaart <rob.tillaart@gmail.com>
sentence=Library for MAX44007 I2C LUX sensor Arduino.

View File

@ -32,7 +32,6 @@
#include <ArduinoUnitTests.h>
#include "Arduino.h"
#include "Max44007.h"
@ -104,4 +103,5 @@ unittest(test_convertToLux)
unittest_main()
// -- END OF FILE --