Skip to content

Commit

Permalink
feat: Added APDS9960 Gesture, Color, Proximity and Ambient Light Sensor
Browse files Browse the repository at this point in the history
  • Loading branch information
AsCress authored and marcnause committed Aug 19, 2024
1 parent 59efa1b commit 7ac5459
Show file tree
Hide file tree
Showing 6 changed files with 1,131 additions and 1 deletion.
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
<activity android:name=".sensors.SensorTSL2561" />
<activity android:name=".sensors.SensorVL53L0X" />
<activity android:name=".sensors.SensorCCS811" />

<activity android:name=".sensors.SensorAPDS9960" />
</application>

</manifest>
6 changes: 6 additions & 0 deletions app/src/main/java/io/pslab/activity/SensorActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.pslab.others.CustomSnackBar;
import io.pslab.others.ScienceLabCommon;
import io.pslab.sensors.SensorADS1115;
import io.pslab.sensors.SensorAPDS9960;
import io.pslab.sensors.SensorBMP180;
import io.pslab.sensors.SensorCCS811;
import io.pslab.sensors.SensorHMC5883L;
Expand Down Expand Up @@ -83,6 +84,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
sensorAddr.put(0x69, "MPU925x");
sensorAddr.put(0x29, "VL53L0X");
sensorAddr.put(0x5A, "CCS811");
sensorAddr.put(0x39, "APDS9960");

adapter = new ArrayAdapter<>(getApplication(), R.layout.sensor_list_item, R.id.tv_sensor_list_item, dataName);

Expand Down Expand Up @@ -141,6 +143,10 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
intent = new Intent(getApplication(), SensorCCS811.class);
startActivity(intent);
break;
case "APDS9960":
intent = new Intent(getApplication(), SensorAPDS9960.class);
startActivity(intent);
break;
default:
CustomSnackBar.showSnackBar(findViewById(android.R.id.content),
"Sensor Not Supported", null, null, Snackbar.LENGTH_SHORT);
Expand Down
156 changes: 156 additions & 0 deletions app/src/main/java/io/pslab/communication/sensors/APDS9960.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
package io.pslab.communication.sensors;

import java.io.IOException;
import java.util.ArrayList;

import io.pslab.communication.ScienceLab;
import io.pslab.communication.peripherals.I2C;

public class APDS9960 {

// APDS9960 default address
private static final int APDS9960_I2C_ADDRESS = 0x39;
private final I2C i2c;

private static final int APDS9960_ENABLE = 0x80;
private static final int APDS9960_ATIME = 0x81;
private static final int APDS9960_PILT = 0x89;
private static final int APDS9960_PERS = 0x8C;
private static final int APDS9960_CONTROL = 0x8F;
private static final int APDS9960_CDATAL = 0x94;
private static final int APDS9960_PDATA = 0x9C;
private static final int APDS9960_GPENTH = 0xA0;
private static final int APDS9960_GEXTH = 0xA1;
private static final int APDS9960_GCONF1 = 0xA2;
private static final int APDS9960_GCONF2 = 0xA3;
private static final int APDS9960_GPULSE = 0xA6;
private static final int APDS9960_GCONF4 = 0xAB;
private static final int APDS9960_AICLEAR = 0xE7;

private static final int BIT_MASK_ENABLE_EN = 0x01;
private static final int BIT_MASK_ENABLE_COLOR = 0x02;
private static final int BIT_MASK_ENABLE_PROX = 0x04;
private static final int BIT_MASK_ENABLE_GESTURE = 0x40;
private static final int BIT_MASK_GCONF4_GFIFO_CLR = 0x04;

private static final int BIT_POS_PERS_PPERS = 4;
private static final int BIT_MASK_PERS_PPERS = 0xF0;

private static final int BIT_POS_CONTROL_AGAIN = 0;
private static final int BIT_MASK_CONTROL_AGAIN = 3;

public APDS9960(I2C i2c, ScienceLab scienceLab) throws Exception {
this.i2c = i2c;
if (scienceLab.isConnected()) {
enableProximity(false);
enableGesture(false);
enableColor(false);

setProximityInterruptThreshold(new int[]{0, 0, 0});
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GPENTH);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GEXTH);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GCONF1);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GCONF2);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GCONF4);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_GPULSE);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{255}, APDS9960_ATIME);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_CONTROL);

clearInterrupt();

