Allow multiple Wire interfaces

Why:

- Some boards have multiple I2C interfaces
- Control when TwoWire.begin() is called

This change addresses the need by:

- Option to not begin() Wire
- Always be in configured state (no null ptr crash)
- Internally use TwoWire pointer
- Add example of new functionality
- Add possible I2C addresses
- Update I2C address in example to be within 0 - 127 range
This commit is contained in:
Moritz Ulmer 2020-01-19 22:53:40 +01:00
parent 53764ffe65
commit fbea3f36f5
4 changed files with 102 additions and 19 deletions

View File

@ -18,7 +18,9 @@
#include "WProgram.h" #include "WProgram.h"
#endif #endif
#define MAX44009_LIB_VERSION "0.2.0" #define MAX44009_LIB_VERSION "0.3.0"
#define MAX44009_DEFAULT_ADDRESS 0x4A
#define MAX44009_ALT_ADDRESS 0x4B
// REGISTERS // REGISTERS
#define MAX44009_INTERRUPT_STATUS 0x00 #define MAX44009_INTERRUPT_STATUS 0x00
@ -40,13 +42,20 @@
class Max44009 class Max44009
{ {
public: public:
// enum class to prevent bool to be implicitly casted to int
enum class Boolean { True, False };
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
// dataPin and clockPin can be used for ESP8266 // dataPin and clockPin can be used for ESP8266
Max44009(const uint8_t address, const uint8_t dataPin, const uint8_t clockPin); Max44009(const uint8_t address, const uint8_t dataPin, const uint8_t clockPin);
#endif #endif
// ctor for UNO // ctor for UNO
Max44009(const uint8_t address); Max44009(const uint8_t address, const Boolean begin = Boolean::True);
// default ctor with default address 0xCB
Max44009(const Boolean begin = Boolean::True);
// Change I2C interface and address
void configure(const uint8_t address, TwoWire *wire);
float getLux(); float getLux();
int getError(); int getError();
@ -91,6 +100,8 @@ private:
uint8_t _address; uint8_t _address;
uint8_t _data; uint8_t _data;
int _error; int _error;
TwoWire* _wire;
}; };
#endif #endif

View File

@ -11,7 +11,7 @@
#include "Wire.h" #include "Wire.h"
#include "Max44009.h" #include "Max44009.h"
Max44009 myLux(0xCB); // default addr Max44009 myLux(MAX44009_DEFAULT_ADDRESS);
uint32_t lastDisplay = 0; uint32_t lastDisplay = 0;

View File

@ -0,0 +1,51 @@
//
// FILE: max44009_test02.ino
// AUTHOR: Moritz Ulmer
// VERSION: 0.3.0
// PURPOSE: demo of max44009 library
// 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.
// See switch S1 / jp1 in the schematics.
// DATE: 2020-01-19
//
// Released to the public domain
//
#include "Max44009.h"
#include "Wire.h"
// Don't begin I2C interface (Wire). Will be called in setup()
Max44009 myLuxA(Max44009::Boolean::False);
Max44009 myLuxB(Max44009::Boolean::False);
Max44009 myLuxC(Max44009::Boolean::False);
Max44009 myLuxD(Max44009::Boolean::False);
uint32_t lastDisplay = 0;
void setup()
{
Serial.begin(115200);
Serial.print("Start max44009_test02 : ");
Serial.println(MAX44009_LIB_VERSION);
Wire.begin(19, 18);
Wire1.begin(22, 23);
myLuxA.configure(MAX44009_DEFAULT_ADDRESS, &Wire);
myLuxB.configure(MAX44009_ALT_ADDRESS, &Wire);
myLuxC.configure(MAX44009_DEFAULT_ADDRESS, &Wire1);
myLuxD.configure(MAX44009_ALT_ADDRESS, &Wire1);
}
void loop() {
if (millis() - lastDisplay >= 1000) {
lastDisplay += 1000;
Serial.println("Sensor|Error|Lux");
Serial.printf("A |%d |%f\n", myLuxA.getError(), myLuxA.getLux());
Serial.printf("B |%d |%f\n", myLuxB.getError(), myLuxB.getLux());
Serial.printf("C |%d |%f\n", myLuxC.getError(), myLuxC.getLux());
Serial.printf("D |%d |%f\n", myLuxD.getError(), myLuxD.getLux());
}
}
// END OF FILE

View File

@ -31,25 +31,46 @@ Max44009::Max44009(const uint8_t address, const uint8_t dataPin, const uint8_t c
_address = address; _address = address;
_data = 0; _data = 0;
_error = 0; _error = 0;
_wire = &Wire;
if ((dataPin < 255) && (clockPin < 255)) if ((dataPin < 255) && (clockPin < 255))
{ {
Wire.begin(dataPin, clockPin); _wire->begin(dataPin, clockPin);
} else { } else {
Wire.begin(); _wire->begin();
} }
// TWBR = 12; // Wire.setClock(400000); // TWBR = 12; // _wire->setClock(400000);
} }
#endif #endif
Max44009::Max44009(const uint8_t address) Max44009::Max44009(const uint8_t address, Boolean begin)
{ {
_address = address; _address = address;
_data = 0; _data = 0;
_error = 0; _error = 0;
_wire = &Wire;
Wire.begin(); if(begin == Boolean::True) {
// TWBR = 12; // Wire.setClock(400000); _wire->begin();
}
// TWBR = 12; // _wire->setClock(400000);
}
Max44009::Max44009(const Boolean begin)
{
_address = MAX44009_DEFAULT_ADDRESS;
_data = 0;
_error = 0;
_wire = &Wire;
if(begin == Boolean::True) {
_wire->begin();
}
}
void Max44009::configure(const uint8_t address, TwoWire *wire) {
_address = address;
_wire = wire;
} }
float Max44009::getLux(void) float Max44009::getLux(void)
@ -169,32 +190,32 @@ float Max44009::getThreshold(uint8_t reg)
uint8_t Max44009::read(uint8_t reg) uint8_t Max44009::read(uint8_t reg)
{ {
Wire.beginTransmission(_address); _wire->beginTransmission(_address);
Wire.write(reg); _wire->write(reg);
_error = Wire.endTransmission(); _error = _wire->endTransmission();
if (_error != 0) if (_error != 0)
{ {
return _data; // last value return _data; // last value
} }
if (Wire.requestFrom(_address, (uint8_t) 1) != 1) if (_wire->requestFrom(_address, (uint8_t) 1) != 1)
{ {
_error = 10; _error = 10;
return _data; // last value return _data; // last value
} }
#if (ARDUINO < 100) #if (ARDUINO < 100)
_data = Wire.receive(); _data = _wire->receive();
#else #else
_data = Wire.read(); _data = _wire->read();
#endif #endif
return _data; return _data;
} }
void Max44009::write(uint8_t reg, uint8_t value) void Max44009::write(uint8_t reg, uint8_t value)
{ {
Wire.beginTransmission(_address); _wire->beginTransmission(_address);
Wire.write(reg); _wire->write(reg);
Wire.write(value); _wire->write(value);
_error = Wire.endTransmission(); _error = _wire->endTransmission();
} }
// --- END OF FILE --- // --- END OF FILE ---