Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Automatic Brightness using TSL2561 Sensor for OpenAuto Pro
#1
Created this service to control brightness automatically.

Using the TSL2561 Senson on the i2c bus the brightness is controlled at the OS level and does not interfere with OpenAuto Pro.

I hope is useful to you guys!

Python Code:
Code:
#!/usr/bin/python3 -u

import smbus
import os
import subprocess
from time import sleep


# Originally Used in Crankshaft.
# Kudos to the guys at Crankshaft for giving me a headstart for controlling the  brightness using the TSL2561
#
# This file was re written to write the brightness variable in /sys/class/backlight/rpi_backlight/brightness
# re written by PlasmaFlow 1/22/19

def get_var(varname):
    try:
        CMD = 'echo $(source /opt/lightsensor/lightsensor_env.sh; echo $%s)' % varname
        p = subprocess.Popen(CMD, stdout=subprocess.PIPE, shell=True, executable='/bin/bash')
        return int(p.stdout.readlines()[0].strip())
    except:
        CMD = 'echo $(source /opt/lightsensor/lightsensor_default_env.sh; echo $%s)' % varname
        p = subprocess.Popen(CMD, stdout=subprocess.PIPE, shell=True, executable='/bin/bash')
        return int(p.stdout.readlines()[0].strip())
# ---------------------------------
# the addresss of TSL2561 can be
# 0x29, 0x39 or 0x49
BUS = 1
TSL2561_ADDR = 0x39

daynight_gpio = get_var('DAYNIGHT_PIN')
# ---------------------------------
i2cBus = smbus.SMBus(BUS)

# Start messure with 402 ms
# (scale factor 1)
i2cBus.write_byte_data(TSL2561_ADDR, 0x80, 0x03)
lastvalue = 0

while True:
# read global brightness read low byte
  LSB = i2cBus.read_byte_data(TSL2561_ADDR, 0x8C)
# read high byte
  MSB = i2cBus.read_byte_data(TSL2561_ADDR, 0x8D)
  Ambient = (MSB << 8) + LSB
#print ("Ambient: {}".format(Ambient))
# read infra red read low byte
  LSB = i2cBus.read_byte_data(TSL2561_ADDR, 0x8E)
# read high byte
  MSB = i2cBus.read_byte_data(TSL2561_ADDR, 0x8F)
  Infrared = (MSB << 8) + LSB
#print ("Infrared: {}".format(Infrared))
# Calc visible spectrum
  Visible = Ambient - Infrared
#print ("Visible: {}".format(Visible))
# Calc factor Infrared/Ambient
  Ratio = 0
  Lux = 0
  if Ambient != 0:
    Ratio = float(Infrared)/float(Ambient)
    #print ("Ratio: {}".format(Ratio))
    # Calc lux based on data sheet TSL2561T T, FN, and CL Package
  if 0 < Ratio <= 0.50:
    Lux = 0.0304*float(Ambient) - 0.062*float(Ambient)*(Ratio**1.4)
  elif 0.50 < Ratio <= 0.61:
    Lux = 0.0224*float(Ambient) - 0.031*float(Infrared)
  elif 0.61 < Ratio <= 0.80:
    Lux = 0.0128*float(Ambient) - 0.0153*float(Infrared)
  elif 0.80 < Ratio <= 1.3:
    Lux = 0.00146*float(Ambient) - 0.00112*float(Infrared)
  else:
    Lux = 0

  Luxrounded = round(Lux,1)
  if lastvalue != Luxrounded:
    print ("Lux = {}\n".format(Luxrounded))
    os.system("echo {} > /tmp/tsl2561".format(Luxrounded))
    lastvalue = Luxrounded
    #Set display brigthness
  if Luxrounded <= get_var('LUX_LEVEL_1'):
    #os.system("xbacklight -set " + str(get_var('DISP_BRIGHTNESS_1')) + " &")
    file = open("/sys/class/backlight/rpi_backlight/brightness", "w")
    file.write(str(get_var('DISP_BRIGHTNESS_1')))
    file.close()
    step = 1
  elif Luxrounded > get_var('LUX_LEVEL_1') and Luxrounded < get_var('LUX_LEVEL_2'):
    #os.system("xbacklight -set " + str(get_var('DISP_BRIGHTNESS_2')) + " &")
    file = open("/sys/class/backlight/rpi_backlight/brightness", "w")
    file.write(str(get_var('DISP_BRIGHTNESS_2')))
    file.close()
    step = 2
  elif Luxrounded >= get_var('LUX_LEVEL_2') and Luxrounded < get_var('LUX_LEVEL_3'):
    #os.system("xbacklight -set  " + str(get_var('DISP_BRIGHTNESS_3')) + " &")
    file = open("/sys/class/backlight/rpi_backlight/brightness", "w")
    file.write(str(get_var('DISP_BRIGHTNESS_3')))
    file.close()
    step = 3
  elif Luxrounded >= get_var('LUX_LEVEL_3') and Luxrounded < get_var('LUX_LEVEL_4'):
    #os.system("xbacklight -set  " + str(get_var('DISP_BRIGHTNESS_4')) + " &")
    file = open("/sys/class/backlight/rpi_backlight/brightness", "w")
    file.write( str(get_var('DISP_BRIGHTNESS_4')))
    file.close()
    step = 4
  elif Luxrounded >= get_var('LUX_LEVEL_5'):
    #os.system("xbacklight -set  " + str(get_var('DISP_BRIGHTNESS_5')) + " &")
    file = open("/sys/class/backlight/rpi_backlight/brightness", "w")
    file.write(str(get_var('DISP_BRIGHTNESS_5')))
    file.close()
    step = 5

  if daynight_gpio == 0:
    if step <= get_var('TSL2561_DAYNIGHT_ON_STEP'):
      print("Lux = {} | ".format(Luxrounded) + "Level " + str(step) + " -> trigger night")
      os.system("touch /tmp/night_mode_enabled >/dev/null 2>&1")
    else:
      if step > get_var('TSL2561_DAYNIGHT_ON_STEP'):
        print("Lux = {} | ".format(Luxrounded) + "Level " + str(step) + " -> trigger day")
        os.system("sudo rm /tmp/night_mode_enabled >/dev/null 2>&1")

