MAX44009 Ambient Light Sensor

MAX44009 Ambient Light Sensor

This section deals with the configuration of the MAX44009 ambient light sensor.

Application

TBA

Configuration

Hardware

The MAX44009 sensor module is configured on an I2C bus with a 3.3V supply voltage.

The other two, unmarked pins on the sensor module set the [upper pin] I2C address—tie to GND to set the address to 0x4A or 3V3 to set it to 0x4B—and the [lower pin] interrupt status—if using interrupts, connect to an appropriate processor pin and a pull-up resistor. The configurations illustrated below set the sensor module I2C address to 0x4A and enable the detection of interrupts generated by the sensor module.

CubeCell Plus - MAX44009 Hardware Configuration

CubeCell Plus - MAX44009 Electrical Circuit

NodeMCU - MAX44009 Hardware Configuration

NodeMCU - MAX44009 Electrical Circuit
Pin Configurations
CubeCell Plus NodeMCU MAX44009
Vext 3V3 VIN
GND GND GND
SCL D1 SCL
SDA D2 SDA
GND GND ADDR [0x4A]
GPIO1 (Pull-Up) D3 (Pull-Up) INT

The I2C address can also be set by bridging the solder jumpers on the module—bridge the upper two pads to set I2C address 0x4A, as shown in the image below, or the lower two to set I2C address 0x4B.

MAX44009

I2C Address Jumpers

Software

Since communication with the sensor is via an I2C bus, that part of the required software is identical for the two platforms. The difference between the two, with the hardware configurations as illustrated, is that the CubeCell Plus configuration supplies power to the sensor via Vext, which must therefore be explicitly turned on before the sensor is used.

See Rob Tillaart MAX44009 library and, one way or another, we will ultimately want to include code to detect/process interrupts, just for the exercise in demonstrating/understanding how they work, if nothing else..


Ambient Light Meter
#include <Wire.h>             			// I2C bus
#include "NodeMCUPins.h"      			// NodeMCU Pin Definitions

const int I2C_SCL = NodeMCU_D1;
const int I2C_SDA = NodeMCU_D2;

// MAX44009

const int I2C_MAX_ADDRESS = 0x4A;		// MAX44009 sensor address
uint16_t lightLevel = 0;

const int reportInterval = 1000;		// Report values every 1000 milliseconds

void setup() {
  Serial.begin(115200);
  while (!Serial);									// Wait until the Serial port is active
  Serial.print("[setup] I2C Light Level Sensor");
  Serial.println();

	// Initialise the I2C Bus

  Wire.begin();

// Initialise the MAX44009 sensor

  Serial.println("[setup] Initialise MAX44009 sensor");
  Wire.begin(I2C_SDA,I2C_SCL); 
  Wire.beginTransmission(I2C_MAX_ADDRESS);
  Wire.write(0x02);
  Wire.write(0x40);
  Wire.endTransmission();

  Serial.println("[setup] Set-up Complete");
  Serial.println(); 
}

void loop() {

// Take a reading from the MAX44009 sensor

  unsigned int data[2];
  Wire.beginTransmission(I2C_MAX_ADDRESS);
  Wire.write(0x03);
  Wire.endTransmission();
   
  // Request 2 bytes of data
  Wire.requestFrom(I2C_MAX_ADDRESS, 2);
   
  // Read 2 bytes of data luminance msb, luminance lsb
  if (Wire.available() == 2)
  {
    data[0] = Wire.read();
    data[1] = Wire.read();
  }
   
  // Convert the data to lux
  int exponent = (data[0] & 0xF0) >> 4;
  int mantissa = ((data[0] & 0x0F) << 4) | (data[1] & 0x0F);
  float luminance = pow(2, exponent) * mantissa * 0.045;
  lightLevel = (int)((luminance + 0.005) * 100);
  Serial.print("[loop] Ambient Light luminance : ");
  Serial.print(luminance);
  Serial.print(" lux [Light Level: ");
  Serial.print((float)lightLevel/100);
  Serial.println("]");

  delay(reportInterval);
}

Further details pending

03-09-2026