๐ฌ MyMultisensors
-
@alexsh1 i'm very glad to hear that :+1: I'll try to upload an example for PIR pinchange with my helper lib for blindtime etc asap
@scalz I know you are currently developing a similar board on SAMD. Do you have any problems with atmega328p memory? Unfortunately, with signing and a few sensors, I'm running out of memory. On your node, I can have PIR, light, temp/hum and reed. I may struggle to combine all of them under 32kb with signing. Given that I have dualoptiboot (1.5k less) for OTA, it does not help either.
I can see your PIR setup is complex. What is it you are trying to achieve?
-
@alexsh1 my next board won't be for SAMD.
I need to check my code and what's the compil results, i don't remember exactly. but that was tight, 90% perhaps, i usually don't want to go above..
What do you mean by PIR setup is complex? -
@alexsh1 my next board won't be for SAMD.
I need to check my code and what's the compil results, i don't remember exactly. but that was tight, 90% perhaps, i usually don't want to go above..
What do you mean by PIR setup is complex? -
@alexsh1 this is a lib for helping to use PIR, could be integrated in nodemanager though, but i generally prefer to keep hands on my code, also because C code is usually more memory optimized.
So this is for handling PIR like some controllers ic do, and pinchange, with weak functions for users functions etc.
How looks my flow:/* ******************************************************************************************************************* * PIR Sensor State Machine * * Flow : sensitivity of pir sensor for noisy environment, limits tx, power saving.. * 1) NODE_SETUP : settle for PIR_SETTLE_TIME. Then 2) * 2) PIR_START : Wait/sleep for the first pulse. Then 3) * 3) PIR_SCAN : If One trigger, wait/sleep for PIR_DEFAULT_PULSES during the PIR_DEFAULT_WINDOWTIME. * If so, the motion is validated. Then 4) * Else 2) * 4) PIR_CANCEL : PIR is disabled for PIR_DEFAULT_CANCELTIME. After, this period it reports new changed state * If LOW, then 5) * Else 4) * 5) PIR_IS_BLIND: Keep PIR sensor insensitive for PIR_DEFAULT_BLINDTIME before 2) * * ******************************************************************************************************************** */ -
@alexsh1 this is a lib for helping to use PIR, could be integrated in nodemanager though, but i generally prefer to keep hands on my code, also because C code is usually more memory optimized.
So this is for handling PIR like some controllers ic do, and pinchange, with weak functions for users functions etc.
How looks my flow:/* ******************************************************************************************************************* * PIR Sensor State Machine * * Flow : sensitivity of pir sensor for noisy environment, limits tx, power saving.. * 1) NODE_SETUP : settle for PIR_SETTLE_TIME. Then 2) * 2) PIR_START : Wait/sleep for the first pulse. Then 3) * 3) PIR_SCAN : If One trigger, wait/sleep for PIR_DEFAULT_PULSES during the PIR_DEFAULT_WINDOWTIME. * If so, the motion is validated. Then 4) * Else 2) * 4) PIR_CANCEL : PIR is disabled for PIR_DEFAULT_CANCELTIME. After, this period it reports new changed state * If LOW, then 5) * Else 4) * 5) PIR_IS_BLIND: Keep PIR sensor insensitive for PIR_DEFAULT_BLINDTIME before 2) * * ******************************************************************************************************************** */@scalz this is exactly what I do not understand. For me PIR is very simple - 1 or 0, HIGH or LOW. Why treating it differently? Maybe this is very Noobs, but this is how I treat my PIRs. I may introduce 10-30 secs delay for it to settle or 30sec sleep after it has been triggered (I do not want to have extra PIR messages to my GW and controller)
-
@alexsh1
sure PIR state is 0 or 1. I'm not changing anything to this. But you can fine tune this.Do you mean you'll update each time there is a CHANGE ?? No intermediate state ??
If so, you'll waste a lot of power in useless radio TX, mcu processing, depending on days and traffic. and your batteries won't last for long!When there are people for an hour in same room, do you update each time it triggers? That can be a lot of waste!
Also why not allowing a blindtime before redecting?
In days with lot of traffic at home for example. If you already know (or the controllers could adjust this dynamically too by custom commands) that a room will be busy. It's useless and will consumes power again, to send 0 if it will retrigger in just a few seconds.So i've done sort of helper for creating intermediate states with timeouts and counters, with user defines etc.
-
@alexsh1
sure PIR state is 0 or 1. I'm not changing anything to this. But you can fine tune this.Do you mean you'll update each time there is a CHANGE ?? No intermediate state ??
If so, you'll waste a lot of power in useless radio TX, mcu processing, depending on days and traffic. and your batteries won't last for long!When there are people for an hour in same room, do you update each time it triggers? That can be a lot of waste!
Also why not allowing a blindtime before redecting?
In days with lot of traffic at home for example. If you already know (or the controllers could adjust this dynamically too by custom commands) that a room will be busy. It's useless and will consumes power again, to send 0 if it will retrigger in just a few seconds.So i've done sort of helper for creating intermediate states with timeouts and counters, with user defines etc.
I would only update each time there is a first HIGH. Then the node goes to unconditional sleep for 30-60 sec - there is no need to send HIGH again or LOW. After 1 min the status in Domoticz for the PIR is cleared (LOW) and the PIR is ready to send another "HIGH" if triggered.
Can Domoticz really adjust PIRs dynamically?
There is blockly stript, which helps to process "HIGH" from a PIR, but I'm not aware how this can done dynamically.Clearly, you approached this as a programmer. I have a much more simplified approach. Maybe because I'm noobs when it comes to PIRs
@scalz said in ๐ฌ MyMultisensors:
@alexsh1
sure PIR state is 0 or 1. I'm not changing anything to this. But you can fine tune this.Do you mean you'll update each time there is a CHANGE ?? No intermediate state ??
If so, you'll waste a lot of power in useless radio TX, mcu processing, depending on days and traffic. and your batteries won't last for long!When there are people for an hour in same room, do you update each time it triggers? That can be a lot of waste!
Also why not allowing a blindtime before redecting?
In days with lot of traffic at home for example. If you already know (or the controllers could adjust this dynamically too by custom commands) that a room will be busy. It's useless and will consumes power again, to send 0 if it will retrigger in just a few seconds.So i've done sort of helper for creating intermediate states with timeouts and counters, with user defines etc.
-
I would only update each time there is a first HIGH. Then the node goes to unconditional sleep for 30-60 sec - there is no need to send HIGH again or LOW. After 1 min the status in Domoticz for the PIR is cleared (LOW) and the PIR is ready to send another "HIGH" if triggered.
Can Domoticz really adjust PIRs dynamically?
There is blockly stript, which helps to process "HIGH" from a PIR, but I'm not aware how this can done dynamically.Clearly, you approached this as a programmer. I have a much more simplified approach. Maybe because I'm noobs when it comes to PIRs
@scalz said in ๐ฌ MyMultisensors:
@alexsh1
sure PIR state is 0 or 1. I'm not changing anything to this. But you can fine tune this.Do you mean you'll update each time there is a CHANGE ?? No intermediate state ??
If so, you'll waste a lot of power in useless radio TX, mcu processing, depending on days and traffic. and your batteries won't last for long!When there are people for an hour in same room, do you update each time it triggers? That can be a lot of waste!
Also why not allowing a blindtime before redecting?
In days with lot of traffic at home for example. If you already know (or the controllers could adjust this dynamically too by custom commands) that a room will be busy. It's useless and will consumes power again, to send 0 if it will retrigger in just a few seconds.So i've done sort of helper for creating intermediate states with timeouts and counters, with user defines etc.
@alexsh1
My domoticz installation does not resets Pirs after a minute or whenever. Are you using the PIR lua scripts or any other?
By default it doesn't do such thing. -
@alexsh1 i have this option too (ctrl clearing pir state) i thought it could depend on the controller used, so i've tried to make something independant. And i like adding features like setting triggers max for a motion etc. But i agree, your way works too ;)
-
@alexsh1
My domoticz installation does not resets Pirs after a minute or whenever. Are you using the PIR lua scripts or any other?
By default it doesn't do such thing.@Sergio-Rius either you have to use lua or there is a much simpler way to do it in Domoticz. Change type to "motion sensor" and then you have an option "off delay". Setup it to 60 seconds and PIR sensor will be off in 60 seconds. Very useful option and yes it is not enabled by default.

