» » » » Controlling Light Brightness using PWM sensor

Controlling Light Brightness using PWM sensor

posted in: Light Sensors, Sensors | 0

Many a times during a day we all must have come across a situation when we feel like controlling the intensity of the light. Sometimes, we need it bright and other times we need it to be dim or off. It is very irritating when we have to physically go to the switch to turn it on or off, every time. Moreover, we cannot control the light intensity as per our requirement and it causes extra consumption of energy.

Here is a quick and painless way to control the intensity as per the requirements. It has no soldering joints, trouble-free connections with boundless ways to interface the sensors with the the Raspberry Pi module.

This will control your lights without any hassle. You just need to follow the undermentioned  instructions.

Seems amazing? So let’s get started!!


Parts Required:


  1. Raspberry Pi 2
  2. I2C shield
  3. TCS34903- Light and Color I2C Mini Module
  4. PCA9530 -PWM I2C Mini Module
  5. I2C cables
  6. Micro USB and Ethernet cable


Here, we are demonstrating it using an LED instead of light so we require the following things along with the above mentioned things:


  1. Breadboard
  2. Red LED
  3. Resistance
  4. Connecting cables




About the sensors used:

Sensors used here are plug and play I2C modules with 2 ports: I2C in and I2C out port. It operating voltage is 5V.

TCS34903 is used here to detect the luminance and using this luminance value, PCA9530 will vary the intensity of the external light source(LED in our case). Basically, PCA9530 is a I2C mini module to control the LED with duty cycle linked to the PWM.



The requisite connections are as follows:

  • Firstly, take a Raspberry Pi board and an I2C header.
  • This will work over I2C. We will place the I2C shield over  Raspberry pi(as shown in the picture below) and gently connect it on to  the gpio pins of Raspberry Pi.
  • Connect the one end of I2C cable to the in-port of TCS34903 sensor and the other end to the I2C shield.
  • Then, Connect the PCA9530 sensor’s in-pot to the TCS34903’s out using I2C cable.
  • Connect the Ethernet cable to Raspberry Pi .Wi-Fi router can also be used for the same.


  • Then, power the Raspberry Pi using a Micro USB adapter.
  • Finally, connect the LED through  resistor to the channel 1 of PCA9530. You can connect light with PCA9530.



Communicating using I2C Protocol:


To make Raspberry Pi I2C enabled, proceed as mentioned below:

  • In terminal, type the following command to open the configuration settings:
    sudo raspi-config
  • Select “Advanced Options” in here.
  • Select “I2C” and Click “Yes”.
  • Reboot the system to set it up as per the changes made using the command reboot.


Programming the module:


The reward of using Raspberry Pi is, that is provides you the flexibility to opt a the programming language in which you want to program to interface the sensing device with Raspberry Pi. Harnessing this advantage of Raspberry Pi, we are demonstrating here its programming in the Java.


To set up the Java environment, Install the “pi4j libraby” from http://pi4j.com/install.html. Pi4j is a Java Input/Output Library for Raspberry Pi.
An easy and most preferred method to install the “pi4j library” is to execute the undermentioned command directly in your Raspberry Pi:

curl -s get.pi4j.com | sudo bash
curl -s get.pi4j.com



