Using APDS-9960 with Teensy 4.0 Microcontroller

Hello everyone,

I am currently trying to get the APDS9960 to work with a Teensy 4.0 microcontroller. I am using the Sparkfun Library and the the GestureTest Sketch as a basis. I’m a beginner when it comes to microcontrollers so I’m hoping it’s something obvious :slight_smile:

Maybe important to note is that i already tried using the adafruit library for the sensor and everything worked. I would prefer to use the Sparkfun Library because it has the NEAR/FAR Gestures that I need for my project which the adafruit library doesn’t.

There are two problems with the Sparkfun Libary

  1. the interrupt routine only get’s called once. So when I wave my hand in front of the sensor the flag gets changed, the gesture is handled, the flag gets changed back and then the routine won’t get called again.

  2. the gesture handling doesn’t work even when i remove all the interrupt stuff and call handleGesture() in the Loop method. isGestureAvailable() is false at the beginning (which it should be) and when i wave my hand in front of the sensor it becomes true but the code goes straight for the default case in the switch which is NONE. After that isGestureAvailable() is stuck on true and I just get infinite NONEs in the console.

I don’t need to use interrupts that badly but I would especially appreciate help with the second Problem. I assume it’s a Teensy Problem but I don’t know what it is. If there are no solutions for both Problems then I guess I could use the Adafruit Library and manually add the NEAR/FAR gestures but I have no experience with changing libraries and coding so close to the hardware.

This is the code I’m using:

#include <SparkFun_APDS9960.h>

// Pins
#define APDS9960_INT 2 // Needs to be an interrupt pin

// Global Variables
SparkFun_APDS9960 apds = SparkFun_APDS9960();
int isr_flag = 0;

void setup() {

  // Set interrupt pin as input
  pinMode(APDS9960_INT, INPUT);

  // Initialize Serial port
  Serial.begin(9600);
  Serial.println();
  Serial.println(F("--------------------------------"));
  Serial.println(F("SparkFun APDS-9960 - GestureTest"));
  Serial.println(F("--------------------------------"));
  
  // Initialize interrupt service routine
  attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);

  // Initialize APDS-9960 (configure I2C and initial values)
  if ( apds.init() ) {
    Serial.println(F("APDS-9960 initialization complete"));
  } else {
    Serial.println(F("Something went wrong during APDS-9960 init!"));
  }
  
  // Start running the APDS-9960 gesture sensor engine
  if ( apds.enableGestureSensor(true) ) {
    Serial.println(F("Gesture sensor is now running"));
  } else {
    Serial.println(F("Something went wrong during gesture sensor init!"));
  }
}

void loop() {

  if( isr_flag == 1 ) {
    Serial.println("Interrupt works");
    Serial.println(isr_flag);
    detachInterrupt(digitalPinToInterrupt(APDS9960_INT));
    handleGesture();
    isr_flag = 0;
    Serial.println(isr_flag);
    attachInterrupt(digitalPinToInterrupt(APDS9960_INT), interruptRoutine, FALLING);
  }
}

void interruptRoutine() {
  isr_flag = 1;
}

void handleGesture() {
    if ( apds.isGestureAvailable() ) {
    switch ( apds.readGesture() ) {
      case DIR_UP:
        Serial.println("UP");
        break;
      case DIR_DOWN:
        Serial.println("DOWN");
        break;
      case DIR_LEFT:
        Serial.println("LEFT");
        break;
      case DIR_RIGHT:
        Serial.println("RIGHT");
        break;
      case DIR_NEAR:
        Serial.println("NEAR");
        break;
      case DIR_FAR:
        Serial.println("FAR");
        break;
      default:
        Serial.println("NONE");
    }
  }
}

My console outputs are:


SparkFun APDS-9960 - GestureTest


APDS-9960 initialization complete

Gesture sensor is now running

Interrupt works

1

NONE

0

And nothing after that, no matter how many times I wave my hand.

Thanks in advance for any help.

Update: I figured out that the Interrupt Pin goes from HIGH to LOW and the readGesture() method is supposed to reset the Interrupt back to HIGH. For some reason it doesn’t reset the pin, even though the method gets called. So it’s stuck on LOW which is why the routine only gets called once.

But I still haven’t figured out why this happens or why I only get NONE as a gesture.

Thanks for reaching out to us on this.

