Since the Vin pin is not powered from the LiPo you can use that pin as a RISING edge wake pin.
This would be the answer to your topic title, but whan you say ...
... this will only tell whether 5V is coming from USB, it doesn't tell anything about whether or not the LiPo gets charged or not (e.g. when fullly charged already).
Connect VIN to WKP pin with a 2.2k resistor in-between. Add a 3.3k resistor to ground on the WKP pin. Make sure pull-up/pull-down resistors for the WKP pin are disabled / don’t enable them in firmware.
This converts 5V to ~3.3V using a resistive voltage divider network. When VIN goes from 0V to 5V because of 5V via the usb, this creates a transition from 0V to ~3.3V on the WKP pin which the processor will listen to to wake it up from sleep.
You could then measure voltage by using WKP as an ADC pin (A7) periodically to determine when to go back to sleep.
Test it to make sure those values work for you. Keep in mind tolerances to make sure the range of voltage outputs meets your requirements.
Sure, extra precautions are nothing to appologise for but if you are after a minimal approach with pragmatic risk assessment the voltage dividers are not a must have.
Some background
This is difficult to achieve since System.sleep() will apply the respective pull-resistors depending on the trigger edge. So if you don't want an internal pull to be applied you'd need to trigger for CHANGE.
Deep sleep always has uses the internal pull-down.
A related comment/proposal exists in a pending firmware issue https://github.com/particle-iot/device-os/issues/1149#issuecomment-257079898
However, as long you are not using A3 or A6 (aka DAC) as wake pin, you don't need a voltage divider as all pins (apart from the two) on the Photon/Electron are 5V tolerant (for a short time even with attached internal resistors).
If the internal pull-resistors are only attached for the sleep periode and after applying 5V the device immediately wakes and reverts to pinMode(pin, INPUT) - either by having had it assigned before Stop Mode sleep or by default after deep sleep - you should be good.
When opting against the voltage divider make sure you don'tanalogRead() that pin but rather use digitalRead() which will again accept 5V and rid you of the need for a voltage divider.
Sure
// either
System.sleep(SLEEP_MODE_DEEP, 3600); // deep sleep for 1h or till RISING edge detected on WKP
// or
System.sleep(D1, RISING, 3600); // Stop mode sleep for 1h or till D1 goes HIGH
// for that version make sure you either don't set pinMode() or
// exlplicitly set it to pinMode(D1, INPUT) any time before sleeping
// or immediately after the System.sleep() call where the code will follow
// on after wake
I try to test just like this code. I don’t have installed 2.2k resistance between VIN and WKP and 3.3k from WKP to ground. Do I need to make this setup to run my code ? Actually is not working.
Note : I don’t test sleep for now, just try using attachInterrupt. When done, I’ll use the System.sleep(
You cannot use Particle.publish() from within an ISR.
Try this instead
void hello(void);
void setup() {
pinMode(D7, OUTPUT);
pinMode(A7, INPUT);
attachInterrupt(A7, hello, RISING);
}
void hello()
{
static uint32_t ms = 0;
if (millis() - ms < 200) return; // simple 200ms debounce
ms = millis();
digitalWrite(D7, !digitalRead(D7)); // toggle D7 LED
}
For this you do need an external pull-down e.g. 10k (should be possible to go higher tho') on A7 and a connection between Vin and A7 (for safety I'd add a 470Ohm resistor to limit current in case of inadvertent OUTPUT LOW).
The external pull-down is required since this condition doesn't apply to your test setup
So with a test code like this, where you need and external pull-down anyway, the voltage divider is the better approach after all - although I'd maybe increase the values to reduce current while USB powered (e.g. 10k + 6k8).