import java.nio.channels.WritableByteChannel;
import java.nio.ByteBuffer;
import com.pi4j.io.i2c.I2CBus;
import com.pi4j.io.i2c.I2CDevice;
import com.pi4j.io.i2c.I2CFactory;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class PCA9530

   public final static int PCA9530_ADDRESS = 0x60;

   // I2C Registers (currently unused ones are commented out)

   public final static int  INPUT    = 0x00;
   public final static int  PSC0     = 0x01;
   public final static int  PWM0     = 0x02;
   public final static int  PSC1     = 0x03;
   public final static int  PWM1     = 0x04;
   public final static int  LSEL     = 0x05;

   public static int  val     = 0x00;


   // Flags and modes

  /*public final static int  FLAG_AI    = 1 << 4

  public final static int  LED0_OFF   = LED1_OFF   = 0b00
  public final static int  LED0_ON    = LED1_ON    = 0b01
  public final static int  LED0_RATE0 = LED1_RATE0 = 0b10
  public final static int  LED0_RATE1 = LED1_RATE1 = 0b11


   // Constants

   public final static int  PWM_CHANNELS   = 2;
   public final static int  PWM_RESOLUTION = 8;
   public final static int  DAC_CHANNELS   = 2;
   public final static int  DAC_RESOLUTION = 8;
   public final static int  GPIO_CHANNELS  = 6;
   public final static int  GPIO_BANKS     = 3;
   public final static int  VREF           = 1; // Unused but must be set for DAC class init, so 1.0 is used

   // Defaults

   public final static int   D_PWM0      = 0x80;
   public final static int   D_PWM1      = 0x80;
  private static boolean verbose = true;//.equals(System.getProperty("htu21df.verbose", "false"));

 private I2CBus bus;
 private I2CDevice pca9530;
 public PCA9530(int address) throws Exception




     // Get i2c bus

     I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1); // Depends onthe RasPI version

     if (verbose)
       System.out.println("Connected to bus. OK.");

     // Get device itself
    pca9530 = bus.getDevice(address);

      if (verbose)
       System.out.println("Connected to device. OK.");
   catch (IOException e)
   public void setLed()
           pca9530.write(LSEL,(byte) 0xFA);

       catch (Exception e)
   public void setFrequency(int period)
           pca9530.write(PSC0,(byte) period);
          pca9530.write(PSC1,(byte) period);
      catch (Exception e)
   public void setPWM(int value)
       catch (Exception e)
public static void main(String[] args) throws Exception  
      PCA9530 sensor = new PCA9530(0x60);
      // Create I2C bus

I2CBus bus = I2CFactory.getInstance(I2CBus.BUS_1);
// Get I2C device, TCS34903 I2C address is 0x39(55)
I2CDevice device = bus.getDevice(0x39);
// Set Wait Time register = 0xff(255), wait time = 2.78 ms
device.write(0x83, (byte)0xFF);
// Enable Access to IR channel
device.write(0xC0, (byte)0x80);
// Set Atime register to 0x00(0), maximum counts = 65535
device.write(0x81, (byte)0x00);
// Power ON, ADC enabled, Wait enabled
device.write(0x80, (byte)0x0B);
// Read 2 bytes of data from address 0x94(148)
byte[] data = new byte[2];
device.read(0x94, data, 0, 2);
int ir = (((data[1] & 0xff) * 256) + (data[0] & 0xff));
// Read 2 bytes of data from address 0x96(150)
device.read(0x96, data, 0, 2);
int red = (((data[1] & 0xff) * 256) + (data[0] & 0xff));
// Read 2 bytes of data from address 0x98(152)
device.read(0x98, data, 0, 2);
int green = (((data[1] & 0xff) * 256) + (data[0] & 0xff));
// Read 2 bytes of data from address 0x9A(154)
device.read(0x9A, data, 0, 2);
int blue = (((data[1] & 0xff) * 256) + (data[0] & 0xff));
// Calculate luminance
double luminance = (-0.32466) * (red) + (1.57837) * (green) + (-0.73191) * (blue);
val = (int)((((-255*luminance)/15000)) + 255);
// Output data to Screen
System.out.println("Value = " +  val );
System.out.printf("IR  luminance is : %d lux %n", ir);
System.out.printf("Red color luminance is : %d lux %n", red);
System.out.printf("Green color luminance is : %d lux %n", green);
System.out.printf("Blue color luminance is : %d lux %n", blue);
System.out.printf("Total luminance is : %.2f lux %n", luminance);





Sensor applications:
The TCS34903 applications are:

  • Ambient Light Sensing
  • Color Temperature Sensing
  • Industrial Process Control
  • Medical Diagnostics


The PCA9530 applications are:

  • LED dimming
  • PWM


This has its applications in industry or medical or at places where one needs to control Light intensity automatically.


PCA9530 datasheet

TCS34903 datasheet

Leave a Reply