Yes, the pin change intgerrupt gives me what I want. The sleep call also wakes up on this interrupt, I thought it would only wake up in INT0 or INT1.
So for now my experiments with FreeRTOS end.
@electrik thanks for the hint!
Yes, the pin change intgerrupt gives me what I want. The sleep call also wakes up on this interrupt, I thought it would only wake up in INT0 or INT1.
So for now my experiments with FreeRTOS end.
@electrik thanks for the hint!
Finally, after reading the data sheet, I see the problem with the watchdog timer: its value can not be read.
Timer2 would be a nice option. I will have a look at that. Thanks for your answers!
@mfalkvidd The development branch has the same behavior. An edit in core/MyGatewayTransportMQTTClient.cpp (I added a "delay(3000)" after line 148 in reconnectMQTT(void)) made it a lot better!
@mfalkvidd Thank you for the link. I followed the instructions, had to download/compile some packages.
It will take some time for me, I have to solve this error:
git commit -m "Accept wildcards in mqtt subscription prefix"
cppcheck: Failed to load library configuration file 'std.cfg'. File not found
cppcheck: Failed to load library configuration file 'avr'. File not found
nofile:0:0: information: Failed to load the library avr [failedToLoadCfg]
Few minutes later, resolved, had to add CFGDIR to make cppcheck:
sudo make install FILESDIR=/usr/share/cppcheck CFGDIR=/usr/share/cppcheck
I have been struggling with the MySensors sleep method. My PIR sensor is not using one of the two supported interrupts.
I have started writing some code, but that is just a beginning. Is anybody interested in this subject or should I just write it for my own use?
Any help would be welcome, it is not unlikely that I am missing something important in this mechanism.
The actual (partial) code can be found at
https://sourceforge.net/p/easypirmultisensorsbox/code/ci/cvdenzen/tree/easyPIRmultisensorsBox2_155/easyPIRmultisensorsBox2_155/
I named the new class Sleep3.
Advantages of current (december 2021) sleep implementation:
Trying to make a better sleep (class Sleep3) that improves some of the shortcomings:
Note 1:
If there is a non-processed interrupt, the cpu must not go to sleep. That happens e.g. in this scenario: the cpu is executing the loop() code and is almost at the point to call sleep(). A PIR sensor triggers an interrupt, the ISR is run, it sets a flag that is to be checked in the loop(). At that point the cpu would go to sleep. The flag would only be seen after the sleep call!
Solution: check whether sleeping is allowed, same scenario extended with the check:
the cpu is executing the loop() code and is almost at the point to call sleep(). A PIR sensor triggers an interrupt, the
ISR is run in which a flag is set to be checked in the loop(). New: at that point the cpu disables interrupts, calls the
callback methods of the observers and will be signaled by the PIR observer that it should not go to sleep(), but continue its processing. The loop is re-entered immediately and the PIR data can be sent to the gateway.
The Observer method will be called in a locked (interrupts disabled) state just before the hardware sleep is entered.
If the Observer notices that there is a pending interrupt on behalf of its subject, it should return false, otherwise
it should return true (as in: allright, go to sleep).
// The Sleep3 code that calls the observers will look like this:
boolean sleepIsAllowed=true;
noInterrupts();
for (Observer observer:observers) { if (!observer()) {sleepIsAllowed=false;break}}
if (sleepIsAllowed) {interrups();sleep;} else interrupts();
// An example application looks like this:
//
Sleep3 sleep3; // Sleep3 is the proposed sleep class
before() {
sleep3.attach(sleepObserver);
.. enable interrupts etc.
}
ISR (PCINT2_vect) {
boolean PIRPinValue = digitalRead(PIR_PIN);
queue.add(PIRPinValue);
}
// This method is entered with interrupts disabled
boolean sleepObserver() {
if (!queue.isEmpty()) return false; else return true;
}
void loop() {
noInterrups(); // to lock the queue
if (!queue.isEmpty()) {
boolean pir=queue.remove();
interrupts();
// do something with pir
} else {
interrupts();
}
sleep3.sleep(SLEEP_TIME);
}
Looks like this was solved in branch develop at Jan, 6, 2019:
98355b2d ( tekka 2019-01-06 18:14:10 +0100 158) delay(1000);
@Nigel31 Thank you, I will try to write some code and test it. It can take a few weeks as I have to do it in my spare time (like most of us).
@Nigel31 Thank you, I will try to write some code and test it. It can take a few weeks as I have to do it in my spare time (like most of us).
I have been struggling with the MySensors sleep method. My PIR sensor is not using one of the two supported interrupts.
I have started writing some code, but that is just a beginning. Is anybody interested in this subject or should I just write it for my own use?
Any help would be welcome, it is not unlikely that I am missing something important in this mechanism.
The actual (partial) code can be found at
https://sourceforge.net/p/easypirmultisensorsbox/code/ci/cvdenzen/tree/easyPIRmultisensorsBox2_155/easyPIRmultisensorsBox2_155/
I named the new class Sleep3.
Advantages of current (december 2021) sleep implementation:
Trying to make a better sleep (class Sleep3) that improves some of the shortcomings:
Note 1:
If there is a non-processed interrupt, the cpu must not go to sleep. That happens e.g. in this scenario: the cpu is executing the loop() code and is almost at the point to call sleep(). A PIR sensor triggers an interrupt, the ISR is run, it sets a flag that is to be checked in the loop(). At that point the cpu would go to sleep. The flag would only be seen after the sleep call!
Solution: check whether sleeping is allowed, same scenario extended with the check:
the cpu is executing the loop() code and is almost at the point to call sleep(). A PIR sensor triggers an interrupt, the
ISR is run in which a flag is set to be checked in the loop(). New: at that point the cpu disables interrupts, calls the
callback methods of the observers and will be signaled by the PIR observer that it should not go to sleep(), but continue its processing. The loop is re-entered immediately and the PIR data can be sent to the gateway.
The Observer method will be called in a locked (interrupts disabled) state just before the hardware sleep is entered.
If the Observer notices that there is a pending interrupt on behalf of its subject, it should return false, otherwise
it should return true (as in: allright, go to sleep).
// The Sleep3 code that calls the observers will look like this:
boolean sleepIsAllowed=true;
noInterrupts();
for (Observer observer:observers) { if (!observer()) {sleepIsAllowed=false;break}}
if (sleepIsAllowed) {interrups();sleep;} else interrupts();
// An example application looks like this:
//
Sleep3 sleep3; // Sleep3 is the proposed sleep class
before() {
sleep3.attach(sleepObserver);
.. enable interrupts etc.
}
ISR (PCINT2_vect) {
boolean PIRPinValue = digitalRead(PIR_PIN);
queue.add(PIRPinValue);
}
// This method is entered with interrupts disabled
boolean sleepObserver() {
if (!queue.isEmpty()) return false; else return true;
}
void loop() {
noInterrups(); // to lock the queue
if (!queue.isEmpty()) {
boolean pir=queue.remove();
interrupts();
// do something with pir
} else {
interrupts();
}
sleep3.sleep(SLEEP_TIME);
}
It seems like building MySensors with my edit failed but I don’t understand the error messages.
The first error: https://ci.mysensors.org/job/MySensors/job/MySensors/job/PR-1497/2/warnings2Result/new/file.702256833/source.9006459693321295180/#1
@mfalkvidd Thank you for the link. I followed the instructions, had to download/compile some packages.
It will take some time for me, I have to solve this error:
git commit -m "Accept wildcards in mqtt subscription prefix"
cppcheck: Failed to load library configuration file 'std.cfg'. File not found
cppcheck: Failed to load library configuration file 'avr'. File not found
nofile:0:0: information: Failed to load the library avr [failedToLoadCfg]
Few minutes later, resolved, had to add CFGDIR to make cppcheck:
sudo make install FILESDIR=/usr/share/cppcheck CFGDIR=/usr/share/cppcheck
I have made some modifications to the code, tested it and it seems to work.
There is a pull request https://github.com/mysensors/MySensors/pull/1497 but I don't know how this will be handled by the MySensors developers.
Can anybody give me a link or some information about the development process? A review of my code will be necessary, I am not a C programmer.
The problem is clear: the subscription topic that I use contains a wildcard: “+/mysensors”.
I send my message with prefix “carl/mysensors”.
The MySensors code assumes the length of the prefix I send is the same as the length of the subscription prefix. But it isn’t because of the wildcard character.
Is there anybody who likes to change the code to make it work? Or should I try it myself?
I see two possible solutions:
@cvdenzen
I have added a GATEWAY_DEBUG line in core/MyProtocol.cpp at line 122:
for (str = strtok_r(topic + strlen(MY_MQTT_SUBSCRIBE_TOPIC_PREFIX) + 1, "/", &p);
str && index < 5;
str = strtok_r(NULL, "/", &p), index++
) {
GATEWAY_DEBUG(PSTR("GWT:TPS:Index=%d, mqttstr=%s\n"), str);
My conclusion is that the length of the mqtt subscription topic is the problem. The first call shows that it thinks "rs" is part of the topic beyond the PREFIX. And "rs" gets translated to "0" in the outgoing mqtt message, shifting the real items one position further and dropping the last item.
Later on I will have a look at the cause of this limitation (or maybe someone else is quicker than I am).
The output of mysgw, first try is with topic carl/mysensors, second try (that succeeds) is with mqtt topic c/mysensors:
Aug 15 23:53:19 DEBUG GWT:TPS:TOPIC=mysensors/all/157/255/3/0/21,MSG SENT
Aug 15 23:53:24 DEBUG GWT:IMQ:TOPIC=carl/mysensors/157/0/1/0/3, MSG RECEIVED
Aug 15 23:53:24 DEBUG GWT:TPS:Index=0, mqttstr=rs
Aug 15 23:53:24 DEBUG GWT:TPS:Index=1, mqttstr=157
Aug 15 23:53:24 DEBUG GWT:TPS:Index=2, mqttstr=0
Aug 15 23:53:24 DEBUG GWT:TPS:Index=3, mqttstr=1
Aug 15 23:53:24 DEBUG GWT:TPS:Index=4, mqttstr=0
Aug 15 23:53:24 DEBUG GWT:TPS:TOPIC=mysensors/all/0/157/0/1/0,MSG SENT
Aug 15 23:54:42 DEBUG GWT:IMQ:TOPIC=c/mysensors/157/0/1/0/3, MSG RECEIVED
Aug 15 23:54:42 DEBUG GWT:TPS:Index=0, mqttstr=157
Aug 15 23:54:42 DEBUG GWT:TPS:Index=1, mqttstr=0
Aug 15 23:54:42 DEBUG GWT:TPS:Index=2, mqttstr=1
Aug 15 23:54:42 DEBUG GWT:TPS:Index=3, mqttstr=0
Aug 15 23:54:42 DEBUG GWT:TPS:Index=4, mqttstr=3
Aug 15 23:54:42 DEBUG TSF:MSG:SEND,0-0-157-157,s=0,c=1,t=3,pt=0,l=2,sg=0,ft=0,st=OK:35
Aug 15 23:54:42 DEBUG TSF:MSG:READ,157-157-0,s=0,c=1,t=2,pt=1,l=1,sg=0:1
Aug 15 23:54:42 DEBUG GWT:TPS:TOPIC=mysensors/all/157/0/1/0/2,MSG SENT
@evb It took some time (have also another home renovation project), but now I have set up a test gateway.
The mqtt topic with a slash in its name seems to be the problem. I changed the mqtt topic to mysensorsa and now the sketch receives the message. The mqtt gateway outputs:
Aug 15 22:50:33 DEBUG GWT:IMQ:TOPIC=mysensorsa/157/0/1/0/3, MSG RECEIVED
Aug 15 22:50:33 DEBUG TSF:MSG:SEND,0-0-157-157,s=0,c=1,t=3,pt=0,l=2,sg=0,ft=0,st=OK:35
Aug 15 22:50:34 DEBUG TSF:MSG:READ,157-157-0,s=0,c=1,t=2,pt=1,l=1,sg=0:1
Aug 15 22:50:34 DEBUG GWT:TPS:TOPIC=mysensors/all/157/0/1/0/2,MSG SENT
Aug 15 22:50:34 DEBUG TSF:MSG:READ,157-157-0,s=0,c=1,t=3,pt=2,l=2,sg=0:35
Aug 15 22:50:34 DEBUG GWT:TPS:TOPIC=mysensors/all/157/0/1/0/3,MSG SENT
I will have a look at the MySensors code and if I cannot find the problem, maybe I will change my mqtt subscription topic.
Is the mysgw output looking good? The sent message doesn”t include the message type (3). Has anybody tested this with a topic that contains a slash?