I have connected a sensor to my Photon which generates an interrupt when something is in front of it. I think this works so far because I can digitalRead the interrupt pin.
I am getting a 1 when there is no interrupt and a 0 when the sensor generates an interrupt.
So I think it should be possible to wake the Photon up.
I did the following in Setup:
pinMode(interruptPin, INPUT_PULLUP);
I am using INPUT_PULLUP because the datasheet of the sensor says:
The interrupt pin is an open drain output. The needed pull-up resistor may be connected to the same supply voltage as the application
controller and the pull-up resistors at SDA/SCL. Proposed value R2 should be >1 kΩ , e.g. 10 kΩ to 100 kΩ.
Proposed value for R3 and R4, e.g. 2.2 kΩ to 4.7 kΩ, depend also on the I2C bus speed.
But this does not work. I have also tried RISING and CHANGE.
When I use CHANGE my Photon wakes up immediatly after going to sleep forever.
Firmware Version: 0.6.0 RC2
I have really no idea why this does not work and I would be very grateful if you could help me
Might be useful to post all the code. Taking your code at face value; with System.sleep() in loop() it seems to me that the photon will wake when the pin value alters, but then will immediately go back to sleep again?
Thank you very much for your answer! I have taken care of the problem that it maybe immediately go back to sleep but it did not change anything so far.
Here is my code:
#include "VCNL40x0.h"
VCNL40x0 vcnl;
const byte interruptPin = D4;
volatile byte state = LOW;
unsigned int nextTime = 0;
unsigned int i=0;
uint8_t ID=0;
uint8_t Command=0;
uint8_t Current=0;
unsigned int ProxiValue=0;
unsigned long SummeProxiValue=0;
unsigned int AverageProxiValue=0;
unsigned int AmbiValue=0;
uint8_t InterruptStatus=0;
uint8_t InterruptControl=0;
void setup() {
Serial.begin(9600);
Serial.println("VCNL40x0 test");
pinMode(interruptPin, INPUT_PULLUP);
//attachInterrupt(interruptPin, VCNL40x0Isr, CHANGE);
if (! vcnl.begin()){
Serial.println("Sensor not found :(");
while (1);
}
Serial.println("Found VCNL4010");
Serial.println(vcnl.readID()); // Read VCNL40x0 product ID revision register
vcnl.writeCurrent(20); // Set current to 20mA
Serial.println(vcnl.readCurrent()); // Read back IR LED current
// stop all activities (necessary for changing proximity rate, see datasheet)
vcnl.setCommandRegister (COMMAND_ALL_DISABLE);
// set proximity rate to 2/s
vcnl.setProximityRate (PROX_MEASUREMENT_RATE_2);
// enable prox and ambi in selftimed mode
vcnl.setCommandRegister (COMMAND_PROX_ENABLE |
COMMAND_AMBI_ENABLE |
COMMAND_SELFTIMED_MODE_ENABLE);
// set interrupt control for threshold
vcnl.setInterruptControl (INTERRUPT_THRES_SEL_PROX |
INTERRUPT_THRES_ENABLE |
INTERRUPT_COUNT_EXCEED_2);
// set ambient light measurement parameter
vcnl.setAmbiConfiguration (AMBI_PARA_AVERAGE_32 |
AMBI_PARA_AUTO_OFFSET_ENABLE |
AMBI_PARA_MEAS_RATE_2);
// measure average of prox value
SummeProxiValue = 0;
for (i=0; i<30; i++) {
/*do {
vcnl.readCommandRegister(); // read command register
} while (!COMMAND_MASK_PROX_DATA_READY);
*/
SummeProxiValue += vcnl.readProxiValue(); // read prox value and sum of all measured prox values
}
AverageProxiValue = SummeProxiValue / 30; // calculate average
vcnl.setHighThreshold (AverageProxiValue + 1000); // set upper threshold for interrupt
Serial.print("Upper Threshold Value: ");
Serial.println(AverageProxiValue + 1000);
Particle.publish("AverageProxy",String(AverageProxiValue));
}
void loop() {
Serial.print("Ambient: "); Serial.println(vcnl.readAmbiValue());
Serial.print("Proximity: "); Serial.println(vcnl.readProxiValue());
Serial.print("State: ");
Serial.println(digitalRead(interruptPin));
if (nextTime > millis()) {
return;
}
nextTime = millis() + 30000;
System.sleep(interruptPin, FALLING, 500);
}
When I uncomment System.sleep I receive the following output in the serial monitor:
Nothing in front of the sensor:
I am not sure I understand your output, what would you expect the output to look like if it was working as you expect?
Did you notice this in the data sheet which seems to suggest you need to clear interrupt status bits after the sensor sends an interrupt:
Once an interrupt is generated the corresponding status bit goes to 1 and stays there unless it is cleared by writing a 1 in the corresponding bit. The int pad will be pulled down while at least one of the status bit is 1.
The data sheet (page 5) refers to an app note which on page 17 also seems to suggest clearing interrupt status flags may be required?
@chrisb2, the system firmware handles resetting the interrupt bit. As for the pull-up, I highly recommend using an external pull-up which is guaranteed to work even during sleep. At what rate is the interrupt firing?
I would expect that when I power my Photon it goes to sleep. After 500 seconds, or when I move my hand in front of the sensor it also wakes up. Then it stays online for 30 seconds and goes to sleep again. It is a work in progress, the next step would be to measure the time between a HIGH threshold and a LOW threshold.
I did not see the notice to clear the interrupt status bits. But shouldn’t it work at least once? For a second time it would be necessary to clear the status bits.
I assume that it is working. Because “State” is the state of the interrupt pin. And it switches between HIGH and LOW when I use INTERRUPT_COUNT_EXCEED_2.
@peekay123 I am now using an external pull-up with 10kOhm and changed INPUT_PULLUP to INPUT. I put it between Vin and Int of the sensor. Interrupts will fire only a few times a day.
I really would like to make the library public but I am unsure which license I have to use. Because it is a mix between the Adafruit library here (BSD license) and the mbed library here (Apache license).
I was not successful in porting only the mbed library.
One other ‘crazy’ thought is that you have declared the interruptPin variable as a byte, the argument to Sytem.sleep() is shown as a uint16_t in the docs, same for attachInterrupt(). Examples in the docs show pin variables declared with int data type. I do not see why byte should cause a problem, but maybe something weird is going on.
yes this works, I can see it in the serial monitor. I have uncommented that line and put this at the end of my code and made some small modifications of my loop:
void VCNL40x0Isr(){
Serial.println("H");
}
I have also changed the pin declaration to int but it did not change anything. I really do not understand why my Photon does not wake up.
@hl68fx, one thing you could try is to disconnect the interrupt line from the VCNL40 board and connect D4 to a wire that you can manually ground. Wait for your photon to go to sleep and try waking it by grounding D4. Let me know what happens.
@peekay123 I am using a mix between this and this library from Adafruit. The Adafruit library does not support interrupts. After some research I have found the library from mbed. I did not get it to compile so I have “ported” the missing parts to the Adafruit library.
The problem is I do not know how to publish my library because both libraries use different licenses (Adafruit -> BSD license, mbed -> Apache license).