Ambient light based LED brightness controller

The main aim of this experiment is to control the brightness of a LED based on the amount of ambient light available in the room. We will be performing this experiment using the Witty Fox ESP 32 Dev Board and Witty Fox OPT3001 Breakout board. The OPT3001 is a single-chip lux meter, measuring the intensity of light as visible by the human eye. The precision spectral response and strong IR rejection of the device enable the OPT3001 to accurately meter the intensity of light as seen by the human eye regardless of the light source. The OPT3001 breakout is directly compatible with the WittyFox ESP 32 Dev Board through the dedicated I2C ports P9 or P10.

 

Absolute Maximum Ratings (From Datasheet)

 Parameter

 

MIN     

MAX

UNIT

Voltage

VDD to GND

–0.5

6

V

SDA, SCL, INT and ADDR to GND

–0.5

6

V

Current into any pin

 

 

10

mA

Temperature

Junction

 

150

°C

Storage, Tstg

–65

+150(2)

°C

 

 

This experiment requires certain prerequisites on programming the Witty Fox ESP 32 Dev Board. Please refer to the following links to learn more about the same.

To learn about programming the Witty Fox ESP 32 Dev Board using Witty Fox programmer (or any generic USB to TTL converter), please refer to the following link: WITTY FOX ESP PROGRAMMER

The code for this experiment is given below. Link for the libraries required is given below:
OPT3001 library:
https://github.com/closedcube/ClosedCube_OPT3001_Arduino


Upload the following code to an ESP32 module. Once uploaded, you can control the brightness of the LED by varying the amount of light falling on the sensor.

Code:

/*
  WittyFox OPT3001 experiment

  Demonstrates the capabilities of the WittyFox ESP 32 Dev Board.

  This sketch controls the brightness of a LED, based on the ambient light present in an environment.

*/

#include <Wire.h>
#include <ClosedCube_OPT3001.h>
ClosedCube_OPT3001 opt3001;

constint ledPin = 2;  // 2 corresponds to GPIO2 which is connected to on-board LED

// setting PWM properties
constint freq = 5000;
constint ledChannel = 0;
constint resolution = 8;
longint dutyCycle;

#define OPT3001_ADDRESS 0x44

voidsetup()
{
  Serial.begin(115200);
  Serial.println("ClosedCube OPT3001 Test");
 
  // configure LED PWM functionalitites
  ledcSetup(ledChannel, freq, resolution);
 
  // attach the channel to the GPIO to be controlled
  ledcAttachPin(ledPin, ledChannel);
 
  opt3001.begin(OPT3001_ADDRESS);
  Serial.print("OPT3001 Manufacturer ID");
  Serial.println(opt3001.readManufacturerID());
  Serial.print("OPT3001 Device ID");
  Serial.println(opt3001.readDeviceID());

  configureSensor();
  printResult("High-Limit", opt3001.readHighLimit());
  printResult("Low-Limit", opt3001.readLowLimit());
  Serial.println("----");
}

voidloop()
{
  OPT3001 result = opt3001.readResult();
  printResult("OPT3001", result);
  dutyCycle = map(result.lux , 0, 20000, 0, 255); // ambient lighting in the room generally varies from 0-20000
  ledcWrite(ledChannel, dutyCycle);
  delay(50);
}

voidconfigureSensor() {
  OPT3001_Config newConfig;
 
  newConfig.RangeNumber = B1100; 
  newConfig.ConvertionTime = B0;
  newConfig.Latch = B1;
  newConfig.ModeOfConversionOperation = B11;

  OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
  if (errorConfig != NO_ERROR)
    printError("OPT3001 configuration", errorConfig);
  else {
    OPT3001_Config sensorConfig = opt3001.readConfig();
    Serial.println("OPT3001 Current Config:");
    Serial.println("------------------------------");
   
    Serial.print("Conversion ready (R):");
    Serial.println(sensorConfig.ConversionReady,HEX);

    Serial.print("Conversion time (R/W):");
    Serial.println(sensorConfig.ConvertionTime, HEX);

    Serial.print("Fault count field (R/W):");
    Serial.println(sensorConfig.FaultCount, HEX);

    Serial.print("Flag high field (R-only):");
    Serial.println(sensorConfig.FlagHigh, HEX);

    Serial.print("Flag low field (R-only):");
    Serial.println(sensorConfig.FlagLow, HEX);

    Serial.print("Latch field (R/W):");
    Serial.println(sensorConfig.Latch, HEX);

    Serial.print("Mask exponent field (R/W):");
    Serial.println(sensorConfig.MaskExponent, HEX);

    Serial.print("Mode of conversion operation (R/W):");
    Serial.println(sensorConfig.ModeOfConversionOperation, HEX);

    Serial.print("Polarity field (R/W):");
    Serial.println(sensorConfig.Polarity, HEX);

    Serial.print("Overflow flag (R-only):");
    Serial.println(sensorConfig.OverflowFlag, HEX);

    Serial.print("Range number (R/W):");
    Serial.println(sensorConfig.RangeNumber, HEX);

    Serial.println("------------------------------");
  }
 
}

voidprintResult(String text, OPT3001 result) {
  if (result.error == NO_ERROR) {
    Serial.print(text);
    Serial.print(": ");
    Serial.print(result.lux);
    Serial.println(" lux");
  }
  else {
    printError(text,result.error);
  }
}

voidprintError(String text, OPT3001_ErrorCode error) {
  Serial.print(text);
  Serial.print(": [ERROR] Code #");
  Serial.println(error);
}