I am using a BH1750 to control the brightness of my 7" display and will
try to describe how I have done it.

Beside of your RaspberryPi, display and the Audio-HAT, you need the
following hardware:

    
-   BH1750 (digital light sensor) 
-   Pin header 1 x 5 pin angled pitch 2.54, e.g. SL25WS5GC 
-   Jumper cable (female - female) 
-   SmartiPi Touch 2, case for official 7" Touchscreen Display and
  Raspberry Pi 
-   Backcover for SmartiPi Touch 2, 35mm 
  

The BH1750 is a digital light sensor using the I2C bus and it is
delivered with a straight pin header. The BH1750 is more compact with an
angled pin header and fits better into the case.

The SmartiPi Touch 2 is designed to house a RPi, the official 7" display
and the official camera. The space for the camera is very helpful
because it can be used by the BH1750. The Touch 2 has not enough space
to house an HAT but it can be extended by an back cover. SmartiPi
provides the back cover in two sizes: 15 mm and 35 mm. You will need the
35 mm version because the cabling on the GPIO header needs some space.

This project uses the Hifiberry Amp2 as audio HAT and I prefer one
single power supply so that the MeanWell GST60A18-P1J 18V DC 3.33A
provides the power for all devices (RPi, display, Amp2 and BH1750). In
case of a DAC, you can power your system via USB -- SmartiPi provides
USB-splitter.

The BH1750 is controlled in this project by a small C program and a
shell script. The following extensions must be loaded via the web page
of the piCorePlayer:
These three are at least required for execution:

    
-   wiringpi.tcz 
-   i2c-tools.tcz 
-   bc.tcz 
  
Additional extensions required for compilation:

    
-   wiringpi-dev.tcz 
-   i2c-tools-dev.tcz 
-   gcc.tcz 
-   gcc_base-dev.tcz 
-   gcc_libs.tcz 
-   gcc_libs-dev.tcz 
-   glibc_base-dev.tcz 
-   glibc_add_lib.tcz 
-   binutils.tcz 
-   flex.tcz 
  
some more extensions might be loaded automatically because of
dependencies.

Per default, I2C is not completely enabled on RPi with pCP. The part in
config.txt is normally already done by pCP. Let's check:
$ m1
$ c1
$ grep i2c config.txt

You should get the following output:
dtparam=i2c_arm=on,spi=on,i2s=on

If not then you must add the entry 'dtparam=i2c_arm=on' to config.txt.
Don't forget to save your changes:
$ pcp bu

Additionally, we need to load the i2c-dev module which is done by 
$ /sbin/modprobe i2c-dev

You can check if the command was successful by
$ lsmod | grep i2c
One line of the output should be as folows:
i2c_dev                20480  0

The module is loaded only for the current runtime and not be available
after a reboot. Therefore, we add the following lines at the end of the
file /opt/bootlocal.sh:

### BH1750 start ------
# Enabling kernel module i2c-dev
/sbin/modprobe i2c-dev
### BH1750 stop ------

Save your changes:
$ pcp bu

The brightness of the official 7" display is controlled by the content
of the file '/sys/class/backlight/rpi_backlight/brightness'. It contains
an integer value in the range of 1 ... 255. The higher the value, the
higher the brightness. But you would need root permission to change the
content of the file. Therefore, we make this file writable for other
users, too. This is done by a new udev rule.

New file:
/etc/udev/rules.d/51-rpi-display.rules

Content:
# udev rules to allow write access to all users for RaspberryPi 7" Touch
Display
SUBSYSTEM=="backlight",RUN+="/bin/chmod 666
/sys/class/backlight/%k/brightness"

Adding filename and path to /opt/.filetool.lst and backup changes via
pCP web page (or via 'pcp bu' on CLI). Note: The file '.filetool.lst'
contains the list of files and folders which are saved by 'pcp bu'.

Before we connect the BH1750, we should reboot the system to activate
the last changes.

The light-sensitive part of the sensor is the small black rectangle
above the lettering "BH1750". The angled pin header should be soldered
on the sensor board so that the pins are on the side opposite of the
sensor (otherwise the pins will cover the sensor which is not what we
want).

The five pins are now connected to the GPIO header of the RPi as
described below:

BH1750 |   RPi       |   Comment
-------|---------|------------------
VCC     | Pin  1    |  3.3V (Power)
GND      | Pin  9    |  GND (Ground)
SCL      | Pin  5   |  GPIO 3 (SCL1)
SDA      | Pin  3   |  GPIO 2 (SDA1)
ADDR    | Pin 14   |  GND (Ground)

Note: I use pin 2 (5V) and 6 (GND) as power supply for the display.

The RPi has two I2C channels (i2c0 and i2c1). I am using i2c1 which is
available via the pins 3 and 5. The channel i2c1 (and its pins) is also
used by the Hifiberry HATs (and probably other audio HATs) but I2C can
handle several devices on one channel -- as long as they have different
addresses. The channel i2c0 is available via the pins 27 and 28 and it
can be activated via config.txt but it is normally reserved for the
EEPROMs of an HAT. I recommend not to activate i2c0 at all because it
causes instabilities in my system.

