Not a programmer just been reading for a few weeks.
I wrote the following code which works but is clearly less than succinct.
I'm using it to to turn on my oled only when necessary .
I read up on (int i=0;i<=300;i++)
and tried that implementation but it didn't go very well.
Please let me know if this currently working code has any pitfalls
and how to shorten/rewrite it if necessary.
thanks.
good one, like what you did there. The rest of the code unfortunately isn't mine to post but isn't directly related to the code I posted. I wrote this as a standalone sketch which works without any additional code. I just added the "bool send" which may be completely unnecessary and is found nowhere else in the code. Why did I add it? who knows. I think i was in my hundreth iteration and that setup finally worked. The sensor read is equal to any input event like a pushbutton sink to ground.
So:
And here is the entire scratch. I call func 20 times a second so timing is counting those. If you call it flat out, you have to count with a long variable, so countUp will always be unsigned long.
I realized at the same time and place where so many questions get answered that it is really just a slow motion debouncing applied only to the falling edge.
Here's a sketch that illustrates hysteresis-style debouncing repurposed as a slow on, slow off switch:
// https://forum.arduino.cc/t/how-to-shorten-this-code/1035307
// symmetric delayed on / off
# define pin7 8
void setup()
{
Serial.begin(115200);
Serial.println("\nhello world.\n");
pinMode(pin7, INPUT_PULLUP);
}
unsigned long lineCounter;
void loop()
{
static unsigned long lastLook;
unsigned long now = millis();
if (now - lastLook < 50)
return;
lastLook = now;
func();
}
# define COMMON_DELAY 15 // 50 ms
unsigned long countUp;
unsigned char send;
void func()
{
unsigned char button = (LOW == digitalRead (pin7));
if (button == send) countUp = 0;
else if (++countUp > COMMON_DELAY) {
send = !send;
Serial.print(lineCounter); lineCounter++;
Serial.println(send ? " ON" : " OFF");
countUp = 0;
}
}
If the button is different, reset the counter. As long as button is the same, count until you pass the COMMON_DELAY count.
All the algorithms or snippets work (or are meant to work…) by counting how many times they have been called, therefor timing is dependent on… wait for it… how often you call them.
If you have a convenient periodic process like many loop()s might implement, hang it on that.
Otherwise the counting mechanism could be switched to the more often seen use of millis() to measure time that a button has been "stable", in the debouncing analogy.
If you call the function as fast as possible, you have to count quite high, and timing will always depend on what else you got going on, that is to say how fast is "as fast as possible"?
Of course it can be made to work in both directions. My versions do, and so does your new idea, if it works.
The code in #9, besides not working, did not appear to address any concept of stability in the turning on of the display by the sensor.
Fixed, it was instant on, counted down to delayed really off.
The apparent desired behaviour of @pro_grammar's original seemed also to be instant on, delayed off.
Which is why I thought everyone was going for instant on / delayed off.
For all I know, the OP was aiming for both delayed on and delayed off. Who cares but s/he? Something to specify.
The edges can be handled by the same code, I mean literally the same lines of code. That gives rise to the symmetrical version above and in the simulation.
The delay period constant could, in that version, be selected by the state of send, to go on faster than it turns off. Or whatever.
The sensor triggering oled "on" is a basic IR proximity sensor. I was going for
screen instantly on when triggered, remaining "on" for about 4 seconds then
immediately off. Though delayed off is also fine,
Remain on until 4 seconds after the last activity. Activity resets the timing period.
Instantly I want to start the camera rollin
but Imma leave it on for a while after I think the action has stopped, just in case it hasn't. I'd just as soon have kept rolling .
If nothing has happened for a while, OK then stop it.
Or a constant action scene would be needlessly slivered into 4 second "takes". You have to refresh the idea of tuning off any time soon. When there is action.