2020-04-28 01:18 AM
Hi there,
My application is battery operated, so I’m trying to wake up atmega328p from deep sleep from an interrupt though the GPIO pin from the sensor.
I'm using Thresholds, "inside window". If any object ditected inside the range, to fire a trigger to wake up the host.
Is such thing possible?
If yes, could you give me some pointers or code samples please?
My host platform is Arduino Pro Mini @ 8Mhz 3.3v.
Thanks!
Solved! Go to Solution.
2020-04-29 07:20 AM
The camera test shows that the sensor is working. If it's flashing, it's ranging.
The interrupt is active low, so going low indicates it's got a range that meets your ranging conditions.
You are using the Pololu code which I'm not really good at, but I can guess.
Place the .startRangeing() call OUTSIDE your loop.
And don't stop it until you want to shut the system off. So take the stopRanging() out of your loop.
Once the sensor is running, it will stay running until you stop it.
Continually starting the senor will goof everything up.
It may well be that you get one interrupt that is outside your window.
So for every interrupt read the range to double check, then just go back to sleep.
2020-04-28 07:36 AM
Thresholds and interrupts are available to do exactly what you want.
With the VL53L1X you have two choices.
The full driver which exposes all the functionality of the sensor, or the UltraLite Driver, which is limited but is very small.
STSW-IMG007 is the full driver, STSW-IMG009 is the UltraLite Driver.
Both can be found on the by searching the web site for VL53L1X.
Using the ULD,
VL53LX_SetDistanceThreshold (). The available detection condition usecases
include:
• Object under a certain distance
• Objet beyond a certain distance
• Object within a window limited by a near and far threshold
• Object out of a window limited by a near and far threshold
Using the Full driver, the ability is the same, but the call is different.
2020-04-28 09:14 AM
Thanks John,
Question;
Looking at the "Ranging flow" diagram (in UM2510),
if I'm using "VL53LX_SetDistanceThreshold" with detection condition to be "Object within a window",
Do the interrupt triggers when an object comes within the window?
Or does the interrupt triggers Autonomously ?
2020-04-28 09:37 AM
I'd do it this way.
Write your code without the thresholds.
Prove it ranges and you can get the data.
if you have a non-iPhone or can use your laptop camera, you can see the flash of light. (Iphones have really good IR filters, so they will not see the light).
The sensor will continue to range even if you don't read the answer.
Then re-write your code and insert the set_thresholds, and your window.
You will see that you only get an interrupt when an object comes within your window.
So to answer your questions:
Do the interrupt triggers when an object comes within the window?
You will get the interrupt after the range occurs with an object within the threshold window
Or does the interrupt triggers Autonomously?
The sensor will run completely autonomously giving an interrupt only when your thresholds are met.
2020-04-29 07:04 AM
:backhand_index_pointing_right: Please I'm a novice and kindly excuse my coding and questions if they seems as lame.:backhand_index_pointing_left:
I'm not sure why you asked me to do try this.
I did the camera test with my laptop camera and I see the light emitting from the sensor on both set of code.
light was always visible.
with regards to the interrupt;
Below is the pseudocode of my program.
It print the GPIO pin state so that I can see if an interrupt had occurred.
But all I see only 0 (digital low) being printed.
I checked and I realized the Sensor pulls the GPIO to low.
But what puzzles me is that it is always pulled to low within or outside the range.
And I'm clueless how i could implement a wake-up on interrupt for my project.
Btw: My test module is from Pololu https://www.pololu.com/product/3415/specs
setup()
{
Sensor.init()
Sensor.setDistanceModeLong();
Sensor.setDistanceThreshold(50, 100, 3); //Min:50mm, Max:100mm, Window: Within a distance range (min/max), "inside window"
}
loop()
{
Sensor.startRanging();
while (!Sensor.checkForDataReady()){
println(digitalRead(2)); //Read the GPIO pin
}
int x = Sensor.getDistance();
Sensor.clearInterrupt();
Sensor.stopRanging();
}
2020-04-29 07:20 AM
The camera test shows that the sensor is working. If it's flashing, it's ranging.
The interrupt is active low, so going low indicates it's got a range that meets your ranging conditions.
You are using the Pololu code which I'm not really good at, but I can guess.
Place the .startRangeing() call OUTSIDE your loop.
And don't stop it until you want to shut the system off. So take the stopRanging() out of your loop.
Once the sensor is running, it will stay running until you stop it.
Continually starting the senor will goof everything up.
It may well be that you get one interrupt that is outside your window.
So for every interrupt read the range to double check, then just go back to sleep.
2020-04-29 07:58 AM
I'm using the Sparkfun library since Pololu library does not have setDistanceThreshold implemented.
Let me try the changes you've mentioned.
Thanks!
2020-05-08 09:00 AM
Okay I managed to get this to work with Sparkfun library for Arduino.
Only thing I should point here is that if anyone using the Sparkfun library for Arduino, make sure to set
setInterruptPolarityLow();
if your interrupt is on a LOW signal as below line of coding,
attachInterrupt(0, wakeUp, LOW);
My test example code here if anyone is interested;
#include <avr/sleep.h>
#include <Wire.h>
#include "SparkFun_VL53L1X.h"
#define SHUTDOWN_PIN 10
#define INTERRUPT_PIN 2
long heartBeatTime = 0, count = 0, pollingInterval = 0;;
int heartBeatLedState = LOW;
int status;
SFEVL53L1X distanceSensor(Wire, SHUTDOWN_PIN, INTERRUPT_PIN);
void setup()
{
pinMode(INTERRUPT_PIN, INPUT_PULLUP);
pinMode(SHUTDOWN_PIN, OUTPUT);
digitalWrite(SHUTDOWN_PIN, HIGH);
ADCSRA &= ~(1 << 7);
Wire.begin();
Serial.begin(9600);
Serial.println(F("VL53L1X Qwiic Test"));
if (distanceSensor.begin() == 0) //Begin returns 0 on a good init
{
Serial.println(F("Sensor online!"));
}
distanceSensor.setInterruptPolarityLow();
distanceSensor.setDistanceModeLong();
distanceSensor.setDistanceThreshold(50, 1000, 3);
distanceSensor.startRanging();
}
void loop(void)
{
if ((millis() - heartBeatTime) >= 1000)
{
heartBeatTime = millis();
if (heartBeatLedState == LOW) {
heartBeatLedState = HIGH;
} else {
heartBeatLedState = LOW;
}
digitalWrite(LED_BUILTIN, heartBeatLedState);
}
if ((millis() - pollingInterval) >= 10)
{
pollingInterval = millis();
static uint16_t startMs = millis();
// non-blocking check for data ready
status = distanceSensor.checkForDataReady();
if(status)
{
int distance = distanceSensor.getDistance();
Serial.print(F("count: "));
Serial.print(count);
Serial.print(F(" distance: "));
Serial.println(distance);
distanceSensor.clearInterrupt();
startMs = millis();
}
else if((uint16_t)(millis() - startMs) > 10000) //Goes to sleep if no object in range for 10 seconds
{
Serial.println(F("Entering CPU low power sleep."));
distanceSensor.clearInterrupt();
startMs = millis();
Going_To_Sleep();
Serial.println(count);
}
}
}
void Going_To_Sleep(){
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
MCUCR = bit (BODS) | bit (BODSE);
MCUCR = bit (BODS);
noInterrupts();
attachInterrupt(0, wakeUp, LOW);
digitalWrite(LED_BUILTIN, LOW);
Serial.println(F("I'm going to bed!"));
Serial.flush();
interrupts();
sleep_cpu();
Serial.println(F("I just now woke up!"));
digitalWrite(LED_BUILTIN, HIGH);
}
void wakeUp(){
count++;
sleep_disable();
detachInterrupt(0);
}