-
@alexsh1 i have this option too (ctrl clearing pir state) i thought it could depend on the controller used, so i've tried to make something independant. And i like adding features like setting triggers max for a motion etc. But i agree, your way works too ;)
-
@alexsh1 i just said i have same option as you in my controller :) My controller is jeedom (french ctrlr)
I've not done it yet (missing time), but i would use some script and scenario if i would like to dynamically adjust this vs some parameters. -
@alexsh1 I'm using pinchange interrupts. It is not supported in Mysensors out of box regarding sleep, if i remember, i made some change to my functions, but the lib has changed a bit. that would need i check the code and i have no time for the moment, and don't want to release something not up to date. will take a look later, don't know when yet.
But if that can help, below is some parts of code, for enabling your irqs, and the interrupts routine. I think if you're using sleep from MySensors, it will return -1 if triggered by the pinchange, that's all. you'll just need to handle that in your sketch.
ISR (PCINT1_vect) { if (digitalRead(AMBIANT_LIGHT_PIN)) irqLight = false; else irqLight = true; } ISR (PCINT2_vect) { if((PIND & (1 << PIND6)) == 0x40 ) { myPirSensor.pirhCount++; myPirSensor.irqPir = true; } if((PIND & (1 << PIND7)) == 0x80 ) { myPirSensor.pirlCount++; myPirSensor.irqPir = true; } } /* ====================================================================== Function: pirIntEnable Purpose : Enable pin change for PIR interrupt Input : - Output : - Comments: ====================================================================== */ void pirIntEnable() { // Enable pin change for D6, D7 PCMSK2 |= bit (PCINT22); PCMSK2 |= bit (PCINT23); PCIFR |= bit (PCIF2); // clear any outstanding interrupts PCICR |= bit (PCIE2); // enable pin change interrupts for D0 to D7 } /* ====================================================================== Function: pirIntDisable Purpose : Disable pin change for PIR interrupt Input : - Output : - Comments: ====================================================================== */ void pirIntDisable() { // Disable pin change for D6, D7 PCICR ^= bit (PCIE2); // disable pin change interrupts for D0 to D7 } /* ====================================================================== Function: lightIntEnable Purpose : Enable pin change for OPT3001 interrupt Input : - Output : - Comments: ====================================================================== */ void lightIntDisable() { PCMSK1 |= bit (PCINT9); PCIFR |= bit (PCIF1); // clear any outstanding interrupts PCICR |= bit (PCIE1); // enable pin change interrupts for A0 to A5 } /* ====================================================================== Function: Light_IntDisable Purpose : Disable pin change for OPT3001 interrupt Input : - Output : - Comments: ====================================================================== */ void lightIntDisable() { PCICR ^= bit (PCIE1); // disable pin change interrupts } -
@alexsh1 I'm using pinchange interrupts. It is not supported in Mysensors out of box regarding sleep, if i remember, i made some change to my functions, but the lib has changed a bit. that would need i check the code and i have no time for the moment, and don't want to release something not up to date. will take a look later, don't know when yet.
But if that can help, below is some parts of code, for enabling your irqs, and the interrupts routine. I think if you're using sleep from MySensors, it will return -1 if triggered by the pinchange, that's all. you'll just need to handle that in your sketch.
ISR (PCINT1_vect) { if (digitalRead(AMBIANT_LIGHT_PIN)) irqLight = false; else irqLight = true; } ISR (PCINT2_vect) { if((PIND & (1 << PIND6)) == 0x40 ) { myPirSensor.pirhCount++; myPirSensor.irqPir = true; } if((PIND & (1 << PIND7)) == 0x80 ) { myPirSensor.pirlCount++; myPirSensor.irqPir = true; } } /* ====================================================================== Function: pirIntEnable Purpose : Enable pin change for PIR interrupt Input : - Output : - Comments: ====================================================================== */ void pirIntEnable() { // Enable pin change for D6, D7 PCMSK2 |= bit (PCINT22); PCMSK2 |= bit (PCINT23); PCIFR |= bit (PCIF2); // clear any outstanding interrupts PCICR |= bit (PCIE2); // enable pin change interrupts for D0 to D7 } /* ====================================================================== Function: pirIntDisable Purpose : Disable pin change for PIR interrupt Input : - Output : - Comments: ====================================================================== */ void pirIntDisable() { // Disable pin change for D6, D7 PCICR ^= bit (PCIE2); // disable pin change interrupts for D0 to D7 } /* ====================================================================== Function: lightIntEnable Purpose : Enable pin change for OPT3001 interrupt Input : - Output : - Comments: ====================================================================== */ void lightIntDisable() { PCMSK1 |= bit (PCINT9); PCIFR |= bit (PCIF1); // clear any outstanding interrupts PCICR |= bit (PCIE1); // enable pin change interrupts for A0 to A5 } /* ====================================================================== Function: Light_IntDisable Purpose : Disable pin change for OPT3001 interrupt Input : - Output : - Comments: ====================================================================== */ void lightIntDisable() { PCICR ^= bit (PCIE1); // disable pin change interrupts } -
@alexsh1
beautiful !
about pin change interrupt, that would be too bad, to be restricted to D2, D3 only :)
there are multiple howtos which show how to use them. mcu datasheet section is also interesting. not that hard, don't worry.
you'll need to clean the code above a bit to fit your sketch (variables etc). the counters on pinh and pinl were for tests, you can factorize a bit pir isr and use only one volatile variable for your trigger etc.Have fun
-
Here's my first 5 multi-sensors assembled and they've passed simple hardware tests. Although I think I have 2 that have PIRs that won't settle down. Thanks for the design scalz!

Now to write some firmware for them... Any hints?