The problem is likely that our hookup/libraries pecify an AVR controller, the teensy is an ARM…here is a link to someone who appears to have solved the conflict (post #9, 4/5 the way down) https://forum.pjrc.com/threads/32286-AP … ith-teensy

Hope this helps, and happy sparking!

TS-Russell:
Thanks for reaching out to us on this.

The problem is likely that our hookup/libraries pecify an AVR controller, the teensy is an ARM…here is a link to someone who appears to have solved the conflict (post #9, 4/5 the way down) https://forum.pjrc.com/threads/32286-AP … ith-teensy

Hope this helps, and happy sparking!

Thanks for your answer. Sadly i already tried that and nothing changed. I figured out that the code is actually working, but you have to move your hand extremely fast. Way faster than anyone would want to. I don’t know how to increase the timewindow for measuring the gesture. That’s also when the code stops working entirely. If i move my hand extremely fast, it can decode the gesture. If i move my hand fast but at a weird angle i get a NONE, but the code keeps working and the Interrupt gets reset, like it should. It only freezes when i move my hand to slow.

The following is a outprint of the code with debug options turned on. I added a couple outprints to the library just to see where i am in the code. The first block is a successfull gesture, the second is a gesture that wasn’t recognized but i moved my hand fast enough so it reset the interrupt and the third block happens when i move my hand slowly and then the code freezes, because the interrupt isn’t reset.


SparkFun APDS-9960 - GestureTest


APDS-9960 initialization complete

Gesture sensor is now running

Gstatus: 1

GValid: 1

Combo: 1

FIFO Level: 7

FIFO Dump: 64 32 46 46 69 38 46 58 67 34 32 60 59 25 15 53 47 12 1 46 36 0 0 38 26 0 0 26

Up Data: 64 69 67 59 47 36 26

Finding last: U:26 D:0 L:0 R:26

Finding last: U:36 D:0 L:0 R:38

Finding last: U:47 D:12 L:1 R:46

Finding last: U:59 D:25 L:15 R:53

Last Values: U:59 D:25 L:15 R:53

Ratios: UD Fi: 33 UD La: 40 LR Fi: 0 LR La: -55

Deltas: UD: 7 LR: -55

Accumulations: UD: 7 LR: -55

LR Delta negative

UD_CT: 0 LR_CT: -1 NEAR_CT: 0 FAR_CT: 0


Gstatus: 0

GValid: 1

Combo: 0

Else

Decoding gesture

Swipe LEFT decoded

END: 1

LEFT

Gstatus: 1

GValid: 1

Combo: 1

FIFO Level: 7

FIFO Dump: 66 36 30 76 83 55 55 84 88 71 74 81 77 67 75 61 61 46 48 35 40 18 14 16 22 0 0 11

Up Data: 66 83 88 77 61 40 22

Finding last: U:22 D:0 L:0 R:11

Finding last: U:40 D:18 L:14 R:16

Last Values: U:40 D:18 L:14 R:16

Ratios: UD Fi: 29 UD La: 37 LR Fi: -43 LR La: -6

Deltas: UD: 8 LR: 37

Accumulations: UD: 8 LR: 37

UD_CT: 0 LR_CT: 0 NEAR_CT: 0 FAR_CT: 0


Gstatus: 0

GValid: 1

Combo: 0

Else

Decoding gesture

END: 0

NONE

Gstatus: 1

GValid: 1

Combo: 1

FIFO Level: 9

FIFO Dump: 77 48 82 52 106 76 118 80 129 104 143 107 154 129 148 139 164 129 132 154 155 115 101 157 136 89 59 139 108 57 26 109

Up Data: 77 106 129 154 164 155 136 108

Finding last: U:108 D:57 L:26 R:109

Last Values: U:108 D:57 L:26 R:109

Ratios: UD Fi: 23 UD La: 30 LR Fi: 22 LR La: -61

Deltas: UD: 7 LR: -83

Accumulations: UD: 7 LR: -83

LR Delta negative

UD_CT: 0 LR_CT: -1 NEAR_CT: 0 FAR_CT: 0


Status Error

NONE

I try to fully understand how the library works but i’m still lost. Thanks in advance.

My suggestion at this point would be to fiddle with the FIFO values, the ratios, and the deltas in the library itself…

If it’s only working when moving FAST, the ratios & deltas may be set too high and low, respectively…only tracking when your hand is encoded as triggering as ‘high’ ratio of ‘last position’ to ‘current position’, or registering too low of a delta (change) from the last position

I imagine this isn’t ideal, but it’s something.

Alternatively, try searching around for a project/post where someone successfully used your set-up and try to find their code.

Best of luck!