2015-02-25 09:11 AM
Hello peers and engineers,
I have a VL6180X proximity sensor in my project (I only measure a range), and I want to use its GPIO1 pin as a wake-up trigger for some other electronics. Is it possible to configure VL6180X to generate interrupt and put GPIO1 in HIGH state once the distance from the target is below some threshold (e.g. 20mm) ? I tried myself to achieve this by configuring some internal registers of VL6180X but with no success. I configure SYSTEM__MODE_GPIO1 register by writing 0x20 to it (to activate GPIO Interrupt output). I also put 0x14 (20mm) into SYSRANGE_THRESH_LOW register Finally, I setup Interrupt mode source for Range readings by writing 0x01 into SYSTEM__INTERRUPT_CONFIG_GPIO register. However, my system do not behave as expected when I start it. Is there anything I'm missing in the configuration part ? Thank you very much for your time and effort. Sincerely, Bojan #vl6180x2015-02-25 12:31 PM
Bojan,
You seem to have covered the three registers that need to be set for interrupt mode:(0x0014) SYSTEM__INTERRUPT_CONFIG_GPIO = 0x02
(0x0011) SYSTEM__MODE_GPIO1
= 0x10 (Active LOW)
= 0x30 (Active HIGH)
(0x001A) SYSRANGE__THRESH_LOW = 0x14 (for 20mm)
Do you have a pull-up resistor on GPIO1 (Pin 1)?
Try changing the polarity in the SYSTEM__MODE_GPIO1 register and see if the pin changed level to test the hardware.
Another thought I had was to check that you are running in continuous mode by setting:
(0x001B) SYSRANGE__INTERMEASUREMENT_PERIOD (0x00 – 0xFF, 0 = 10ms)
And start the ranging measurements by:
Setting (0x0018) SYSRANGE__START to 0x03
Otherwise you will only take one measurement and the GPIO would only trigger on that measurement.
Ken W@ ST
2015-02-26 12:37 AM
Hello Ken,
Thank you for your help. I'm actually using VL6180X Explorer shield connected to ST's nucleo-F401RE board. I don't know the schematic, but I suppose there is a pull-up on GPIO1 given that ST recommends using it. I will try to change the polarity of the GPIO1 as you suggested. My sensor is currently configured in single shot mode. This might be the main problem since you suggest me that it should be configured in continuous mode. :) I will also try with the continuous mode by setting the appropriate registers. Since my system is battery powered one of my need is to prolong battery life as much as possible. If I configure the sensor to measure in the continuous mode, can I adjust the time between two range measurements ? If affirmative, how can I do it (which register to use and what to put in) ? What is the range of the time between two measurements ? I saw somewhere that sensor consumes about 17mA of the current while in the ranging mode and about 1uA in standby. Is it correct ? Thank you very much for your effort. Sincerely, Bojan.2015-02-26 01:20 AM
I found the answer regarding the intermeasurement period (SYSRANGE__INTERMEASUREMENT_PERIOD register). It is from 10ms to 2540ms if I'm right. :)
2015-02-26 09:50 AM
Bojan,
You are correct If you need greater than 2.54 seconds of inter-measurement time you can use the single shot mode with the interrupt, but the uP will need to wake up to send the Start command via I2C. In continuous mode, the uP can remain in sleep mode until an interrupt event occurs.
The 17mA is the average current based on 10Hz sample rate with a 17% grey target at 50mm. There a is low power features design tip available on
that has measured average current consumption data using different low power features of the VL6180X. In addition, section 2.11.2 of the latest datasheet (rev 6) has a detailed current consumption calculator.Hope this helps,
Ken
2015-02-27 06:37 AM
Thank you Ken,
Everything is OK now. I can set an intermeasurement period between 10ms and 2.5s as well as to use GPIO1 signal to wake-up the uP when measurend range is < or > of some defined threshold. Thanks for your help. Sincerely, Bojan.2015-08-04 11:00 PM
I have also great trouble generating an interrupt on GPIO1 after a new sample is ready. It works in the one shot mode. Below is my code. What am I doing wrong? I'm first calling 'set_range_it' and then 'start_cont_range' from the main program. I'm expecting a range measurement every 100ms but there is nothing.
There is nothing wrong with the hardware or the interrupt handler. If I pull the pin high manually the MCU detects the interrupt and executes the correct code. def set_range_it(self): while (self.i2c1.mem_read(1, self.addr, 0x004D, addr_size=16)[0] & 0x01) != 0x01: pyb.delay(1) self.i2c1.mem_write(0x09, self.addr, 0x001B, addr_size=16) self.i2c1.mem_write(0x01, self.addr, 0x0017, addr_size=16) self.i2c1.mem_write(0x30, self.addr, 0x0011, addr_size=16) self.i2c1.mem_write(0x04, self.addr, 0x0014, addr_size=16) self.i2c1.mem_write(0x00, self.addr, 0x0017, addr_size=16) self.i2c1.mem_write(0x07, self.addr, 0x0015, addr_size=16) def start_cont_range(self): while (self.i2c1.mem_read(1, self.addr, 0x004D, addr_size=16)[0] & 0x01) != 0x01: pyb.delay(1) self.i2c1.mem_write(0x03, self.addr, 0x0018, addr_size=16)