If the sensor is recognized by the I2C bus can be checked by the command
'i2cdetect -y 1':
$ i2cdetect -y 1
0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- 23 -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                         

The address 0x23h represents the BH1750.

A simple test program from sends the control code for a one-time
measurement in high resolution mode with 1 lux precision to the BH1750.
The value 0x20h, corresponds to 00100000. After a short wait, the code
reads the measurement results. The bytes then return to the correct
order, and display the measurement result.

$ cat lux.c
#include <wiringPiI2C.h>
#include <stdio.h>
#include <unistd.h>

int main (void) {
/* BH1750 uses address 0x23 on the I2C bus */
int handle = wiringPiI2CSetup(0x23);
if (handle == -1) 
return 1;
/* The control code 0x20 tells BH1750 to execute a One-Time
measurement
with high resolution (i.e. 1 lx resolution) */
wiringPiI2CWrite(handle,0x20);
sleep(1);  // Measurement Time is typically 120ms.
int word=wiringPiI2CReadReg16(handle,0x00);
int lux=((word & 0xff00)>>8) | ((word & 0x00ff)<<8);
printf("%d \n",lux);

return 0 ;
}

I stored the file in a new folder of the $HOME-directory of the user
'tc', i.e. under '/home/tc/lux/'. The complete $HOME-directory is
normally saved with a 'pcp bu'.

Save your changes:
$ pcp bu

Now we compile our source code, rename the executable and set the
permissions accordingly.
$ cc lux.c -lwiringPi
$ mv a.out lux && chmod 755 lux

Some results when running 'lux':
tc@SB-Bedroom:~/lux$ ./lux
20 
tc@SB-Bedroom:~/lux$ ./lux
304 

Next we need a tool that sets the brightness of the display according to
the measured light intensity. I use a shell script for this task because
it can be easily adapted. Currently it is still a very basic script but
it fulfils its main task.

$ cat display-control.sh
#!/bin/sh

WDIR=/home/tc/lux
# if the measured value is below MIN_THRESHOLD then the display is set
to MIN_BRIGHTNESS
MIN_THRESHOLD=10
MIN_BRIGHTNESS=10
# if the measured value is above MAX_THRESHOLD then the display is set
to MAX_BRIGHTNESS
MAX_THRESHOLD=1010
MAX_BRIGHTNESS=255
LUX_RANGE=`echo "$MAX_THRESHOLD-$MIN_THRESHOLD" | bc`
BRIGHTNESS_RANGE=`echo "$MAX_BRIGHTNESS-$MIN_BRIGHTNESS" | bc`
STEPSIZE=$(echo "scale=2 ; $LUX_RANGE/$BRIGHTNESS_RANGE" | bc -l | cut
-f1 -d\.);
# time interval between two measurements
INTERVAL=5

# Debugging ...
echo `date` > $WDIR/deleteme

# Let's wait until pCP is up & running
sleep 20

while true; do
# Measuring the current LUX value
LUX=$($WDIR/lux)
# Calculating the target brightness of the display
if [ $LUX -lt $MIN_THRESHOLD ]; then
TRGT=$MIN_BRIGHTNESS
elif [ $LUX -gt $MAX_THRESHOLD ]; then
TRGT=$MAX_BRIGHTNESS
else
TRGT=$(echo "$MIN_BRIGHTNESS+(($LUX-$MIN_THRESHOLD)/$STEPSIZE)" | bc
-l | cut -f1 -d\.);
fi

# Setting the brightness value of the display
echo $TRGT > /sys/class/backlight/rpi_backlight/brightness

# Uncomment for debugging & testing
#    echo $LUX
#    echo $TRGT

# Wait some seconds before the next calculation
sleep $INTERVAL
done

For verifying the configuration, you can execute the script manually
(you should uncomment the lines with 'echo $LUX' and 'echo $TRGT').

$ ./display-control.sh

The script prints now the measured light intensity and the target value
for the brightness of the display.

Save your changes:
$ pcp bu

This script must be executed automatically when the piCorePlayer has
started. This is done by enhancing the BH1750 part in the file
/opt/bootlocal.sh:

### BH1750 start ------
# Enabling kernel module i2c-dev
/sbin/modprobe i2c-dev
# starting shell script to control display brightness
/home/tc/lux/display-control.sh
### BH1750 stop ------

Save your changes:
$ pcp bu

tbc


------------------------------------------------------------------------
jd68's Profile: http://forums.slimdevices.com/member.php?userid=30795
View this thread: http://forums.slimdevices.com/showthread.php?t=112460

_______________________________________________
unix mailing list
[email protected]
http://lists.slimdevices.com/mailman/listinfo/unix

Reply via email to