Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. using interrupt - cant back to void loop

using interrupt - cant back to void loop

Scheduled Pinned Locked Moved Development
7 Posts 3 Posters 1.4k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    afick
    wrote on last edited by
    #1

    Hello,

    I'm checking some sensors in some time period:

    void loop()     
    {   
        
    
    unsigned long currentMillis_gas = millis();
    unsigned long currentMillis_temp = millis();
      
    if (currentMillis_temp - previousMillis_temp >= interval) {
    check_temp();
    check_gas();
    check_light();
    previousMillis_temp = currentMillis_temp;
    }
    }
    

    All working fine.

    But i have also PIR sensor.

    To catch PIR status I'm using interrupt

    attachInterrupt(digitalPinToInterrupt(2), check_pir, CHANGE);
    

    All works fine - except one think.
    When I call function check_pir() using interrupt, program is not able to back (after finishing function check_pir()) to running void loop.

    Its like program jump to check_pir() and stay there for ever....

    Any idea what im doing wrong ?

    mfalkviddM YveauxY 2 Replies Last reply
    0
    • A afick

      Hello,

      I'm checking some sensors in some time period:

      void loop()     
      {   
          
      
      unsigned long currentMillis_gas = millis();
      unsigned long currentMillis_temp = millis();
        
      if (currentMillis_temp - previousMillis_temp >= interval) {
      check_temp();
      check_gas();
      check_light();
      previousMillis_temp = currentMillis_temp;
      }
      }
      

      All working fine.

      But i have also PIR sensor.

      To catch PIR status I'm using interrupt

      attachInterrupt(digitalPinToInterrupt(2), check_pir, CHANGE);
      

      All works fine - except one think.
      When I call function check_pir() using interrupt, program is not able to back (after finishing function check_pir()) to running void loop.

      Its like program jump to check_pir() and stay there for ever....

      Any idea what im doing wrong ?

      mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #2

      @afick would you mond posting the code for the check_pir function? That would help a lot when trying to figure out why it is wrong.

      Also, please use thr auto-format function (ctrl/cmd+T) in the Arduino IDE. That will make the code much easier to read, for yourself and everyone else.

      1 Reply Last reply
      1
      • A Offline
        A Offline
        afick
        wrote on last edited by
        #3

        check_pir is standard function created from mysensors example (motion)

        void check_pir()
        {
         Serial.println("check  PIR");
            // Read digital motion value
          boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
                
          Serial.println(tripped);
          send(msg.set(tripped?"1":"0"));  // Send tripped value to gw 
           
        }```
        mfalkviddM 1 Reply Last reply
        0
        • A afick

          check_pir is standard function created from mysensors example (motion)

          void check_pir()
          {
           Serial.println("check  PIR");
              // Read digital motion value
            boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; 
                  
            Serial.println(tripped);
            send(msg.set(tripped?"1":"0"));  // Send tripped value to gw 
             
          }```
          mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by mfalkvidd
          #4

          @afick that code is supposed to be in the loop. It is not supposed to be an interrupt handler. Interrupt handlers can not interact with Serial and they can not call the MySensors send function.

          See the section "About Interrupt Service Routines" at https://www.arduino.cc/en/Reference/attachInterrupt

          1 Reply Last reply
          2
          • A afick

            Hello,

            I'm checking some sensors in some time period:

            void loop()     
            {   
                
            
            unsigned long currentMillis_gas = millis();
            unsigned long currentMillis_temp = millis();
              
            if (currentMillis_temp - previousMillis_temp >= interval) {
            check_temp();
            check_gas();
            check_light();
            previousMillis_temp = currentMillis_temp;
            }
            }
            

            All working fine.

            But i have also PIR sensor.

            To catch PIR status I'm using interrupt

            attachInterrupt(digitalPinToInterrupt(2), check_pir, CHANGE);
            

            All works fine - except one think.
            When I call function check_pir() using interrupt, program is not able to back (after finishing function check_pir()) to running void loop.

            Its like program jump to check_pir() and stay there for ever....

            Any idea what im doing wrong ?

            YveauxY Offline
            YveauxY Offline
            Yveaux
            Mod
            wrote on last edited by
            #5

            @afick please post your whole sketch first, otherwise we won't be able to help.

            http://yveaux.blogspot.nl

            1 Reply Last reply
            0
            • A Offline
              A Offline
              afick
              wrote on last edited by
              #6

              A little bit messy :>

              /**
                 The MySensors Arduino library handles the wireless radio link and protocol
                 between your home built sensors/actuators and HA controller of choice.
                 The sensors forms a self healing radio network with optional repeaters. Each
                 repeater and gateway builds a routing tables in EEPROM which keeps track of the
                 network topology allowing messages to be routed to nodes.
              
                 Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                 Copyright (C) 2013-2015 Sensnology AB
                 Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
              
                 Documentation: http://www.mysensors.org
                 Support Forum: http://forum.mysensors.org
              
                 This program is free software; you can redistribute it and/or
                 modify it under the terms of the GNU General Public License
                 version 2 as published by the Free Software Foundation.
              
               *******************************
              
                 REVISION HISTORY
                 Version 1.0 - Henrik Ekblad
              
                 DESCRIPTION
                 Motion Sensor example using HC-SR501
                 http://www.mysensors.org/build/motion
              
              */
              
              // Enable debug prints
              #define MY_DEBUG
              
              // Enable and select radio type attached
              #define MY_RADIO_NRF24
              //#define MY_RADIO_RFM69
              
              #include <SPI.h>
              #include <MySensors.h>
              
              
              //pir================================================================================================================
              unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
              #define DIGITAL_INPUT_SENSOR 2   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
              #define CHILD_ID 40   // Id of the sensor child
              
              // Initialize motion message
              MyMessage msg(CHILD_ID, V_TRIPPED);
              bool lasttripped;
              
              //gas================================================================================================================
              
              
              
              #define   CHILD_ID_MQ                   43
              /************************Hardware Related Macros************************************/
              #define   MQ_SENSOR_ANALOG_PIN         (4)  //define which analog input channel you are going to use
              #define         RL_VALUE                     (5)     //define the load resistance on the board, in kilo ohms
              #define         RO_CLEAN_AIR_FACTOR          (9.83)  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
              //which is derived from the chart in datasheet
              /***********************Software Related Macros************************************/
              #define         CALIBARAION_SAMPLE_TIMES     (50)    //define how many samples you are going to take in the calibration phase
              #define         CALIBRATION_SAMPLE_INTERVAL  (500)   //define the time interal(in milisecond) between each samples in the
              //cablibration phase
              #define         READ_SAMPLE_INTERVAL         (50)    //define how many samples you are going to take in normal operation
              #define         READ_SAMPLE_TIMES            (5)     //define the time interal(in milisecond) between each samples in 
              //normal operation
              /**********************Application Related Macros**********************************/
              #define         GAS_LPG                      (0)
              #define         GAS_CO                       (1)
              #define         GAS_SMOKE                    (2)
              /*****************************Globals***********************************************/
              //VARIABLES
              float Ro = 10000.0;    // this has to be tuned 10K Ohm
              int val = 0;           // variable to store the value coming from the sensor
              float valMQ = 0.0;
              float lastMQ = 0.0;
              float           LPGCurve[3]  =  {2.3, 0.21, -0.47}; //two points are taken from the curve.
              //with these two points, a line is formed which is "approximately equivalent"
              //to the original curve.
              //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59)
              float           COCurve[3]  =  {2.3, 0.72, -0.34};  //two points are taken from the curve.
              //with these two points, a line is formed which is "approximately equivalent"
              //to the original curve.
              //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000,  0.15)
              float           SmokeCurve[3] = {2.3, 0.53, -0.44}; //two points are taken from the curve.
              //with these two points, a line is formed which is "approximately equivalent"
              //to the original curve.
              //data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22)
              
              
              MyMessage msg_gas(CHILD_ID_MQ, V_LEVEL);
              unsigned long interval_gas = 10000; // sprawdzanie czasu dla gazu
              
              //light
              #define CHILD_ID_LIGHT 44
              #define LIGHT_SENSOR_ANALOG_PIN 2
              
              
              
              MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
              int lastLightLevel;
              
              
              
              
              //dht================================================================================================================
              #include <DHT.h>
              #define CHILD_ID_HUM 41
              #define CHILD_ID_TEMP 42
              #define HUMIDITY_SENSOR_DIGITAL_PIN 6
              DHT dht;
              float lastTemp;
              float lastHum;
              boolean metric = true;
              MyMessage msgHum(CHILD_ID_HUM, V_HUM);
              MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
              unsigned long previousMillis_temp = 0;
              const long interval = 10000;
              
              
              
              
              void setup()
              {
                pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
                dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
              
                metric = getConfig().isMetric;
                //gas
                Ro = MQCalibration(MQ_SENSOR_ANALOG_PIN);         //Calibrating the sensor. Please make sure the sensor is in clean air
              }
              
              void presentation()  {
              
                //dht
                present(CHILD_ID_HUM, S_HUM);
                present(CHILD_ID_TEMP, S_TEMP);
              
                //pir
              
                // Send the sketch version information to the gateway and Controller
                sendSketchInfo("Piwnica przejscie", "0.3");
              
                // Register all sensors to gw (they will be created as child devices)
                present(CHILD_ID, S_MOTION);
              
                attachInterrupt(digitalPinToInterrupt(2), check_pir, CHANGE);
              
              
                //gas
                present(CHILD_ID_MQ, S_AIR_QUALITY);
              
                //light
                present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
              }
              
              void loop()
              {
              
              
                unsigned long currentMillis_gas = millis();
                unsigned long currentMillis_temp = millis();
              
                if (currentMillis_temp - previousMillis_temp >= interval) {
                  check_temp();
                  check_gas();
                  check_light();
                  previousMillis_temp = currentMillis_temp;
                }
              }
              
              void check_light()
              {
                int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23;
                Serial.println(lightLevel);
                if (lightLevel != lastLightLevel) {
                  send(msgLight.set(lightLevel));
                  lastLightLevel = lightLevel;
                }
              
              
              }
              
              void check_pir()
              {
                Serial.println("check  PIR");
                // Read digital motion value
                boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
              
                Serial.println(tripped);
                send(msg.set(tripped ? "1" : "0")); // Send tripped value to gw
              
              }
              
              
              void check_temp()
              {
                delay(dht.getMinimumSamplingPeriod());
              
                // Fetch temperatures from DHT sensor
                float temperature = dht.getTemperature();
                if (isnan(temperature)) {
                  Serial.println("Failed reading temperature from DHT");
                } else if (temperature != lastTemp) {
                  lastTemp = temperature;
                  if (!metric) {
                    temperature = dht.toFahrenheit(temperature);
                  }
                  send(msgTemp.set(temperature, 1));
              #ifdef MY_DEBUG
                  Serial.print("T: ");
                  Serial.println(temperature);
              #endif
                }
              
                // Fetch humidity from DHT sensor
                float humidity = dht.getHumidity();
                if (isnan(humidity)) {
                  Serial.println("Failed reading humidity from DHT");
                } else if (humidity != lastHum) {
                  lastHum = humidity;
                  send(msgHum.set(humidity, 1));
              #ifdef MY_DEBUG
                  Serial.print("H: ");
                  Serial.println(humidity);
              #endif
                }
              }
              
              
              void check_gas()
              {
                uint16_t valMQ = MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_CO);
                Serial.println(val);
              
                Serial.print("LPG:");
                Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_LPG) );
                Serial.print( "ppm" );
                Serial.print("    ");
                Serial.print("CO:");
                Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_CO) );
                Serial.print( "ppm" );
                Serial.print("    ");
                Serial.print("SMOKE:");
                Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_SMOKE) );
                Serial.print( "ppm" );
                Serial.print("\n");
              
                if (valMQ != lastMQ) {
                  send(msg_gas.set((int)ceil(valMQ)));
                  lastMQ = ceil(valMQ);
                }
              }
              
              
              float MQResistanceCalculation(int raw_adc)
              {
                return ( ((float)RL_VALUE * (1023 - raw_adc) / raw_adc));
              }
              
              /***************************** MQCalibration ****************************************
                Input:   mq_pin - analog channel
                Output:  Ro of the sensor
                Remarks: This function assumes that the sensor is in clean air. It use
                       MQResistanceCalculation to calculates the sensor resistance in clean air
                       and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
                       10, which differs slightly between different sensors.
              ************************************************************************************/
              float MQCalibration(int mq_pin)
              {
                int i;
                float val = 0;
              
                for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {      //take multiple samples
                  val += MQResistanceCalculation(analogRead(mq_pin));
                  delay(CALIBRATION_SAMPLE_INTERVAL);
                }
                val = val / CALIBARAION_SAMPLE_TIMES;                 //calculate the average value
              
                val = val / RO_CLEAN_AIR_FACTOR;                      //divided by RO_CLEAN_AIR_FACTOR yields the Ro
                //according to the chart in the datasheet
              
                return val;
              }
              /*****************************  MQRead *********************************************
                Input:   mq_pin - analog channel
                Output:  Rs of the sensor
                Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
                       The Rs changes as the sensor is in the different consentration of the target
                       gas. The sample times and the time interval between samples could be configured
                       by changing the definition of the macros.
              ************************************************************************************/
              float MQRead(int mq_pin)
              {
                int i;
                float rs = 0;
              
                for (i = 0; i < READ_SAMPLE_TIMES; i++) {
                  rs += MQResistanceCalculation(analogRead(mq_pin));
                  delay(READ_SAMPLE_INTERVAL);
                }
              
                rs = rs / READ_SAMPLE_TIMES;
              
                return rs;
              }
              
              /*****************************  MQGetGasPercentage **********************************
                Input:   rs_ro_ratio - Rs divided by Ro
                       gas_id      - target gas type
                Output:  ppm of the target gas
                Remarks: This function passes different curves to the MQGetPercentage function which
                       calculates the ppm (parts per million) of the target gas.
              ************************************************************************************/
              int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
              {
                if ( gas_id == GAS_LPG ) {
                  return MQGetPercentage(rs_ro_ratio, LPGCurve);
                } else if ( gas_id == GAS_CO ) {
                  return MQGetPercentage(rs_ro_ratio, COCurve);
                } else if ( gas_id == GAS_SMOKE ) {
                  return MQGetPercentage(rs_ro_ratio, SmokeCurve);
                }
              
                return 0;
              }
              
              /*****************************  MQGetPercentage **********************************
                Input:   rs_ro_ratio - Rs divided by Ro
                       pcurve      - pointer to the curve of the target gas
                Output:  ppm of the target gas
                Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
                       of the line could be derived if y(rs_ro_ratio) is provided. As it is a
                       logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
                       value.
              ************************************************************************************/
              int  MQGetPercentage(float rs_ro_ratio, float *pcurve)
              {
                return (pow(10, ( ((log(rs_ro_ratio) - pcurve[1]) / pcurve[2]) + pcurve[0])));
              }
              
              YveauxY 1 Reply Last reply
              0
              • A afick

                A little bit messy :>

                /**
                   The MySensors Arduino library handles the wireless radio link and protocol
                   between your home built sensors/actuators and HA controller of choice.
                   The sensors forms a self healing radio network with optional repeaters. Each
                   repeater and gateway builds a routing tables in EEPROM which keeps track of the
                   network topology allowing messages to be routed to nodes.
                
                   Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                   Copyright (C) 2013-2015 Sensnology AB
                   Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                
                   Documentation: http://www.mysensors.org
                   Support Forum: http://forum.mysensors.org
                
                   This program is free software; you can redistribute it and/or
                   modify it under the terms of the GNU General Public License
                   version 2 as published by the Free Software Foundation.
                
                 *******************************
                
                   REVISION HISTORY
                   Version 1.0 - Henrik Ekblad
                
                   DESCRIPTION
                   Motion Sensor example using HC-SR501
                   http://www.mysensors.org/build/motion
                
                */
                
                // Enable debug prints
                #define MY_DEBUG
                
                // Enable and select radio type attached
                #define MY_RADIO_NRF24
                //#define MY_RADIO_RFM69
                
                #include <SPI.h>
                #include <MySensors.h>
                
                
                //pir================================================================================================================
                unsigned long SLEEP_TIME = 120000; // Sleep time between reports (in milliseconds)
                #define DIGITAL_INPUT_SENSOR 2   // The digital input you attached your motion sensor.  (Only 2 and 3 generates interrupt!)
                #define CHILD_ID 40   // Id of the sensor child
                
                // Initialize motion message
                MyMessage msg(CHILD_ID, V_TRIPPED);
                bool lasttripped;
                
                //gas================================================================================================================
                
                
                
                #define   CHILD_ID_MQ                   43
                /************************Hardware Related Macros************************************/
                #define   MQ_SENSOR_ANALOG_PIN         (4)  //define which analog input channel you are going to use
                #define         RL_VALUE                     (5)     //define the load resistance on the board, in kilo ohms
                #define         RO_CLEAN_AIR_FACTOR          (9.83)  //RO_CLEAR_AIR_FACTOR=(Sensor resistance in clean air)/RO,
                //which is derived from the chart in datasheet
                /***********************Software Related Macros************************************/
                #define         CALIBARAION_SAMPLE_TIMES     (50)    //define how many samples you are going to take in the calibration phase
                #define         CALIBRATION_SAMPLE_INTERVAL  (500)   //define the time interal(in milisecond) between each samples in the
                //cablibration phase
                #define         READ_SAMPLE_INTERVAL         (50)    //define how many samples you are going to take in normal operation
                #define         READ_SAMPLE_TIMES            (5)     //define the time interal(in milisecond) between each samples in 
                //normal operation
                /**********************Application Related Macros**********************************/
                #define         GAS_LPG                      (0)
                #define         GAS_CO                       (1)
                #define         GAS_SMOKE                    (2)
                /*****************************Globals***********************************************/
                //VARIABLES
                float Ro = 10000.0;    // this has to be tuned 10K Ohm
                int val = 0;           // variable to store the value coming from the sensor
                float valMQ = 0.0;
                float lastMQ = 0.0;
                float           LPGCurve[3]  =  {2.3, 0.21, -0.47}; //two points are taken from the curve.
                //with these two points, a line is formed which is "approximately equivalent"
                //to the original curve.
                //data format:{ x, y, slope}; point1: (lg200, 0.21), point2: (lg10000, -0.59)
                float           COCurve[3]  =  {2.3, 0.72, -0.34};  //two points are taken from the curve.
                //with these two points, a line is formed which is "approximately equivalent"
                //to the original curve.
                //data format:{ x, y, slope}; point1: (lg200, 0.72), point2: (lg10000,  0.15)
                float           SmokeCurve[3] = {2.3, 0.53, -0.44}; //two points are taken from the curve.
                //with these two points, a line is formed which is "approximately equivalent"
                //to the original curve.
                //data format:{ x, y, slope}; point1: (lg200, 0.53), point2:(lg10000,-0.22)
                
                
                MyMessage msg_gas(CHILD_ID_MQ, V_LEVEL);
                unsigned long interval_gas = 10000; // sprawdzanie czasu dla gazu
                
                //light
                #define CHILD_ID_LIGHT 44
                #define LIGHT_SENSOR_ANALOG_PIN 2
                
                
                
                MyMessage msgLight(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
                int lastLightLevel;
                
                
                
                
                //dht================================================================================================================
                #include <DHT.h>
                #define CHILD_ID_HUM 41
                #define CHILD_ID_TEMP 42
                #define HUMIDITY_SENSOR_DIGITAL_PIN 6
                DHT dht;
                float lastTemp;
                float lastHum;
                boolean metric = true;
                MyMessage msgHum(CHILD_ID_HUM, V_HUM);
                MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
                unsigned long previousMillis_temp = 0;
                const long interval = 10000;
                
                
                
                
                void setup()
                {
                  pinMode(DIGITAL_INPUT_SENSOR, INPUT);      // sets the motion sensor digital pin as input
                  dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
                
                  metric = getConfig().isMetric;
                  //gas
                  Ro = MQCalibration(MQ_SENSOR_ANALOG_PIN);         //Calibrating the sensor. Please make sure the sensor is in clean air
                }
                
                void presentation()  {
                
                  //dht
                  present(CHILD_ID_HUM, S_HUM);
                  present(CHILD_ID_TEMP, S_TEMP);
                
                  //pir
                
                  // Send the sketch version information to the gateway and Controller
                  sendSketchInfo("Piwnica przejscie", "0.3");
                
                  // Register all sensors to gw (they will be created as child devices)
                  present(CHILD_ID, S_MOTION);
                
                  attachInterrupt(digitalPinToInterrupt(2), check_pir, CHANGE);
                
                
                  //gas
                  present(CHILD_ID_MQ, S_AIR_QUALITY);
                
                  //light
                  present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
                }
                
                void loop()
                {
                
                
                  unsigned long currentMillis_gas = millis();
                  unsigned long currentMillis_temp = millis();
                
                  if (currentMillis_temp - previousMillis_temp >= interval) {
                    check_temp();
                    check_gas();
                    check_light();
                    previousMillis_temp = currentMillis_temp;
                  }
                }
                
                void check_light()
                {
                  int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23;
                  Serial.println(lightLevel);
                  if (lightLevel != lastLightLevel) {
                    send(msgLight.set(lightLevel));
                    lastLightLevel = lightLevel;
                  }
                
                
                }
                
                void check_pir()
                {
                  Serial.println("check  PIR");
                  // Read digital motion value
                  boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
                
                  Serial.println(tripped);
                  send(msg.set(tripped ? "1" : "0")); // Send tripped value to gw
                
                }
                
                
                void check_temp()
                {
                  delay(dht.getMinimumSamplingPeriod());
                
                  // Fetch temperatures from DHT sensor
                  float temperature = dht.getTemperature();
                  if (isnan(temperature)) {
                    Serial.println("Failed reading temperature from DHT");
                  } else if (temperature != lastTemp) {
                    lastTemp = temperature;
                    if (!metric) {
                      temperature = dht.toFahrenheit(temperature);
                    }
                    send(msgTemp.set(temperature, 1));
                #ifdef MY_DEBUG
                    Serial.print("T: ");
                    Serial.println(temperature);
                #endif
                  }
                
                  // Fetch humidity from DHT sensor
                  float humidity = dht.getHumidity();
                  if (isnan(humidity)) {
                    Serial.println("Failed reading humidity from DHT");
                  } else if (humidity != lastHum) {
                    lastHum = humidity;
                    send(msgHum.set(humidity, 1));
                #ifdef MY_DEBUG
                    Serial.print("H: ");
                    Serial.println(humidity);
                #endif
                  }
                }
                
                
                void check_gas()
                {
                  uint16_t valMQ = MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_CO);
                  Serial.println(val);
                
                  Serial.print("LPG:");
                  Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_LPG) );
                  Serial.print( "ppm" );
                  Serial.print("    ");
                  Serial.print("CO:");
                  Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_CO) );
                  Serial.print( "ppm" );
                  Serial.print("    ");
                  Serial.print("SMOKE:");
                  Serial.print(MQGetGasPercentage(MQRead(MQ_SENSOR_ANALOG_PIN) / Ro, GAS_SMOKE) );
                  Serial.print( "ppm" );
                  Serial.print("\n");
                
                  if (valMQ != lastMQ) {
                    send(msg_gas.set((int)ceil(valMQ)));
                    lastMQ = ceil(valMQ);
                  }
                }
                
                
                float MQResistanceCalculation(int raw_adc)
                {
                  return ( ((float)RL_VALUE * (1023 - raw_adc) / raw_adc));
                }
                
                /***************************** MQCalibration ****************************************
                  Input:   mq_pin - analog channel
                  Output:  Ro of the sensor
                  Remarks: This function assumes that the sensor is in clean air. It use
                         MQResistanceCalculation to calculates the sensor resistance in clean air
                         and then divides it with RO_CLEAN_AIR_FACTOR. RO_CLEAN_AIR_FACTOR is about
                         10, which differs slightly between different sensors.
                ************************************************************************************/
                float MQCalibration(int mq_pin)
                {
                  int i;
                  float val = 0;
                
                  for (i = 0; i < CALIBARAION_SAMPLE_TIMES; i++) {      //take multiple samples
                    val += MQResistanceCalculation(analogRead(mq_pin));
                    delay(CALIBRATION_SAMPLE_INTERVAL);
                  }
                  val = val / CALIBARAION_SAMPLE_TIMES;                 //calculate the average value
                
                  val = val / RO_CLEAN_AIR_FACTOR;                      //divided by RO_CLEAN_AIR_FACTOR yields the Ro
                  //according to the chart in the datasheet
                
                  return val;
                }
                /*****************************  MQRead *********************************************
                  Input:   mq_pin - analog channel
                  Output:  Rs of the sensor
                  Remarks: This function use MQResistanceCalculation to caculate the sensor resistenc (Rs).
                         The Rs changes as the sensor is in the different consentration of the target
                         gas. The sample times and the time interval between samples could be configured
                         by changing the definition of the macros.
                ************************************************************************************/
                float MQRead(int mq_pin)
                {
                  int i;
                  float rs = 0;
                
                  for (i = 0; i < READ_SAMPLE_TIMES; i++) {
                    rs += MQResistanceCalculation(analogRead(mq_pin));
                    delay(READ_SAMPLE_INTERVAL);
                  }
                
                  rs = rs / READ_SAMPLE_TIMES;
                
                  return rs;
                }
                
                /*****************************  MQGetGasPercentage **********************************
                  Input:   rs_ro_ratio - Rs divided by Ro
                         gas_id      - target gas type
                  Output:  ppm of the target gas
                  Remarks: This function passes different curves to the MQGetPercentage function which
                         calculates the ppm (parts per million) of the target gas.
                ************************************************************************************/
                int MQGetGasPercentage(float rs_ro_ratio, int gas_id)
                {
                  if ( gas_id == GAS_LPG ) {
                    return MQGetPercentage(rs_ro_ratio, LPGCurve);
                  } else if ( gas_id == GAS_CO ) {
                    return MQGetPercentage(rs_ro_ratio, COCurve);
                  } else if ( gas_id == GAS_SMOKE ) {
                    return MQGetPercentage(rs_ro_ratio, SmokeCurve);
                  }
                
                  return 0;
                }
                
                /*****************************  MQGetPercentage **********************************
                  Input:   rs_ro_ratio - Rs divided by Ro
                         pcurve      - pointer to the curve of the target gas
                  Output:  ppm of the target gas
                  Remarks: By using the slope and a point of the line. The x(logarithmic value of ppm)
                         of the line could be derived if y(rs_ro_ratio) is provided. As it is a
                         logarithmic coordinate, power of 10 is used to convert the result to non-logarithmic
                         value.
                ************************************************************************************/
                int  MQGetPercentage(float rs_ro_ratio, float *pcurve)
                {
                  return (pow(10, ( ((log(rs_ro_ratio) - pcurve[1]) / pcurve[2]) + pcurve[0])));
                }
                
                YveauxY Offline
                YveauxY Offline
                Yveaux
                Mod
                wrote on last edited by Yveaux
                #7

                @afick Sorry for my request for the full sketch -- for some reason I only saw your first post.
                Anyway, @mfalkvidd is right, you should not access the MySensors library (e.g. send messages) from an interrupt handler. That will certainly mess up things.
                What you could do is set e.g. a flag from the interrupt handler and check in the loop() function if this flag has been set. If so, send a message and clear the flag.

                E.g. (untested):

                static volatile bool pirChanged = false;
                static volatile bool pirTripped;
                
                void check_pir()
                {
                  pirTripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH;
                  pirChanged = true;
                }
                
                void loop()
                {
                  // .. your old code ..
                
                  if (pirChanged)
                  {
                    send(msg.set(pirTripped ? "1" : "0"));   // Send tripped value to gw
                    pirChanged = false;
                  }
                }
                

                http://yveaux.blogspot.nl

                1 Reply Last reply
                2
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                14

                Online

                11.7k

                Users

                11.2k

                Topics

                113.1k

                Posts


                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • MySensors
                • OpenHardware.io
                • Categories
                • Recent
                • Tags
                • Popular