sleep (get_var('TSL2561_CHECK_INTERVAL'))


Service File

Code:
[Unit]
Description=Pi Lightsensor Service
ConditionPathExists=/opt/lightsensor/service_lightsensor.py
ConditionPathExists=/opt/lightsensor/lightsensor_env.sh
ConditionPathExists=/sys/class/backlight/rpi_backlight/brightness


[Service]
Type=simple
ExecStart=/opt/lightsensor/service_lightsensor.py
ExecStartPost=/bin/touch /tmp/auto_brightness_active
ExecStop=/bin/rm /tmp/auto_brightness_active
Restart=on-failure
StartLimitInterval=60
RestartSec=5
StartLimitBurst=3

[Install]
WantedBy=multi-user.target


ReadMe Info

Code:
Written by PlasmaFlow with sources form Crankshaft and others.
Date 1/22/2019 plasmaflow@ivns.net

This software allows the use of a TSL2561 Sensor to control the brightness of the Raspberry Pi Screen automatically.

The service writes the brightness value to the brightness file on the Pi at:

/sys/class/backlight/rpi_backlight/brightness

Files included are:

lightsensor_default_env.sh - default settings file - py script looks here if the custom file is not there.
lightsensor_env.sh - custom settings file py script looks here first.
lightsensor.service - Service definition file.
service_lightsensor.py


### Software

The software is installed with the following commands:

    sudo mkdir -p /opt/lightsensor
    Copy the files to /opt/lightsensor
    chmod +x service_lightsensor.py
    chmod +x lightsensor_default_env.sh
    chmod +x lightsensor_env.sh
    sudo cp lightsensor.service /etc/systemd/system
    sudo systemctl enable lightsensor.service
    sudo systemctl start lightsensor.service



### Sample Service Status

