├── apds9960
├── __init__.py
├── exceptions.py
├── const.py
└── device.py
├── micropython
├── test_ambient.py
├── test_prox.py
└── test_gesture.py
├── rpi
├── test_ambient.py
├── test_prox.py
└── test_gesture.py
├── README.md
├── .gitignore
├── RPi.md
└── LICENSE
/apds9960/__init__.py:
--------------------------------------------------------------------------------
1 | from apds9960.device import APDS9960, uAPDS9960
2 |
3 | __all__ = [ 'APDS9960', 'uAPDS9960', ]
4 |
--------------------------------------------------------------------------------
/apds9960/exceptions.py:
--------------------------------------------------------------------------------
1 | class ADPS9960InvalidDevId(ValueError):
2 | def __init__(self, id, valid_ids):
3 | Exception.__init__(self, "Device id 0x{} is not a valied one (valid: {})!".format(format(id, '02x'), ', '.join(["0x{}".format(format(i, '02x')) for i in valid_ids])))
4 |
5 | class ADPS9960InvalidMode(ValueError):
6 | def __init__(self, mode):
7 | Exception.__init__(self, "Feature mode {} is invalid!".format(mode))
8 |
--------------------------------------------------------------------------------
/micropython/test_ambient.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 |
3 | from machine import Pin, I2C
4 |
5 | from apds9960.const import *
6 | from apds9960 import uAPDS9960 as APDS9960
7 |
8 | bus = I2C(sda=Pin(13), scl=Pin(14))
9 |
10 | apds = APDS9960(bus)
11 |
12 | print("Light Sensor Test")
13 | print("=================")
14 | apds.enableLightSensor()
15 |
16 | oval = -1
17 | while True:
18 | sleep(0.25)
19 | val = apds.readAmbientLight()
20 | if val != oval:
21 | print("AmbientLight={}".format(val))
22 | oval = val
23 |
24 |
--------------------------------------------------------------------------------
/micropython/test_prox.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 |
3 | from machine import Pin, I2C
4 |
5 | from apds9960.const import *
6 | from apds9960 import uAPDS9960 as APDS9960
7 |
8 | bus = I2C(sda=Pin(13), scl=Pin(14))
9 |
10 | apds = APDS9960(bus)
11 |
12 | apds.setProximityIntLowThreshold(50)
13 |
14 | print("Proximity Sensor Test")
15 | print("=====================")
16 | apds.enableProximitySensor()
17 |
18 | oval = -1
19 | while True:
20 | sleep(0.25)
21 | val = apds.readProximity()
22 | if val != oval:
23 | print("proximity={}".format(val))
24 | oval = val
25 |
26 |
--------------------------------------------------------------------------------
/micropython/test_gesture.py:
--------------------------------------------------------------------------------
1 | from time import sleep
2 |
3 | from machine import Pin, I2C
4 |
5 | from apds9960.const import *
6 | from apds9960 import uAPDS9960 as APDS9960
7 |
8 | bus = I2C(sda=Pin(13), scl=Pin(14))
9 |
10 | apds = APDS9960(bus)
11 |
12 | dirs = {
13 | APDS9960_DIR_NONE: "none",
14 | APDS9960_DIR_LEFT: "left",
15 | APDS9960_DIR_RIGHT: "right",
16 | APDS9960_DIR_UP: "up",
17 | APDS9960_DIR_DOWN: "down",
18 | APDS9960_DIR_NEAR: "near",
19 | APDS9960_DIR_FAR: "far",
20 | }
21 |
22 | apds.setProximityIntLowThreshold(50)
23 |
24 | print("Gesture Test")
25 | print("============")
26 | apds.enableGestureSensor()
27 |
28 | while True:
29 | sleep(0.5)
30 | if apds.isGestureAvailable():
31 | motion = apds.readGesture()
32 | print("Gesture={}".format(dirs.get(motion, "unknown")))
33 |
34 |
--------------------------------------------------------------------------------
/rpi/test_ambient.py:
--------------------------------------------------------------------------------
1 | from apds9960.const import *
2 | from apds9960 import APDS9960
3 | import RPi.GPIO as GPIO
4 | import smbus
5 | from time import sleep
6 |
7 | port = 1
8 | bus = smbus.SMBus(port)
9 |
10 | apds = APDS9960(bus)
11 |
12 | def intH(channel):
13 | print("INTERRUPT")
14 |
15 | GPIO.setmode(GPIO.BOARD)
16 | GPIO.setup(7, GPIO.IN)
17 | try:
18 | # Interrupt-Event hinzufuegen, steigende Flanke
19 | GPIO.add_event_detect(7, GPIO.FALLING, callback = intH)
20 |
21 | print("Light Sensor Test")
22 | print("=================")
23 | apds.enableLightSensor()
24 | oval = -1
25 | while True:
26 | sleep(0.25)
27 | val = apds.readAmbientLight()
28 | if val != oval:
29 | print("AmbientLight={}".format(val))
30 | oval = val
31 |
32 | finally:
33 | GPIO.cleanup()
34 | print "Bye"
35 |
--------------------------------------------------------------------------------
/rpi/test_prox.py:
--------------------------------------------------------------------------------
1 | from apds9960.const import *
2 | from apds9960 import APDS9960
3 | import RPi.GPIO as GPIO
4 | import smbus
5 | from time import sleep
6 |
7 | port = 1
8 | bus = smbus.SMBus(port)
9 |
10 | apds = APDS9960(bus)
11 |
12 | def intH(channel):
13 | print("INTERRUPT")
14 |
15 | GPIO.setmode(GPIO.BOARD)
16 | GPIO.setup(7, GPIO.IN)
17 | try:
18 | # Interrupt-Event hinzufuegen, steigende Flanke
19 | GPIO.add_event_detect(7, GPIO.FALLING, callback = intH)
20 |
21 | apds.setProximityIntLowThreshold(50)
22 |
23 | print("Proximity Sensor Test")
24 | print("=====================")
25 | apds.enableProximitySensor()
26 | oval = -1
27 | while True:
28 | sleep(0.25)
29 | val = apds.readProximity()
30 | if val != oval:
31 | print("proximity={}".format(val))
32 | oval = val
33 |
34 | finally:
35 | GPIO.cleanup()
36 | print "Bye"
37 |
--------------------------------------------------------------------------------
/rpi/test_gesture.py:
--------------------------------------------------------------------------------
1 | from apds9960.const import *
2 | from apds9960 import APDS9960
3 | import RPi.GPIO as GPIO
4 | import smbus
5 | from time import sleep
6 |
7 | port = 1
8 | bus = smbus.SMBus(port)
9 |
10 | apds = APDS9960(bus)
11 |
12 | def intH(channel):
13 | print("INTERRUPT")
14 |
15 | GPIO.setmode(GPIO.BOARD)
16 | GPIO.setup(7, GPIO.IN)
17 |
18 | dirs = {
19 | APDS9960_DIR_NONE: "none",
20 | APDS9960_DIR_LEFT: "left",
21 | APDS9960_DIR_RIGHT: "right",
22 | APDS9960_DIR_UP: "up",
23 | APDS9960_DIR_DOWN: "down",
24 | APDS9960_DIR_NEAR: "near",
25 | APDS9960_DIR_FAR: "far",
26 | }
27 | try:
28 | # Interrupt-Event hinzufuegen, steigende Flanke
29 | GPIO.add_event_detect(7, GPIO.FALLING, callback = intH)
30 |
31 | apds.setProximityIntLowThreshold(50)
32 |
33 | print("Gesture Test")
34 | print("============")
35 | apds.enableGestureSensor()
36 | while True:
37 | sleep(0.5)
38 | if apds.isGestureAvailable():
39 | motion = apds.readGesture()
40 | print("Gesture={}".format(dirs.get(motion, "unknown")))
41 |
42 |
43 | finally:
44 | GPIO.cleanup()
45 | print "Bye"
46 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python (and MicroPython) APDS-9960 Library
2 |
3 | Python library for the APDS-9960 gesture sensor developed while I was looking to get the APDS-9960 to work with a _Raspberry Pi_ to build a user interface feeling like in _Minority Report_.
4 |
5 | This library is a port of the [APDS-9960 Raspberry Pi Library](https://bitbucket.org/justin_woodman/apds-9960-raspberry-pi-library) of [Justin Woodman](https://justinwoodman.wordpress.com/2014/11/15/using-the-apds-9960-rgb-proximity-and-gesture-sensor-with-the-raspberry-pi-2/). Sadly his library is coded in C++ and seems not to be maintained any more.
6 |
7 | This library has been tested with [SparkFun RGB and Gesture Sensor - APDS-9960](https://www.sparkfun.com/products/12787) but should work with any other APDS-9960 based I²C device, too.
8 |
9 | Features:
10 | - operational voltage: 3.3V
11 | - ambient light & RGB color sensing
12 | - proximity sensing
13 | - gesture detection
14 | - operating range: 10 - 20cm
15 | - I²C interface (hard wired I²C address: 0x39)
16 |
17 | Documentation:
18 | - [RPi](RPi.md) - connect and configure the APDS-9960 on Raspberry Pi
19 | - Example scripts:
20 | - simple ambient light level demo: [rpi](rpi/test_ambient.py), [micropython](micropython/test_ambient.py)
21 | - simple gesture detection demo: [rpi](rpi/test_gesture.py), [micropython](micropython/test_gesture.py)
22 | - simple proximity level demo: [rpi](rpi/test_prox.py), [micropython](micropython/test_prox.py)
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | env/
12 | build/
13 | develop-eggs/
14 | dist/
15 | downloads/
16 | eggs/
17 | .eggs/
18 | lib/
19 | lib64/
20 | parts/
21 | sdist/
22 | var/
23 | wheels/
24 | *.egg-info/
25 | .installed.cfg
26 | *.egg
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 |
49 | # Translations
50 | *.mo
51 | *.pot
52 |
53 | # Django stuff:
54 | *.log
55 | local_settings.py
56 |
57 | # Flask stuff:
58 | instance/
59 | .webassets-cache
60 |
61 | # Scrapy stuff:
62 | .scrapy
63 |
64 | # Sphinx documentation
65 | docs/_build/
66 |
67 | # PyBuilder
68 | target/
69 |
70 | # Jupyter Notebook
71 | .ipynb_checkpoints
72 |
73 | # pyenv
74 | .python-version
75 |
76 | # celery beat schedule file
77 | celerybeat-schedule
78 |
79 | # SageMath parsed files
80 | *.sage.py
81 |
82 | # dotenv
83 | .env
84 |
85 | # virtualenv
86 | .venv
87 | venv/
88 | ENV/
89 |
90 | # Spyder project settings
91 | .spyderproject
92 | .spyproject
93 |
94 | # Rope project settings
95 | .ropeproject
96 |
97 | # mkdocs documentation
98 | /site
99 |
100 | # mypy
101 | .mypy_cache/
102 |
--------------------------------------------------------------------------------
/RPi.md:
--------------------------------------------------------------------------------
1 | # APDS-9960 on Raspberry Pi
2 |
3 | ## Wiring
4 |
5 | The APDS-9960 can be connected to the I²C bus of the RPi using the P01 header:
6 |
7 | | Board Pin | Function | RPi Pin | RPi Function |
8 | |-----------|--------------|----------|----------------|
9 | | VL | IR LED Power _(optional)_ | n.c. | _(not connected)_
10 | | GND | Ground | P01-9 | GND
11 | | VCC | +3.3V | P01-1 | 3.3V PWR
12 | | SDA | Data | P01-3 | I2C1 SDA
13 | | SCL | Clock | P01-5 | I2C1 SCL
14 | | INT | Interrupt | P01-7 | GPIO 4 _(optional)_
15 |
16 |
17 | ## I²C
18 |
19 | You need to have enabled loading of the I²C kernel module. You might use `raspi-config` to enable I²C:
20 | - run `raspi-config`
21 | - select `5 Interfacing Options`
22 | - enable `P5 I2C`
23 |
24 | The APDS-9960 supports a I²C clock up to 400KHz (default is 100KHz). To speed up detection performance you should increase the clock rate be using the following option in `/boot/config.txt`:
25 |
26 | ```
27 | dtparam=i2c_arm=on,i2c_baudrate=400000
28 | ```
29 |
30 | A reboot is required to apply the change.
31 |
32 |
33 | ## Verify
34 |
35 | To verify your setup use the `i2cdetect` command. The APDS-9960 chip is hard coded at the address 0x39:
36 |
37 | ```shell
38 | # i2cdetect -y 1
39 | 0 1 2 3 4 5 6 7 8 9 a b c d e f
40 | 00: -- -- -- -- -- -- -- -- -- -- -- -- --
41 | 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
42 | 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
43 | 30: -- -- -- -- -- -- -- -- -- 39 -- -- -- -- -- --
44 | 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
45 | 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
46 | 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
47 | 70: -- -- -- -- -- -- -- --
48 | ```
49 |
--------------------------------------------------------------------------------
/apds9960/const.py:
--------------------------------------------------------------------------------
1 | # APDS9960 i2c address
2 | APDS9960_I2C_ADDR = 0x39
3 |
4 | # APDS9960 gesture parameters
5 | APDS9960_GESTURE_THRESHOLD_OUT = 10
6 | APDS9960_GESTURE_SENSITIVITY_1 = 50
7 | APDS9960_GESTURE_SENSITIVITY_2 = 20
8 |
9 | # APDS9960 device IDs
10 | APDS9960_DEV_ID = [0xab, 0x9c, 0xa8]
11 |
12 | # APDS9960 times
13 | APDS9960_TIME_FIFO_PAUSE = 0.03
14 |
15 | # APDS9960 register addresses
16 | APDS9960_REG_ENABLE = 0x80
17 | APDS9960_REG_ATIME = 0x81
18 | APDS9960_REG_WTIME = 0x83
19 | APDS9960_REG_AILTL = 0x84
20 | APDS9960_REG_AILTH = 0x85
21 | APDS9960_REG_AIHTL = 0x86
22 | APDS9960_REG_AIHTH = 0x87
23 | APDS9960_REG_PILT = 0x89
24 | APDS9960_REG_PIHT = 0x8b
25 | APDS9960_REG_PERS = 0x8c
26 | APDS9960_REG_CONFIG1 = 0x8d
27 | APDS9960_REG_PPULSE = 0x8e
28 | APDS9960_REG_CONTROL = 0x8f
29 | APDS9960_REG_CONFIG2 = 0x90
30 | APDS9960_REG_ID = 0x92
31 | APDS9960_REG_STATUS = 0x93
32 | APDS9960_REG_CDATAL = 0x94
33 | APDS9960_REG_CDATAH = 0x95
34 | APDS9960_REG_RDATAL = 0x96
35 | APDS9960_REG_RDATAH = 0x97
36 | APDS9960_REG_GDATAL = 0x98
37 | APDS9960_REG_GDATAH = 0x99
38 | APDS9960_REG_BDATAL = 0x9a
39 | APDS9960_REG_BDATAH = 0x9b
40 | APDS9960_REG_PDATA = 0x9c
41 | APDS9960_REG_POFFSET_UR = 0x9d
42 | APDS9960_REG_POFFSET_DL = 0x9e
43 | APDS9960_REG_CONFIG3 = 0x9f
44 | APDS9960_REG_GPENTH = 0xa0
45 | APDS9960_REG_GEXTH = 0xa1
46 | APDS9960_REG_GCONF1 = 0xa2
47 | APDS9960_REG_GCONF2 = 0xa3
48 | APDS9960_REG_GOFFSET_U = 0xa4
49 | APDS9960_REG_GOFFSET_D = 0xa5
50 | APDS9960_REG_GOFFSET_L = 0xa7
51 | APDS9960_REG_GOFFSET_R = 0xa9
52 | APDS9960_REG_GPULSE = 0xa6
53 | APDS9960_REG_GCONF3 = 0xaA
54 | APDS9960_REG_GCONF4 = 0xaB
55 | APDS9960_REG_GFLVL = 0xae
56 | APDS9960_REG_GSTATUS = 0xaf
57 | APDS9960_REG_IFORCE = 0xe4
58 | APDS9960_REG_PICLEAR = 0xe5
59 | APDS9960_REG_CICLEAR = 0xe6
60 | APDS9960_REG_AICLEAR = 0xe7
61 | APDS9960_REG_GFIFO_U = 0xfc
62 | APDS9960_REG_GFIFO_D = 0xfd
63 | APDS9960_REG_GFIFO_L = 0xfe
64 | APDS9960_REG_GFIFO_R = 0xff
65 |
66 | # APDS9960 bit fields
67 | APDS9960_BIT_PON = 0b00000001
68 | APDS9960_BIT_AEN = 0b00000010
69 | APDS9960_BIT_PEN = 0b00000100
70 | APDS9960_BIT_WEN = 0b00001000
71 | APSD9960_BIT_AIEN =0b00010000
72 | APDS9960_BIT_PIEN = 0b00100000
73 | APDS9960_BIT_GEN = 0b01000000
74 | APDS9960_BIT_GVALID = 0b00000001
75 |
76 | # APDS9960 modes
77 | APDS9960_MODE_POWER = 0
78 | APDS9960_MODE_AMBIENT_LIGHT = 1
79 | APDS9960_MODE_PROXIMITY = 2
80 | APDS9960_MODE_WAIT = 3
81 | APDS9960_MODE_AMBIENT_LIGHT_INT = 4
82 | APDS9960_MODE_PROXIMITY_INT = 5
83 | APDS9960_MODE_GESTURE = 6
84 | APDS9960_MODE_ALL = 7
85 |
86 | # LED Drive values
87 | APDS9960_LED_DRIVE_100MA = 0
88 | APDS9960_LED_DRIVE_50MA = 1
89 | APDS9960_LED_DRIVE_25MA = 2
90 | APDS9960_LED_DRIVE_12_5MA = 3
91 |
92 | # Proximity Gain (PGAIN) values
93 | APDS9960_PGAIN_1X = 0
94 | APDS9960_PGAIN_2X = 1
95 | APDS9960_PGAIN_4X = 2
96 | APDS9960_PGAIN_8X = 3
97 |
98 | # ALS Gain (AGAIN) values
99 | APDS9960_AGAIN_1X = 0
100 | APDS9960_AGAIN_4X = 1
101 | APDS9960_AGAIN_16X = 2
102 | APDS9960_AGAIN_64X = 3
103 |
104 | # Gesture Gain (GGAIN) values
105 | APDS9960_GGAIN_1X = 0
106 | APDS9960_GGAIN_2X = 1
107 | APDS9960_GGAIN_4X = 2
108 | APDS9960_GGAIN_8X = 3
109 |
110 | # LED Boost values
111 | APDS9960_LED_BOOST_100 = 0
112 | APDS9960_LED_BOOST_150 = 1
113 | APDS9960_LED_BOOST_200 = 2
114 | APDS9960_LED_BOOST_300 = 3
115 |
116 | # Gesture wait time values
117 | APDS9960_GWTIME_0MS = 0
118 | APDS9960_GWTIME_2_8MS = 1
119 | APDS9960_GWTIME_5_6MS = 2
120 | APDS9960_GWTIME_8_4MS = 3
121 | APDS9960_GWTIME_14_0MS = 4
122 | APDS9960_GWTIME_22_4MS = 5
123 | APDS9960_GWTIME_30_8MS = 6
124 | APDS9960_GWTIME_39_2MS = 7
125 |
126 | # Default values
127 | APDS9960_DEFAULT_ATIME = 219 # 103ms
128 | APDS9960_DEFAULT_WTIME = 246 # 27ms
129 | APDS9960_DEFAULT_PROX_PPULSE = 0x87 # 16us, 8 pulses
130 | APDS9960_DEFAULT_GESTURE_PPULSE = 0x89 # 16us, 10 pulses
131 | APDS9960_DEFAULT_POFFSET_UR = 0 # 0 offset
132 | APDS9960_DEFAULT_POFFSET_DL = 0 # 0 offset
133 | APDS9960_DEFAULT_CONFIG1 = 0x60 # No 12x wait (WTIME) factor
134 | APDS9960_DEFAULT_LDRIVE = APDS9960_LED_DRIVE_100MA
135 | APDS9960_DEFAULT_PGAIN = APDS9960_PGAIN_4X
136 | APDS9960_DEFAULT_AGAIN = APDS9960_AGAIN_4X
137 | APDS9960_DEFAULT_PILT = 0 # Low proximity threshold
138 | APDS9960_DEFAULT_PIHT = 50 # High proximity threshold
139 | APDS9960_DEFAULT_AILT = 0xffff # Force interrupt for calibration
140 | APDS9960_DEFAULT_AIHT = 0
141 | APDS9960_DEFAULT_PERS = 0x11 # 2 consecutive prox or ALS for int.
142 | APDS9960_DEFAULT_CONFIG2 = 0x01 # No saturation interrupts or LED boost
143 | APDS9960_DEFAULT_CONFIG3 = 0 # Enable all photodiodes, no SAI
144 | APDS9960_DEFAULT_GPENTH = 40 # Threshold for entering gesture mode
145 | APDS9960_DEFAULT_GEXTH = 30 # Threshold for exiting gesture mode
146 | APDS9960_DEFAULT_GCONF1 = 0x40 # 4 gesture events for int., 1 for exit
147 | APDS9960_DEFAULT_GGAIN = APDS9960_GGAIN_4X
148 | APDS9960_DEFAULT_GLDRIVE = APDS9960_LED_DRIVE_100MA
149 | APDS9960_DEFAULT_GWTIME = APDS9960_GWTIME_2_8MS
150 | APDS9960_DEFAULT_GOFFSET = 0 # No offset scaling for gesture mode
151 | APDS9960_DEFAULT_GPULSE = 0xc9 # 32us, 10 pulses
152 | APDS9960_DEFAULT_GCONF3 = 0 # All photodiodes active during gesture
153 | APDS9960_DEFAULT_GIEN = 0 # Disable gesture interrupts
154 |
155 | # gesture directions
156 | APDS9960_DIR_NONE = 0
157 | APDS9960_DIR_LEFT = 1
158 | APDS9960_DIR_RIGHT = 2
159 | APDS9960_DIR_UP = 3
160 | APDS9960_DIR_DOWN = 4
161 | APDS9960_DIR_NEAR = 5
162 | APDS9960_DIR_FAR = 6
163 | APDS9960_DIR_ALL = 7
164 |
165 | # state definitions
166 | APDS9960_STATE_NA = 0
167 | APDS9960_STATE_NEAR = 1
168 | APDS9960_STATE_FAR = 2
169 | APDS9960_STATE_ALL = 3
170 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 | {one line to give the program's name and a brief idea of what it does.}
635 | Copyright (C) {year} {name of author}
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | {project} Copyright (C) {year} {fullname}
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/apds9960/device.py:
--------------------------------------------------------------------------------
1 | from apds9960.const import *
2 | from apds9960.exceptions import *
3 |
4 | from time import sleep
5 |
6 | class APDS9960:
7 | class GestureData:
8 | def __init__(self):
9 | self.u_data = [0] * 32
10 | self.d_data = [0] * 32
11 | self.l_data = [0] * 32
12 | self.r_data = [0] * 32
13 | self.index = 0
14 | self.total_gestures = 0
15 | self.in_threshold = 0
16 | self.out_threshold = 0
17 |
18 | def __init__(self, bus, address=APDS9960_I2C_ADDR, valid_id=APDS9960_DEV_ID):
19 | # I2C stuff
20 | self.address = address
21 | self.bus = bus
22 |
23 | # instance variables for gesture detection
24 | self.gesture_ud_delta_ = 0
25 | self.gesture_lr_delta_ = 0
26 |
27 | self.gesture_ud_count_ = 0
28 | self.gesture_lr_count_ = 0
29 |
30 | self.gesture_near_count_ = 0
31 | self.gesture_far_count_ = 0
32 |
33 | self.gesture_state_ = 0
34 | self.gesture_motion_ = APDS9960_DIR_NONE
35 |
36 | self.gesture_data_ = APDS9960.GestureData()
37 |
38 | # check device id
39 | self.dev_id = self._read_byte_data(APDS9960_REG_ID)
40 | if not self.dev_id in valid_id:
41 | raise ADPS9960InvalidDevId(self.dev_id, valid_id)
42 |
43 | # disable all features
44 | self.setMode(APDS9960_MODE_ALL, False)
45 |
46 | # set default values for ambient light and proximity registers
47 | self._write_byte_data(APDS9960_REG_ATIME, APDS9960_DEFAULT_ATIME)
48 | self._write_byte_data(APDS9960_REG_WTIME, APDS9960_DEFAULT_WTIME)
49 | self._write_byte_data(APDS9960_REG_PPULSE, APDS9960_DEFAULT_PROX_PPULSE)
50 | self._write_byte_data(APDS9960_REG_POFFSET_UR, APDS9960_DEFAULT_POFFSET_UR)
51 | self._write_byte_data(APDS9960_REG_POFFSET_DL, APDS9960_DEFAULT_POFFSET_DL)
52 | self._write_byte_data(APDS9960_REG_CONFIG1, APDS9960_DEFAULT_CONFIG1)
53 | self.setLEDDrive(APDS9960_DEFAULT_LDRIVE)
54 | self.setProximityGain(APDS9960_DEFAULT_PGAIN)
55 | self.setAmbientLightGain(APDS9960_DEFAULT_AGAIN)
56 | self.setProxIntLowThresh(APDS9960_DEFAULT_PILT)
57 | self.setProxIntHighThresh(APDS9960_DEFAULT_PIHT)
58 | self.setLightIntLowThreshold(APDS9960_DEFAULT_AILT)
59 | self.setLightIntHighThreshold(APDS9960_DEFAULT_AIHT)
60 |
61 | self._write_byte_data(APDS9960_REG_PERS, APDS9960_DEFAULT_PERS)
62 | self._write_byte_data(APDS9960_REG_CONFIG2, APDS9960_DEFAULT_CONFIG2)
63 | self._write_byte_data(APDS9960_REG_CONFIG3, APDS9960_DEFAULT_CONFIG3)
64 |
65 | # set default values for gesture sense registers
66 | self.setGestureEnterThresh(APDS9960_DEFAULT_GPENTH)
67 | self.setGestureExitThresh(APDS9960_DEFAULT_GEXTH)
68 | self._write_byte_data(APDS9960_REG_GCONF1, APDS9960_DEFAULT_GCONF1)
69 |
70 | self.setGestureGain(APDS9960_DEFAULT_GGAIN)
71 | self.setGestureLEDDrive(APDS9960_DEFAULT_GLDRIVE)
72 | self.setGestureWaitTime(APDS9960_DEFAULT_GWTIME)
73 | self._write_byte_data(APDS9960_REG_GOFFSET_U, APDS9960_DEFAULT_GOFFSET)
74 | self._write_byte_data(APDS9960_REG_GOFFSET_D, APDS9960_DEFAULT_GOFFSET)
75 | self._write_byte_data(APDS9960_REG_GOFFSET_L, APDS9960_DEFAULT_GOFFSET)
76 | self._write_byte_data(APDS9960_REG_GOFFSET_R, APDS9960_DEFAULT_GOFFSET)
77 | self._write_byte_data(APDS9960_REG_GPULSE, APDS9960_DEFAULT_GPULSE)
78 | self._write_byte_data(APDS9960_REG_GCONF3, APDS9960_DEFAULT_GCONF3)
79 | self.setGestureIntEnable(APDS9960_DEFAULT_GIEN)
80 |
81 |
82 | def getMode(self):
83 | return self._read_byte_data(APDS9960_REG_ENABLE)
84 |
85 | def setMode(self, mode, enable=True):
86 | # read ENABLE register
87 | reg_val = self.getMode()
88 |
89 | if mode < 0 or mode > APDS9960_MODE_ALL:
90 | raise ADPS9960InvalidMode(mode)
91 |
92 | # change bit(s) in ENABLE register */
93 | if mode == APDS9960_MODE_ALL:
94 | if enable:
95 | reg_val = 0x7f
96 | else:
97 | reg_val = 0x00
98 | else:
99 | if enable:
100 | reg_val |= (1 << mode);
101 | else:
102 | reg_val &= ~(1 << mode);
103 |
104 | # write value to ENABLE register
105 | self._write_byte_data(APDS9960_REG_ENABLE, reg_val)
106 |
107 |
108 | # start the light (R/G/B/Ambient) sensor
109 | def enableLightSensor(self, interrupts=True):
110 | self.setAmbientLightGain(APDS9960_DEFAULT_AGAIN)
111 | self.setAmbientLightIntEnable(interrupts)
112 | self.enablePower()
113 | self.setMode(APDS9960_MODE_AMBIENT_LIGHT, True)
114 |
115 | # stop the light sensor
116 | def disableLightSensor(self):
117 | self.setAmbientLightIntEnable(False)
118 | self.setMode(APDS9960_MODE_AMBIENT_LIGHT, False)
119 |
120 |
121 | # start the proximity sensor
122 | def enableProximitySensor(self, interrupts=True):
123 | self.setProximityGain(APDS9960_DEFAULT_PGAIN)
124 | self.setLEDDrive(APDS9960_DEFAULT_LDRIVE)
125 | self.setProximityIntEnable(interrupts)
126 | self.enablePower()
127 | self.setMode(APDS9960_MODE_PROXIMITY, True)
128 |
129 | # stop the proximity sensor
130 | def disableProximitySensor(self):
131 | self.setProximityIntEnable(False)
132 | self.setMode(APDS9960_MODE_PROXIMITY, False)
133 |
134 |
135 | # start the gesture recognition engine
136 | def enableGestureSensor(self, interrupts=True):
137 | self.resetGestureParameters()
138 | self._write_byte_data(APDS9960_REG_WTIME, 0xff)
139 | self._write_byte_data(APDS9960_REG_PPULSE, APDS9960_DEFAULT_GESTURE_PPULSE)
140 | self.setLEDBoost(APDS9960_LED_BOOST_300)
141 | self.setGestureIntEnable(interrupts)
142 | self.setGestureMode(True)
143 | self.enablePower()
144 | self.setMode(APDS9960_MODE_WAIT, True)
145 | self.setMode(APDS9960_MODE_PROXIMITY, True)
146 | self.setMode(APDS9960_MODE_GESTURE, True)
147 |
148 | # stop the gesture recognition engine
149 | def disableGestureSensor(self):
150 | self.resetGestureParameters()
151 | self.setGestureIntEnable(False)
152 | self.setGestureMode(False)
153 | self.setMode(APDS9960_MODE_GESTURE, False)
154 |
155 |
156 | # check if there is a gesture available
157 | def isGestureAvailable(self):
158 | val = self._read_byte_data(APDS9960_REG_GSTATUS)
159 |
160 | # shift and mask out GVALID bit
161 | val &= APDS9960_BIT_GVALID;
162 |
163 | return (val == APDS9960_BIT_GVALID)
164 |
165 |
166 | # processes a gesture event and returns best guessed gesture
167 | def readGesture(self):
168 | fifo_level = 0
169 | bytes_read = 0
170 | fifo_data = []
171 |
172 | # make sure that power and gesture is on and data is valid
173 | if not (self.getMode() & 0b01000001) or not self.isGestureAvailable():
174 | return APDS9960_DIR_NONE
175 |
176 | # keep looping as long as gesture data is valid
177 | while(self.isGestureAvailable()):
178 | # read the current FIFO level
179 | fifo_level = self._read_byte_data(APDS9960_REG_GFLVL)
180 |
181 | # if there's stuff in the FIFO, read it into our data block
182 | if fifo_level > 0:
183 | fifo_data = []
184 | for i in range(0, fifo_level):
185 | fifo_data += self._read_i2c_block_data(APDS9960_REG_GFIFO_U, 4)
186 |
187 | # if at least 1 set of data, sort the data into U/D/L/R
188 | if len(fifo_data) >= 4:
189 | for i in range(0, len(fifo_data), 4):
190 | self.gesture_data_.u_data[self.gesture_data_.index] = fifo_data[i + 0]
191 | self.gesture_data_.d_data[self.gesture_data_.index] = fifo_data[i + 1]
192 | self.gesture_data_.l_data[self.gesture_data_.index] = fifo_data[i + 2]
193 | self.gesture_data_.r_data[self.gesture_data_.index] = fifo_data[i + 3]
194 | self.gesture_data_.index += 1
195 | self.gesture_data_.total_gestures += 1
196 |
197 | # filter and process gesture data, decode near/far state
198 | if self.processGestureData():
199 | if self.decodeGesture():
200 | #***TODO: U-Turn Gestures
201 | pass
202 |
203 | # reset data
204 | self.gesture_data_.index = 0
205 | self.gesture_data_.total_gestures = 0
206 |
207 | # wait some time to collect next batch of FIFO data
208 | sleep(APDS9960_TIME_FIFO_PAUSE)
209 |
210 | # determine best guessed gesture and clean up
211 | sleep(APDS9960_TIME_FIFO_PAUSE)
212 | self.decodeGesture()
213 | motion = self.gesture_motion_
214 |
215 | self.resetGestureParameters()
216 | return motion
217 |
218 |
219 | # turn the APDS-9960 on
220 | def enablePower(self):
221 | self.setMode(APDS9960_MODE_POWER, True)
222 |
223 |
224 | def disablePower(self):
225 | # turn the APDS-9960 off
226 | self.setMode(APDS9960_MODE_POWER, False)
227 |
228 |
229 |
230 | # *******************************************************************************
231 | # ambient light and color sensor controls
232 | # *******************************************************************************
233 |
234 | # reads the ambient (clear) light level as a 16-bit value
235 | def readAmbientLight(self):
236 | # read value from clear channel, low byte register
237 | l = self._read_byte_data(APDS9960_REG_CDATAL)
238 |
239 | # read value from clear channel, high byte register
240 | h = self._read_byte_data(APDS9960_REG_CDATAH)
241 |
242 | return l + (h << 8)
243 |
244 | # reads the red light level as a 16-bit value
245 | def readRedLight(self):
246 | # read value from red channel, low byte register
247 | l = self._read_byte_data(APDS9960_REG_RDATAL)
248 |
249 | # read value from red channel, high byte register
250 | h = self._read_byte_data(APDS9960_REG_RDATAH)
251 |
252 | return l + (h << 8)
253 |
254 | # reads the green light level as a 16-bit value
255 | def readGreenLight(self):
256 | # read value from green channel, low byte register
257 | l = self._read_byte_data(APDS9960_REG_GDATAL)
258 |
259 | # read value from green channel, high byte register
260 | h = self._read_byte_data(APDS9960_REG_GDATAH)
261 |
262 | return l + (h << 8)
263 |
264 | # reads the blue light level as a 16-bit value
265 | def readBlueLight(self):
266 | # read value from blue channel, low byte register
267 | l = self._read_byte_data(APDS9960_REG_BDATAL)
268 |
269 | # read value from blue channel, high byte register
270 | h = self._read_byte_data(APDS9960_REG_BDATAH)
271 |
272 | return l + (h << 8)
273 |
274 |
275 | # *******************************************************************************
276 | # Proximity sensor controls
277 | # *******************************************************************************
278 |
279 | # reads the proximity level as an 8-bit value
280 | def readProximity(self):
281 | return self._read_byte_data(APDS9960_REG_PDATA)
282 |
283 |
284 | # *******************************************************************************
285 | # High-level gesture controls
286 | # *******************************************************************************
287 |
288 | def resetGestureParameters(self):
289 | self.gesture_data_.index = 0
290 | self.gesture_data_.total_gestures = 0
291 |
292 | self.gesture_ud_delta_ = 0
293 | self.gesture_lr_delta_ = 0
294 |
295 | self.gesture_ud_count_ = 0
296 | self.gesture_lr_count_ = 0
297 |
298 | self.gesture_near_count_ = 0
299 | self.gesture_far_count_ = 0
300 |
301 | self.gesture_state_ = 0
302 | self.gesture_motion_ = APDS9960_DIR_NONE
303 |
304 |
305 | def processGestureData(self):
306 | """Processes the raw gesture data to determine swipe direction
307 |
308 | Returns:
309 | bool: True if near or far state seen, False otherwise.
310 | """
311 | u_first = 0
312 | d_first = 0
313 | l_first = 0
314 | r_first = 0
315 | u_last = 0
316 | d_last = 0
317 | l_last = 0
318 | r_last = 0
319 |
320 | # if we have less than 4 total gestures, that's not enough
321 | if self.gesture_data_.total_gestures <= 4:
322 | return False
323 |
324 | # check to make sure our data isn't out of bounds
325 | if self.gesture_data_.total_gestures <= 32 and self.gesture_data_.total_gestures > 0:
326 | # find the first value in U/D/L/R above the threshold
327 | for i in range(0, self.gesture_data_.total_gestures):
328 | if self.gesture_data_.u_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
329 | self.gesture_data_.d_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
330 | self.gesture_data_.l_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
331 | self.gesture_data_.r_data[i] > APDS9960_GESTURE_THRESHOLD_OUT:
332 |
333 | u_first = self.gesture_data_.u_data[i]
334 | d_first = self.gesture_data_.d_data[i]
335 | l_first = self.gesture_data_.l_data[i]
336 | r_first = self.gesture_data_.r_data[i]
337 | break
338 |
339 | # if one of the _first values is 0, then there is no good data
340 | if u_first == 0 or d_first == 0 or l_first == 0 or r_first == 0:
341 | return False
342 |
343 | # find the last value in U/D/L/R above the threshold
344 | for i in reversed(range(0, self.gesture_data_.total_gestures)):
345 | if self.gesture_data_.u_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
346 | self.gesture_data_.d_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
347 | self.gesture_data_.l_data[i] > APDS9960_GESTURE_THRESHOLD_OUT and \
348 | self.gesture_data_.r_data[i] > APDS9960_GESTURE_THRESHOLD_OUT:
349 |
350 | u_last = self.gesture_data_.u_data[i]
351 | d_last = self.gesture_data_.d_data[i]
352 | l_last = self.gesture_data_.l_data[i]
353 | r_last = self.gesture_data_.r_data[i]
354 | break
355 |
356 | # calculate the first vs. last ratio of up/down and left/right
357 | ud_ratio_first = ((u_first - d_first) * 100) / (u_first + d_first)
358 | lr_ratio_first = ((l_first - r_first) * 100) / (l_first + r_first)
359 | ud_ratio_last = ((u_last - d_last) * 100) / (u_last + d_last)
360 | lr_ratio_last = ((l_last - r_last) * 100) / (l_last + r_last)
361 |
362 | # determine the difference between the first and last ratios
363 | ud_delta = ud_ratio_last - ud_ratio_first
364 | lr_delta = lr_ratio_last - lr_ratio_first
365 |
366 | # accumulate the UD and LR delta values
367 | self.gesture_ud_delta_ += ud_delta
368 | self.gesture_lr_delta_ += lr_delta
369 |
370 | # determine U/D gesture
371 | if self.gesture_ud_delta_ >= APDS9960_GESTURE_SENSITIVITY_1:
372 | self.gesture_ud_count_ = 1
373 | elif self.gesture_ud_delta_ <= -APDS9960_GESTURE_SENSITIVITY_1:
374 | self.gesture_ud_count_ = -1
375 | else:
376 | self.gesture_ud_count_ = 0
377 |
378 | # determine L/R gesture
379 | if self.gesture_lr_delta_ >= APDS9960_GESTURE_SENSITIVITY_1:
380 | self.gesture_lr_count_ = 1
381 | elif self.gesture_lr_delta_ <= -APDS9960_GESTURE_SENSITIVITY_1:
382 | self.gesture_lr_count_ = -1
383 | else:
384 | self.gesture_lr_count_ = 0
385 |
386 | # determine Near/Far gesture
387 | if self.gesture_ud_count_ == 0 and self.gesture_lr_count_ == 0:
388 | if abs(ud_delta) < APDS9960_GESTURE_SENSITIVITY_2 and \
389 | abs(lr_delta) < APDS9960_GESTURE_SENSITIVITY_2:
390 |
391 | if ud_delta == 0 and lr_delta == 0:
392 | self.gesture_near_count_ += 1
393 | elif ud_delta != 0 or lr_delta != 0:
394 | self.gesture_far_count_ += 1
395 |
396 | if self.gesture_near_count_ >= 10 and self.gesture_far_count_ >= 2:
397 | if ud_delta == 0 and lr_delta == 0:
398 | self.gesture_state_ = APDS9960_STATE_NEAR
399 | elif ud_delta != 0 and lr_delta != 0:
400 | self.gesture_state_ = APDS9960_STATE_FAR
401 | return True
402 | else:
403 | if abs(ud_delta) < APDS9960_GESTURE_SENSITIVITY_2 and \
404 | abs(lr_delta) < APDS9960_GESTURE_SENSITIVITY_2:
405 |
406 | if ud_delta == 0 and lr_delta == 0:
407 | self.gesture_near_count_ += 1
408 |
409 | if self.gesture_near_count_ >= 10:
410 | self.gesture_ud_count_ = 0
411 | self.gesture_lr_count_ = 0
412 | self.gesture_ud_delta_ = 0
413 | self.gesture_lr_delta_ = 0
414 |
415 | return False
416 |
417 | def decodeGesture(self):
418 | """Determines swipe direction or near/far state.
419 | """
420 |
421 | # return if near or far event is detected
422 | if self.gesture_state_ == APDS9960_STATE_NEAR:
423 | self.gesture_motion_ = APDS9960_DIR_NEAR
424 | return True
425 |
426 | if self.gesture_state_ == APDS9960_STATE_FAR:
427 | self.gesture_motion_ = APDS9960_DIR_FAR
428 | return True
429 |
430 | # determine swipe direction
431 | if self.gesture_ud_count_ == -1 and self.gesture_lr_count_ == 0:
432 | self.gesture_motion_ = APDS9960_DIR_UP
433 | elif self.gesture_ud_count_ == 1 and self.gesture_lr_count_ == 0:
434 | self.gesture_motion_ = APDS9960_DIR_DOWN
435 | elif self.gesture_ud_count_ == 0 and self.gesture_lr_count_ == 1:
436 | self.gesture_motion_ = APDS9960_DIR_RIGHT
437 | elif self.gesture_ud_count_ == 0 and self.gesture_lr_count_ == -1:
438 | self.gesture_motion_ = APDS9960_DIR_LEFT
439 | elif self.gesture_ud_count_ == -1 and self.gesture_lr_count_ == 1:
440 | if abs(self.gesture_ud_delta_) > abs(self.gesture_lr_delta_):
441 | self.gesture_motion_ = APDS9960_DIR_UP
442 | else:
443 | self.gesture_motion_ = APDS9960_DIR_DOWN
444 | elif self.gesture_ud_count_ == 1 and self.gesture_lr_count_ == -1:
445 | if abs(self.gesture_ud_delta_) > abs(self.gesture_lr_delta_):
446 | self.gesture_motion_ = APDS9960_DIR_DOWN
447 | else:
448 | self.gesture_motion_ = APDS9960_DIR_LEFT
449 | elif self.gesture_ud_count_ == -1 and self.gesture_lr_count_ == -1:
450 | if abs(self.gesture_ud_delta_) > abs(self.gesture_lr_delta_):
451 | self.gesture_motion_ = APDS9960_DIR_UP
452 | else:
453 | self.gesture_motion_ = APDS9960_DIR_LEFT
454 | elif self.gesture_ud_count_ == 1 and self.gesture_lr_count_ == 1:
455 | if abs(self.gesture_ud_delta_) > abs(self.gesture_lr_delta_):
456 | self.gesture_motion_ = APDS9960_DIR_DOWN
457 | else:
458 | self.gesture_motion_ = APDS9960_DIR_RIGHT
459 | else:
460 | return False
461 |
462 | return True
463 |
464 |
465 | # *******************************************************************************
466 | # Getters and setters for register values
467 | # *******************************************************************************
468 |
469 | def getProxIntLowThresh(self):
470 | """Returns the lower threshold for proximity detection
471 | """
472 | return self._read_byte_data(APDS9960_REG_PILT)
473 |
474 | def setProxIntLowThresh(self, threshold):
475 | """Sets the lower threshold for proximity detection.
476 | """
477 | self._write_byte_data(APDS9960_REG_PILT, threshold)
478 |
479 |
480 | def getProxIntHighThresh(self):
481 | """Returns the high threshold for proximity detection.
482 | """
483 | return self._read_byte_data(APDS9960_REG_PIHT)
484 |
485 | def setProxIntHighThresh(self, threshold):
486 | """Sets the high threshold for proximity detection.
487 | """
488 | self._write_byte_data(APDS9960_REG_PIHT, threshold)
489 |
490 |
491 | def getLEDDrive(self):
492 | """Returns LED drive strength for proximity and ALS.
493 |
494 | Value LED Current
495 | 0 100 mA
496 | 1 50 mA
497 | 2 25 mA
498 | 3 12.5 mA
499 |
500 | Returns:
501 | int: the value of the LED drive strength
502 | """
503 | val = self._read_byte_data(APDS9960_REG_CONTROL)
504 |
505 | # shift and mask out LED drive bits
506 | return (val >> 6) & 0b00000011
507 |
508 | def setLEDDrive(self, drive):
509 | """Sets LED drive strength for proximity and ALS.
510 |
511 | Value LED Current
512 | 0 100 mA
513 | 1 50 mA
514 | 2 25 mA
515 | 3 12.5 mA
516 |
517 | Args:
518 | drive (int): value for the LED drive strength
519 | """
520 | val = self._read_byte_data(APDS9960_REG_CONTROL)
521 |
522 | # set bits in register to given value
523 | drive &= 0b00000011
524 | drive = drive << 6
525 | val &= 0b00111111
526 | val |= drive
527 |
528 | self._write_byte_data(APDS9960_REG_CONTROL, val)
529 |
530 |
531 | def getProximityGain(self):
532 | """Returns receiver gain for proximity detection.
533 |
534 | Value Gain
535 | 0 1x
536 | 1 2x
537 | 2 4x
538 | 3 8x
539 |
540 | Returns:
541 | int: the value of the proximity gain
542 | """
543 | val = self._read_byte_data(APDS9960_REG_CONTROL)
544 |
545 | # shift and mask out PDRIVE bits
546 | return (val >> 2) & 0b00000011
547 |
548 | def setProximityGain(self, drive):
549 | """Returns receiver gain for proximity detection.
550 |
551 | Value Gain
552 | 0 1x
553 | 1 2x
554 | 2 4x
555 | 3 8x
556 |
557 | Args:
558 | drive (int): value for the proximity gain
559 | """
560 | val = self._read_byte_data(APDS9960_REG_CONTROL)
561 |
562 | # set bits in register to given value
563 | drive &= 0b00000011
564 | drive = drive << 2
565 | val &= 0b11110011
566 | val |= drive
567 |
568 | self._write_byte_data(APDS9960_REG_CONTROL, val)
569 |
570 |
571 | def getAmbientLightGain(self):
572 | """Returns receiver gain for the ambient light sensor (ALS).
573 |
574 | Value Gain
575 | 0 1x
576 | 1 4x
577 | 2 16x
578 | 3 64x
579 |
580 | Returns:
581 | int: the value of the ALS gain
582 | """
583 | val = self._read_byte_data(APDS9960_REG_CONTROL)
584 |
585 | # shift and mask out ADRIVE bits
586 | return (val & 0b00000011)
587 |
588 | def setAmbientLightGain(self, drive):
589 | """Sets the receiver gain for the ambient light sensor (ALS).
590 |
591 | Value Gain
592 | 0 1x
593 | 1 4x
594 | 2 16x
595 | 3 64x
596 |
597 | Args:
598 | drive (int): value for the ALS gain
599 | """
600 | val = self._read_byte_data(APDS9960_REG_CONTROL)
601 |
602 | # set bits in register to given value
603 | drive &= 0b00000011
604 | val &= 0b11111100
605 | val |= drive
606 |
607 | self._write_byte_data(APDS9960_REG_CONTROL, val)
608 |
609 |
610 | def getLEDBoost(self):
611 | """Get the current LED boost value.
612 |
613 | Value Gain
614 | 0 100%
615 | 1 150%
616 | 2 200%
617 | 3 300%
618 |
619 | Returns:
620 | int: the LED boost value
621 | """
622 | val = self._read_byte_data(APDS9960_REG_CONFIG2)
623 |
624 | # shift and mask out LED_BOOST bits
625 | return (val >> 4) & 0b00000011
626 |
627 | def setLEDBoost(self, boost):
628 | """Sets the LED current boost value.
629 |
630 | Value Gain
631 | 0 100%
632 | 1 150%
633 | 2 200%
634 | 3 300%
635 |
636 | Args:
637 | boost (int): value for the LED boost
638 | """
639 | val = self._read_byte_data(APDS9960_REG_CONFIG2)
640 |
641 | # set bits in register to given value
642 | boost &= 0b00000011
643 | boost = boost << 4
644 | val &= 0b11001111
645 | val |= boost
646 |
647 | self._write_byte_data(APDS9960_REG_CONFIG2, val)
648 |
649 |
650 | def getProxGainCompEnable(self):
651 | """Gets proximity gain compensation enable.
652 |
653 | Returns:
654 | bool: True if compensation is enabled, False if not
655 | """
656 | val = self._read_byte_data(APDS9960_REG_CONFIG3)
657 |
658 | # Shift and mask out PCMP bits
659 | val = (val >> 5) & 0b00000001
660 | return val == 1
661 |
662 | def setProxGainCompEnable(self, enable):
663 | """Sets the proximity gain compensation enable.
664 |
665 | Args:
666 | enable (bool): True to enable compensation, False to disable
667 | """
668 | val = self._read_byte_data(APDS9960_REG_CONFIG3)
669 |
670 | # set bits in register to given value
671 | val &= 0b11011111
672 | if enable:
673 | val |= 0b00100000
674 |
675 | self._write_byte_data(APDS9960_REG_CONFIG3, val)
676 |
677 |
678 | def getProxPhotoMask(self):
679 | """Gets the current mask for enabled/disabled proximity photodiodes.
680 |
681 | Bit Photodiode
682 | 3 UP
683 | 2 DOWN
684 | 1 LEFT
685 | 0 RIGHT
686 |
687 | 1 = disabled, 0 = enabled
688 |
689 | Returns:
690 | int: Current proximity mask for photodiodes.
691 | """
692 | val = self._read_byte_data(APDS9960_REG_CONFIG3)
693 |
694 | # mask out photodiode enable mask bits
695 | return val & 0b00001111
696 |
697 | def setProxPhotoMask(self, mask):
698 | """Sets the mask for enabling/disabling proximity photodiodes.
699 |
700 | Bit Photodiode
701 | 3 UP
702 | 2 DOWN
703 | 1 LEFT
704 | 0 RIGHT
705 |
706 | 1 = disabled, 0 = enabled
707 |
708 | Args:
709 | mask (int): 4-bit mask value
710 | """
711 | val = self._read_byte_data(APDS9960_REG_CONFIG3)
712 |
713 | # set bits in register to given value
714 | mask &= 0b00001111
715 | val &= 0b11110000
716 | val |= mask
717 |
718 | self._write_byte_data(APDS9960_REG_CONFIG3, val)
719 |
720 |
721 | def getGestureEnterThresh(self):
722 | """Gets the entry proximity threshold for gesture sensing.
723 |
724 | Returns:
725 | int: current entry proximity threshold
726 | """
727 | return self._read_byte_data(APDS9960_REG_GPENTH)
728 |
729 | def setGestureEnterThresh(self, threshold):
730 | """Sets the entry proximity threshold for gesture sensing.
731 |
732 | Args:
733 | threshold (int): threshold proximity value needed to start gesture mode
734 | """
735 | self._write_byte_data(APDS9960_REG_GPENTH, threshold)
736 |
737 |
738 | def getGestureExitThresh(self):
739 | """Gets the exit proximity threshold for gesture sensing.
740 |
741 | Returns:
742 | int: current exit proximity threshold
743 | """
744 | return self._read_byte_data(APDS9960_REG_GEXTH)
745 |
746 | def setGestureExitThresh(self, threshold):
747 | """Sets the exit proximity threshold for gesture sensing.
748 |
749 | Args:
750 | threshold (int): threshold proximity value needed to end gesture mode
751 | """
752 | self._write_byte_data(APDS9960_REG_GEXTH, threshold)
753 |
754 |
755 | def getGestureGain(self):
756 | """Gets the gain of the photodiode during gesture mode.
757 |
758 | Value Gain
759 | 0 1x
760 | 1 2x
761 | 2 4x
762 | 3 8x
763 |
764 | Returns:
765 | int: the current photodiode gain
766 | """
767 | val = self._read_byte_data(APDS9960_REG_GCONF2)
768 |
769 | # shift and mask out PDRIVE bits
770 | return (val >> 5) & 0b00000011
771 |
772 | def setGestureGain(self, gain):
773 | """Sets the gain of the photodiode during gesture mode.
774 |
775 | Value Gain
776 | 0 1x
777 | 1 2x
778 | 2 4x
779 | 3 8x
780 |
781 | Args:
782 | gain (int): the value for the photodiode gain
783 | """
784 | val = self._read_byte_data(APDS9960_REG_GCONF2)
785 |
786 | # set bits in register to given value
787 | gain &= 0b00000011
788 | gain = gain << 5
789 | val &= 0b10011111
790 | val |= gain
791 |
792 | self._write_byte_data(APDS9960_REG_GCONF2, val)
793 |
794 |
795 | def getGestureLEDDrive(self):
796 | """Gets the drive current of the LED during gesture mode.
797 |
798 | Value LED Current
799 | 0 100 mA
800 | 1 50 mA
801 | 2 25 mA
802 | 3 12.5 mA
803 |
804 | Returns:
805 | int: the LED drive current value
806 | """
807 | val = self._read_byte_data(APDS9960_REG_GCONF2)
808 |
809 | # shift and mask out LED drive bits
810 | return (val >> 3) & 0b00000011
811 |
812 | def setGestureLEDDrive(self, drive):
813 | """Sets LED drive strength for proximity and ALS.
814 |
815 | Value LED Current
816 | 0 100 mA
817 | 1 50 mA
818 | 2 25 mA
819 | 3 12.5 mA
820 |
821 | Args:
822 | drive (int): value for the LED drive current
823 | """
824 | val = self._read_byte_data(APDS9960_REG_GCONF2)
825 |
826 | # set bits in register to given value
827 | drive &= 0b00000011;
828 | drive = drive << 3;
829 | val &= 0b11100111;
830 | val |= drive;
831 |
832 | self._write_byte_data(APDS9960_REG_GCONF2, val)
833 |
834 |
835 | def getGestureWaitTime(self):
836 | """Gets the time in low power mode between gesture detections.
837 |
838 | Value Wait time
839 | 0 0 ms
840 | 1 2.8 ms
841 | 2 5.6 ms
842 | 3 8.4 ms
843 | 4 14.0 ms
844 | 5 22.4 ms
845 | 6 30.8 ms
846 | 7 39.2 ms
847 |
848 | Returns:
849 | int: the current wait time between gestures
850 | """
851 | val = self._read_byte_data(APDS9960_REG_GCONF2)
852 |
853 | # shift and mask out LED drive bits
854 | return val & 0b00000111
855 |
856 | def setGestureWaitTime(self, time):
857 | """Sets the time in low power mode between gesture detections.
858 |
859 | Value Wait time
860 | 0 0 ms
861 | 1 2.8 ms
862 | 2 5.6 ms
863 | 3 8.4 ms
864 | 4 14.0 ms
865 | 5 22.4 ms
866 | 6 30.8 ms
867 | 7 39.2 ms
868 |
869 | Args:
870 | time (int): value for the wait time
871 | """
872 | val = self._read_byte_data(APDS9960_REG_GCONF2)
873 |
874 | # set bits in register to given value
875 | time &= 0b00000111
876 | val &= 0b11111000
877 | val |= time
878 |
879 | self._write_byte_data(APDS9960_REG_GCONF2, val)
880 |
881 |
882 | def getLightIntLowThreshold(self):
883 | """Gets the low threshold for ambient light interrupts.
884 |
885 | Returns:
886 | int: threshold current low threshold stored on the APDS9960
887 | """
888 | return self._read_byte_data(APDS9960_REG_AILTL) | (self._read_byte_data(APDS9960_REG_AILTH) << 8)
889 |
890 | def setLightIntLowThreshold(self, threshold):
891 | """Sets the low threshold for ambient light interrupts.
892 |
893 | Args:
894 | threshold (int): low threshold value for interrupt to trigger
895 | """
896 | # break 16-bit threshold into 2 8-bit values
897 | self._write_byte_data(APDS9960_REG_AILTL, threshold & 0x00ff)
898 | self._write_byte_data(APDS9960_REG_AILTH, (threshold & 0xff00) >> 8)
899 |
900 |
901 | def getLightIntHighThreshold(self):
902 | """Gets the high threshold for ambient light interrupts.
903 |
904 | Returns:
905 | int: threshold current low threshold stored on the APDS9960
906 | """
907 | return self._read_byte_data(APDS9960_REG_AIHTL) | (self._read_byte_data(APDS9960_REG_AIHTH) << 8)
908 |
909 | def setLightIntHighThreshold(self, threshold):
910 | """Sets the high threshold for ambient light interrupts.
911 |
912 | Args:
913 | threshold (int): high threshold value for interrupt to trigger
914 | """
915 | # break 16-bit threshold into 2 8-bit values
916 | self._write_byte_data(APDS9960_REG_AIHTL, threshold & 0x00ff)
917 | self._write_byte_data(APDS9960_REG_AIHTH, (threshold & 0xff00) >> 8)
918 |
919 |
920 | def getProximityIntLowThreshold(self):
921 | """Gets the low threshold for proximity interrupts.
922 |
923 | Returns:
924 | int: threshold current low threshold stored on the APDS9960
925 | """
926 | return self._read_byte_data(APDS9960_REG_PILT)
927 |
928 | def setProximityIntLowThreshold(self, threshold):
929 | """Sets the low threshold for proximity interrupts.
930 |
931 | Args:
932 | threshold (int): low threshold value for interrupt to trigger
933 | """
934 | self._write_byte_data(APDS9960_REG_PILT, threshold)
935 |
936 |
937 | def getProximityIntHighThreshold(self):
938 | """Gets the high threshold for proximity interrupts.
939 |
940 | Returns:
941 | int: threshold current high threshold stored on the APDS9960
942 | """
943 | return self._read_byte_data(APDS9960_REG_PIHT)
944 |
945 | def setProximityIntHighThreshold(self, threshold):
946 | """Sets the high threshold for proximity interrupts.
947 |
948 | Args:
949 | threshold (int): high threshold value for interrupt to trigger
950 | """
951 | self._write_byte_data(APDS9960_REG_PIHT, threshold)
952 |
953 |
954 | def getAmbientLightIntEnable(self):
955 | """Gets if ambient light interrupts are enabled or not.
956 |
957 | Returns:
958 | bool: True if interrupts are enabled, False if not
959 | """
960 | val = self._read_byte_data(APDS9960_REG_ENABLE)
961 | return (val >> 4) & 0b00000001 == 1
962 |
963 | def setAmbientLightIntEnable(self, enable):
964 | """Turns ambient light interrupts on or off.
965 |
966 | Args:
967 | enable (bool): True to enable interrupts, False to turn them off
968 | """
969 | val = self._read_byte_data(APDS9960_REG_ENABLE)
970 |
971 | # set bits in register to given value
972 | val &= 0b11101111;
973 | if enable:
974 | val |= 0b00010000
975 |
976 | self._write_byte_data(APDS9960_REG_ENABLE, val)
977 |
978 |
979 | def getProximityIntEnable(self):
980 | """Gets if proximity interrupts are enabled or not.
981 |
982 | Returns:
983 | bool: True if interrupts are enabled, False if not
984 | """
985 | val = self._read_byte_data(APDS9960_REG_ENABLE)
986 | return (val >> 5) & 0b00000001 == 1
987 |
988 | def setProximityIntEnable(self, enable):
989 | """Turns proximity interrupts on or off.
990 |
991 | Args:
992 | enable (bool): True to enable interrupts, False to turn them off
993 | """
994 | val = self._read_byte_data(APDS9960_REG_ENABLE)
995 |
996 | # set bits in register to given value
997 | val &= 0b11011111;
998 | if enable:
999 | val |= 0b00100000
1000 |
1001 | self._write_byte_data(APDS9960_REG_ENABLE, val)
1002 |
1003 |
1004 | def getGestureIntEnable(self):
1005 | """Gets if gesture interrupts are enabled or not.
1006 |
1007 | Returns:
1008 | bool: True if interrupts are enabled, False if not
1009 | """
1010 | val = self._read_byte_data(APDS9960_REG_GCONF4)
1011 | return (val >> 1) & 0b00000001 == 1
1012 |
1013 | def setGestureIntEnable(self, enable):
1014 | """Turns gesture-related interrupts on or off.
1015 |
1016 | Args:
1017 | enable (bool): True to enable interrupts, False to turn them off
1018 | """
1019 | val = self._read_byte_data(APDS9960_REG_GCONF4)
1020 |
1021 | # set bits in register to given value
1022 | val &= 0b11111101
1023 | if enable:
1024 | val |= 0b00000010
1025 |
1026 | self._write_byte_data(APDS9960_REG_GCONF4, val)
1027 |
1028 |
1029 | def clearAmbientLightInt(self):
1030 | """Clears the ambient light interrupt.
1031 | """
1032 | self._read_byte_data(APDS9960_REG_AICLEAR)
1033 |
1034 |
1035 | def clearProximityInt(self):
1036 | """Clears the proximity interrupt.
1037 | """
1038 | self._read_byte_data(APDS9960_REG_PICLEAR)
1039 |
1040 |
1041 | def getGestureMode(self):
1042 | """Tells if the gesture state machine is currently running.
1043 |
1044 | Returns:
1045 | bool: True if gesture state machine is running, False if not
1046 | """
1047 | val = self._read_byte_data(APDS9960_REG_GCONF4)
1048 | return val & 0b00000001 == 1
1049 |
1050 | def setGestureMode(self, enable):
1051 | """Turns gesture-related interrupts on or off.
1052 |
1053 | Args:
1054 | enable (bool): True to enter gesture state machine, False to turn them off
1055 | """
1056 | val = self._read_byte_data(APDS9960_REG_GCONF4)
1057 |
1058 | # set bits in register to given value
1059 | val &= 0b11111110
1060 | if enable:
1061 | val |= 0b00000001
1062 |
1063 | self._write_byte_data(APDS9960_REG_GCONF4, val)
1064 |
1065 |
1066 | # *******************************************************************************
1067 | # Raw I2C Reads and Writes
1068 | # *******************************************************************************
1069 |
1070 | def _read_byte_data(self, cmd):
1071 | return self.bus.read_byte_data(self.address, cmd)
1072 |
1073 | def _write_byte_data(self, cmd, val):
1074 | return self.bus.write_byte_data(self.address, cmd, val)
1075 |
1076 |
1077 | def _read_i2c_block_data(self, cmd, num):
1078 | return self.bus.read_i2c_block_data(self.address, cmd, num)
1079 |
1080 |
1081 | # *******************************************************************************
1082 | # High-level gesture controls
1083 | # *******************************************************************************
1084 |
1085 | # resets all the parameters in the gesture data member
1086 |
1087 |
1088 |
1089 | class uAPDS9960(APDS9960):
1090 | """
1091 | APDS9960 for MicroPython
1092 |
1093 | sensor = uAPDS9960(bus=I2C_instance,
1094 | address=APDS9960_I2C_ADDR, valid_id=APDS9960_DEV_ID)
1095 | """
1096 | def _read_byte_data(self, cmd):
1097 | return self.bus.readfrom_mem(self.address, cmd, 1)[0]
1098 |
1099 | def _write_byte_data(self, cmd, val):
1100 | self.bus.writeto_mem(self.address, cmd, bytes([val]))
1101 |
1102 | def _read_i2c_block_data(self, cmd, num):
1103 | return self.bus.readfrom_mem(self.address, cmd, num)
1104 |
--------------------------------------------------------------------------------