setBit(APDS9960_GCONF4, BIT_MASK_GCONF4_GFIFO_CLR, true);

i2c.write(APDS9960_I2C_ADDRESS, new int[]{0}, APDS9960_ENABLE);
Thread.sleep(25);

enable(true);
Thread.sleep(10);

setProximityInterruptThreshold(new int[]{0, 5, 4});
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0x05}, APDS9960_GPENTH);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0x1E}, APDS9960_GEXTH);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0x82}, APDS9960_GCONF1);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0x41}, APDS9960_GCONF2);
i2c.write(APDS9960_I2C_ADDRESS, new int[]{0x85}, APDS9960_GPULSE);
setColorIntegrationTime(256);
setColorGain(1);
}
}

private void enable(Boolean value) throws IOException {
setBit(APDS9960_ENABLE, BIT_MASK_ENABLE_EN, value);
}

public void enableProximity(Boolean value) throws IOException {
setBit(APDS9960_ENABLE, BIT_MASK_ENABLE_PROX, value);
}

public void enableGesture(Boolean value) throws IOException {
setBit(APDS9960_ENABLE, BIT_MASK_ENABLE_GESTURE, value);
}

public void enableColor(Boolean value) throws IOException {
setBit(APDS9960_ENABLE, BIT_MASK_ENABLE_COLOR, value);
}

private void setProximityInterruptThreshold(int[] settingArray) throws IOException {
if (settingArray.length != 0 && settingArray[0] >= 0 && settingArray[0] <= 255) {
i2c.write(APDS9960_I2C_ADDRESS, new int[]{settingArray[0]}, APDS9960_PILT);
}
if (settingArray.length > 1 && settingArray[0] >= 0 && settingArray[0] <= 255) {
i2c.write(APDS9960_I2C_ADDRESS, new int[]{settingArray[1]}, APDS9960_PILT);
}
int persist = 4;
if (settingArray.length > 2 && settingArray[0] >= 0 && settingArray[0] <= 15) {
persist = Math.min(settingArray[2], 15);
setBits(APDS9960_PERS, BIT_POS_PERS_PPERS, BIT_MASK_PERS_PPERS, persist);
}
}

private void clearInterrupt() throws IOException {
i2c.write(APDS9960_I2C_ADDRESS, new int[]{}, APDS9960_AICLEAR);
}

private void setColorIntegrationTime(int value) throws IOException {
i2c.write(APDS9960_I2C_ADDRESS, new int[]{256 - value}, APDS9960_ATIME);
}

private void setColorGain(int value) throws IOException {
setBits(APDS9960_CONTROL, BIT_POS_CONTROL_AGAIN, BIT_MASK_CONTROL_AGAIN, value);
}

public int getProximity() throws IOException {
ArrayList<Integer> data = i2c.read(APDS9960_I2C_ADDRESS, 1, APDS9960_PDATA);
return data.get(0) & 0xFF;
}

public int[] getColorData() throws IOException {
return new int[]{
colorData16(APDS9960_CDATAL + 2),
colorData16(APDS9960_CDATAL + 4),
colorData16(APDS9960_CDATAL + 6),
colorData16(APDS9960_CDATAL)
};
}

private void setBit(int register, int mask, Boolean value) throws IOException {
ArrayList<Integer> data = i2c.read(APDS9960_I2C_ADDRESS, 1, register);
if (value) {
data.set(0, (data.get(0) & 0xFF) | mask);
} else {
data.set(0, (data.get(0) & 0xFF) & ~mask);
}
i2c.write(APDS9960_I2C_ADDRESS, data.stream().mapToInt(Integer::intValue).toArray(), register);
}

private void setBits(int register, int pos, int mask, int value) throws IOException {
ArrayList<Integer> data = i2c.read(APDS9960_I2C_ADDRESS, 1, register);
data.set(0, ((data.get(0) & 0xFF) & ~mask) | (value << pos));
i2c.write(APDS9960_I2C_ADDRESS, data.stream().mapToInt(Integer::intValue).toArray(), register);
}

private int colorData16(int register) throws IOException {
ArrayList<Integer> data = i2c.read(APDS9960_I2C_ADDRESS, 2, register);
return ((data.get(1) & 0xFF) << 8) | ((data.get(0) & 0xFF));
}
}
Loading

0 comments on commit 7ac5459

Please sign in to comment.