AttachInterrupt and receiving messages problem
-
I'm working on a Sketch in which I want to monitor a PIR sensor and be able to control a relais from Domoticz. This combination will replace my PIR controlled front door light. But I'm having a hard time coding the sketch.
I'm using an Arduino Nano for the development. And this is the Sketch
#include <SPI.h> #define SENSOR_ACTIVE_LIGHT 15 // the pin for indicating that the sensor is active. #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define RELAIS_ACTIVE_PIN 14 // The pin for the led indicator for indicating whether the relais is on. #define INTERRUPT DIGITAL_INPUT_SENSOR-2 // Usually the interrupt = pin -2 (on uno/nano anyway) #define CHILD_ID_MOTIONSENSOR 1 // Id of the sensor child #define CHILD_ID_RELAY 2 // Id of the relais switch // Declare variables unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds) MySensor gw; boolean lasTrippedValue = false; // Initialize motion message MyMessage msgMotionSensor( CHILD_ID_MOTIONSENSOR, V_TRIPPED ); // Change to V_LIGHT if you use S_LIGHT in presentation below MyMessage msgRelaisActuator( CHILD_ID_RELAY, V_LIGHT ); void setup() { Serial.begin(115200); gw.begin(incomingMessage); // Send the sketch version information to the gateway and Controller gw.sendSketchInfo("Motion Sensor", "1.0"); pinMode( DIGITAL_INPUT_SENSOR, INPUT ); // sets the motion sensor digital pin as input pinMode( SENSOR_ACTIVE_LIGHT, OUTPUT ); // visual indicator for motion detection pinMode (RELAIS_ACTIVE_PIN, OUTPUT ); attachInterrupt(digitalPinToInterrupt( DIGITAL_INPUT_SENSOR ), pirSensorValueChanged, CHANGE); // attach interrupt handler to the PIR motion sensor. // Register all sensors to gw (they will be created as child devices) gw.present(CHILD_ID_MOTIONSENSOR, S_MOTION); gw.present(CHILD_ID_RELAY, S_LIGHT); digitalWrite( SENSOR_ACTIVE_LIGHT, LOW ); } void loop() { // space for Hummidity and Temp reading gw.wait(50); } void incomingMessage(const MyMessage &message) { Serial.println("message"); // We only expect one type of message from controller. But we better check anyway. if (message.type==V_LIGHT) { if ( message.sensor == CHILD_ID_RELAY ) { digitalWrite( RELAIS_ACTIVE_PIN, message.getBool()? HIGH :LOW ); } } } void pirSensorValueChanged() { boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; digitalWrite( SENSOR_ACTIVE_LIGHT, tripped? HIGH :LOW ); gw.send(msgMotionSensor.set(tripped?"1":"0")); // Send tripped value to gw }
I'm trying to attach an interrupt handler to the PIR motion sensor, so that I keep my main loop clean. If possible I want to attach a DHT11 sensor, so that I can measure the temperature and humidity of the little work shop in which the Arduino will be mounted. Be keeping my loop clean, I can put the code for temp measurement there, without having to schedule the measurements.
The problem is that the Sketch causes the Arduino to crash. I have manage to find out where abouts it happens. It happens when my Arduino receives a message from the GateWay. After a couple of runs from the loop. I see the the following text in the serial monitor:
meWhich should be "message"- which is in the incomingMessage method - and my arduino stalls. It doesn't do anything. What am I doing wrong?
Updated: attached a new version of the Sketch. In the last one, the attaching of the interrupt handler was commented out. That was for my own test purpose to see if the interrupt handler caused the problem and it did.
-
Update:
It looks like the interrupt handler is interfering with the MySensors core. Before the sketch stalls, I see that the communication is getting lost. I get failures. Then the sensors tries to connect to the parent again, in the following example it succeeds with that, but just a little bit later the sketch stalls.
-
@TheoL I'm also having this problem using TimerOne.
My code is simply
Timer1.initialize(freqStep); // Initialize TimerOne library for the freq we need 75uS
Timer1.attachInterrupt(dim_check);This code is part of a 2xSSR and 2x Triac Dimmer project.
The SSR's work fine being controlled by Veralite so long as the attachInterrupt is commented out. as soon as the line is included, Vera cannot control the SSR's.I wonder if Mysensors might have something to do with the problem. Hope Hek sees this post and can reply
-
Maybe this could be a comcurrency problem. The code inside the interrupt-routines should be very short (calc some values und flag variables). The main code is then in the loop.
Try to avoid calling mysensor code (e.g. gw.send) in the interrupt routine and keep it as short as possible.
-
@FotoFieber it might be. I have taken a different road with the code and completely skipped using interrupts. But it might be worth trying. Even thought the sending of a message doesn't take a lot of time on the node part. And I wasn't using the ACK mechanism.
I know I tested the interrupt handler with a single Serial.println() statement which still caused the Sketch to stop. But what might help is using interrupts() and noInterrupts() in the interruptHandler. I just typed the following code directly in this post so it might give compile errors, but I think you'll get the idea.
void pirSensorValueChanged() { noInterrupts(); boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; digitalWrite( SENSOR_ACTIVE_LIGHT, tripped? HIGH :LOW ); gw.send(msgMotionSensor.set(tripped?"1":"0")); // Send tripped value to gw interrupts(); }
-
As @FotoFieber says, keep interrupt handler to a absolute minimum. Like updating a status flag.
You cannot call mysensors functions like send in there.
-
Hello again
I've attached a version which show/demonstrates the problem I have when using Timer1.attachInterrupt(dim_check, freqStep);. I'm using a Veralite and simple pro mini arduino to controll 2x SSR and 2x Triac dimmers. I use a structured array to hole the various valus for the lamps.
When I upload a version of this attached code with Timer1.attachInterrupt(dim_check, freqStep);commented out - the SSR's work fine.
When I uncomment the one line in the code the is no response to the Vera's command to switch on a SSR lamp.
As you can see the interrupt routine is extremely short - nothing but the call.
I wonder if someone else might have any idea or have run into this problem before.. The interrupt is to occur every 75uS so as to allow 128 steps of dimming.Timer1Testing.ino