pi@raspberrypi:/opt/lightsensor $ sudo service lightsensor status
â lightsensor.service - Pi Lightsensor Service
   Loaded: loaded (/etc/systemd/system/lightsensor.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-01-22 19:09:44 EST; 30min ago
  Process: 374 ExecStop=/bin/rm /tmp/auto_brightness_active (code=exited, status=0/SUCCESS)
  Process: 383 ExecStartPost=/bin/touch /tmp/auto_brightness_active (code=exited, status=0/SUCCESS)
Main PID: 381 (service_lightse)
   CGroup: /system.slice/lightsensor.service
           ââ  381 /usr/bin/python3 -u /opt/lightsensor/service_lightsensor.py
           ââ14575 /usr/bin/python3 -u /opt/lightsensor/service_lightsensor.py

Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:39 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:40 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:40 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Jan 22 19:40:40 raspberrypi service_lightsensor.py[381]: Lux = 8.7 | Level 2 -> trigger night
Warning: lightsensor.service changed on disk. Run 'systemctl daemon-reload' to reload units.


### References
The rerefence folder includes installation guides and reference material used to modify the scripts and service.

Environment File
Code:
# Originally Used in Crankshaft.
# Kudos to the guys at Crankshaft for giving me a headstart for controlling the  brightness using the TSL2561
#
# GPIO Trigger for Day/Night
# GPIO wich triggers Day (open gpio)/Night (closed to gnd) of GUI
# To disable set to 0
# If enabled it overrides lightsensor!
DAYNIGHT_PIN=0

### Screen ###
# Brightness related stuff
# brightness file (default for rpi display: /sys/class/backlight/rpi_backlight/brightness)
BRIGHTNESS_FILE=/sys/class/backlight/rpi_backlight/brightness

# brightness values
BR_MIN=30
BR_MAX=255
BR_STEP=25
BR_DAY=255
BR_NIGHT=30

# Custom brightness control
# Note: this command is called after every brightness change - can slow down for example the brightness
# slider depending on execution speed - the process is called with "&" so call is not waiting for exit!
# Sample call which will be executed on request: "CUSTOM_BRIGHTNESS_COMMAND brightnessvalue &"
#
# Note: To allow backup and restore your command must be located on /boot/crankshaft/custom/
# otherwise it will not be transfered during updates!
#
# To disable leave empty
CUSTOM_BRIGHTNESS_COMMAND=

# Auto brightness control based on tsl2561 light sensor
# Check interval sensor 5,10,15,20,25,30
TSL2561_CHECK_INTERVAL=10
# Switch to night on this level or lower (0 = disabled / 1-5)
TSL2561_DAYNIGHT_ON_STEP=2
# Switch levels for brightness sensor in lux
LUX_LEVEL_1=5
LUX_LEVEL_2=20
LUX_LEVEL_3=100
LUX_LEVEL_4=200
LUX_LEVEL_5=500
# Set this display brightness by switch levels
DISP_BRIGHTNESS_1=30
DISP_BRIGHTNESS_2=90
DISP_BRIGHTNESS_3=150
DISP_BRIGHTNESS_4=210
DISP_BRIGHTNESS_5=255


Attached Files
.zip   TSL2561 Luminosity Sensor & Python (detect IR and visible light).zip (Size: 134.27 KB / Downloads: 75)
Reply
#2
Im gonna steal few lines of code and just use simple sunrise/sunset modifications. Thanks for inspiration!
Reply
#3
I have an external monitor connected to the pi HDMI output.  I think I'm going to use an external backlight driver for my screen as I really want it to be automatic.  Is this adaptable to an external driver?  I love the idea of automatic day night switching.
Reply
#4
Hello, can you please give me instructions how to install this and can you please give me the files to download

I connected the sensor and created the files with the above codes and copied them to the raspberry, according to the instructions in the readme.

I probably did not create the files correctly or did anything wrong, unfortunately I am still a beginner with the raspberry.

The terminal it shows me this:


Attached Files
.jpg   error.JPG (Size: 88.79 KB / Downloads: 516)
Reply
#5
I found the problem. In the original Service File Code from PlasmaFlow.

The line "ExecStart=/opt/lightsensor/service_lightsensor.py" is wrong, it's missing /usr/bin/python3.

The corrected Code is:
Code:
[Unit]
Description=Pi Lightsensor Service
ConditionPathExists=/opt/lightsensor/service_lightsensor.py
ConditionPathExists=/opt/lightsensor/lightsensor_env.sh
ConditionPathExists=/sys/class/backlight/rpi_backlight/brightness


[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/lightsensor/service_lightsensor.py
ExecStartPost=/bin/touch /tmp/auto_brightness_active
ExecStop=/bin/rm /tmp/auto_brightness_active
Restart=on-failure
StartLimitInterval=60
RestartSec=5
StartLimitBurst=3

[Install]
WantedBy=multi-user.target


In the Zip folder are the files that work for me


Attached Files
.zip   TSL2561.zip (Size: 3.8 KB / Downloads: 45)
Reply
#6
Will this work with official 7" touchscreen as automatic backlight brightness?

Also I wonder how can I connect both TSL2561 and DS3231 as they both use the same gpio pins

edit: newermind i found old usb gps dongle and im using it to sync my time
Reply
#7
They are using i2c protocol - you can connect there more then one device.
Reply
#8
Today I wired "photoresistor" and 10Uf capacitor ..
and wired up like in the link provided.
I must say it works perfect.
https://github.com/dandydanny/PiAutoDim
Reply
#9
I had problems getting the TSL2561 working so tried using a photo ressistor and 10uf cap, worked without problem, i did change the min light level from 12 to 30, 12 was too dark Big Grin
Reply
#10
I can not download the file attached to this text. I would like to receive a separate link or email.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)