Skip to content

Instantly share code, notes, and snippets.

@fnishio
Last active May 4, 2017 05:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fnishio/8e9b5018a7e752569e36 to your computer and use it in GitHub Desktop.
Save fnishio/8e9b5018a7e752569e36 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import wiringpi2 as wp
class APDS9960:
# Register addresses
REG_ENABLE = 0x80
REG_ATIME = 0x81
REG_WTIME = 0x83
REG_AILTL = 0x84
REG_AILTH = 0x85
REG_AIHTL = 0x86
REG_AIHTH = 0x87
REG_PILT = 0x89
REG_PIHT = 0x8B
REG_PERS = 0x8C
REG_CONFIG1 = 0x8D
REG_PPULSE = 0x8E
REG_CONTROL = 0x8F
REG_CONFIG2 = 0x90
REG_ID = 0x92
REG_STATUS = 0x93
REG_CDATAL = 0x94
REG_CDATAH = 0x95
REG_RDATAL = 0x96
REG_RDATAH = 0x97
REG_GDATAL = 0x98
REG_GDATAH = 0x99
REG_BDATAL = 0x9A
REG_BDATAH = 0x9B
REG_PDATA = 0x9C
REG_POFFSET_UR = 0x9D
REG_POFFSET_DL = 0x9E
REG_CONFIG3 = 0x9F
REG_GPENTH = 0xA0
REG_GEXTH = 0xA1
REG_GCONF1 = 0xA2
REG_GCONF2 = 0xA3
REG_GOFFSET_U = 0xA4
REG_GOFFSET_D = 0xA5
REG_GOFFSET_L = 0xA7
REG_GOFFSET_R = 0xA9
REG_GPULSE = 0xA6
REG_GCONF3 = 0xAA
REG_GCONF4 = 0xAB
REG_GFLVL = 0xAE
REG_GSTATUS = 0xAF
REG_IFORCE = 0xE4
REG_PICLEAR = 0xE5
REG_CICLEAR = 0xE6
REG_AICLEAR = 0xE7
REG_GFIFO_U = 0xFC
REG_GFIFO_D = 0xFD
REG_GFIFO_L = 0xFE
REG_GFIFO_R = 0xFF
# Enable register bits
ENABLE_GEN = 0b01000000 # Gesture enable
ENABLE_PIEN = 0b00100000 # Proximity Interrupt Enable
ENABLE_AIEN = 0b00010000 # ALS Interrupt Enable
ENABLE_WEN = 0b00001000 # Wait Enable
ENABLE_PEN = 0b00000100 # Proximity Enable
ENABLE_AEN = 0b00000010 # ALS Enable
ENABLE_PON = 0b00000001 # Power ON
# Congiguration register 2
CONFIG2_LEDBOOST_150 = (1 << 4) # LED boost 150%
CONFIG2_LEDBOOST_200 = (2 << 4) # LED boost 300%
CONFIG2_LEDBOOST_300 = (3 << 4) # LED boost 300%
GCONFIG3_GDIMS_LR = 2
GCONFIG3_GDIMS_UD = 1 # 01
GCONFIG4_GMODE = 1 # Gesture mode
def __init__(self, i2c_addr = 0x39):
self.i2c_addr = i2c_addr
self.i2c = wp.I2C()
self.fd = self.i2c.setup(i2c_addr)
def _write(register, data8):
self.i2c.writeReg8(self.fd, register, data8)
def _read(register):
self.i2c.readReg8(self.fd, self.register)
def initialize(self):
if (self.get_device_id() != 0xAB):
return false
self.write(self.REG_ENABLE,
self.ENABLE_PON | self.ENABLE_PEN | self.ENABLE_GEN)
self.write(self.REG_CONFIG2,
self.CONFIG2_LEDBOOST_300)
self.write(self.REG_GOFFSET_U, 70)
self.write(self.REG_GOFFSET_D, 0)
self.write(self.REG_GOFFSET_L, 10)
self.write(self.REG_GOFFSET_R, 34)
self.write(self.REG_CONFIG3,
self.GCONFIG3_GDIMS_UD | self.GCONFIG3_GDIMS_LR)
self.write(self.REG_GCONFIG4, GCONFIG4_GMODE)
def get_device_id(self):
return _read(self.REG_ID)
def gesture(self):
level = _read(self.REG_GFLVL)
if (level == 0):
return # no data
fifo_u = _read(self.REG_GFIFO_U)
fifo_d = _read(self.REG_GFIFO_D)
fifo_l = _read(self.REG_GFIFO_L)
fifo_r = _read(self.REG_GFIFO_R)
if __name__ == '__main__':
sensor = APDS9960()
print("device ID: {:#X}".format(sensor.get_device_id()))
sensor.initialize()
sensor.gesture()
@Stan92
Copy link

Stan92 commented Apr 14, 2017

Hi
I'm trying to use your code but get an error saying '_read' is not defined.
How can I fix it?

@frank-f
Copy link

frank-f commented Apr 22, 2017

I don''t think this code ever worked. I modified it to some extend so it reads the device ID, but beyond that this code has a) lots more errors and b) does basically nothing.

@frank-f
Copy link

frank-f commented Apr 24, 2017

My main problem is, that I get completely wrong data. For example, get_device_id() returns 0xD0 instead of 0xAB and I have absolutely no clue why it's doing that. I triple checked all registers and addresses, changed the code to use SMbus instead of wiringpi, but I'm still getting the same results. I can control my HD44780 LCD with the same SMbus calls just fine. Also the sensor itself is not broken, because with a C++ program everything works just fine. I am puzzled.

@frank-f
Copy link

frank-f commented Apr 24, 2017

Well, disregard my last comment. I was apparently way overdue to sleep last night. 0xD0 is a different sensor, that I have hooked up to my I2C bus aswell. I put the correct I2C address in my script today and wah la, querying the APDS 9660 with python works as expected. :)

@gregmacway
Copy link

Same error as Stan above. Frank, can you post your working code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment