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. Troubleshooting
  3. Timer2 does not work after including MySensors.h

Timer2 does not work after including MySensors.h

Scheduled Pinned Locked Moved Troubleshooting
17 Posts 3 Posters 1.9k Views 2 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.
  • T TSD

    @mfalkvidd

    "The application" in this case is just a blinking LED. I intend to use the ISR to read out a sensor and send the data with MySensors. But because I couldn't get the ISR to work, I reduced "the application" to an LED to keep this discussion focused on the real issue.

    Yes, it always compiles, whether I include MySensors.h or not, and whether I use Arduino IDE or Atmel Studio.

    It's just that the LED doesn't always blink. In fact, the LED only blinks if I compile with Atmel Studio and don't include MySensors.h.

    I cannot use a serial monitor, because the custom node only has an ISP interface to program the MCU, there's no USB or anything like that.

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

    @tsd my guess is that there is a problem with wiring to the radio, or that MySensors is unable to connect to your gateway.

    In both those cases, MySensors will never reach setup() or loop().

    What do the logs from your gateway say?
    If you add something to presentation(), does the presentation reach your gateway?

    1 Reply Last reply
    0
    • T Offline
      T Offline
      TSD
      wrote on last edited by TSD
      #7

      @mfalkvidd
      I was testing without the radio even attached, to try and simplify the problem.

      But I reconnected the radio and expanded my example sketch to include a battery voltage measurement, that is transmitted to the GW with the RFM69 radio. The MySensors part of the sketch runs well, but the LED on pin 3 does not blink.

      #define MY_NODE_ID 6
      #define MY_RADIO_RFM69
      #define MY_IS_RFM69HW
      #define MY_DEBUG
      
      #define LEDPIN 3
      
      #include <MySensors.h>
      
      MyMessage msgVcc(1, V_VOLTAGE);
      
      
      int LEDstate = 0;
      volatile byte counter;
      ISR(TIMER2_OVF_vect) {
      
      	++counter;
      	if (counter == 0) {
      		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
      		LEDstate = !LEDstate;
      	};
      }
      
      void presentation()
      {
      	sendSketchInfo("Vbat", "1.0");
      	present(1, S_MULTIMETER);
      
      }
      
      void setup()
      {
      	// Configure timer 2
      	bitSet(ASSR,AS2);                // Select external clock for timer2
      	TCCR2B = bit(CS22) | bit(CS20);  // Set clock divider to 1024
      	bitSet(TIMSK2, TOIE2);           // Set timer 2 Overflow Interupt Enable (Timer Interupt Mask)
      	
      	// Configure LED
      	pinMode(LEDPIN,OUTPUT);
      	digitalWrite(LEDPIN,HIGH);
      	
      	sei();
      }
      
      void loop()
      {
      	if (counter) {
      		counter = 0;
      //		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
      //		LEDstate = !LEDstate;
      	}
      	
      	long vcc = readVcc();      // Read battery voltage
      	send(msgVcc.set(vcc, 1));  // Send battery voltage
      	sleep(2000);               // Sleep 2s
      
      }
      
      
      long readVcc() {
      	// Read 1.1V reference against AVcc
      	// set the reference to Vcc and the measurement to the internal 1.1V reference
      	#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      	#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
      	ADMUX = _BV(MUX5) | _BV(MUX0);
      	#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
      	ADMUX = _BV(MUX3) | _BV(MUX2);
      	#else
      	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
      	#endif
      
      	delay(2); // Wait for Vref to settle
      	ADCSRA |= _BV(ADSC); // Start conversion
      	while (bit_is_set(ADCSRA,ADSC)); // measuring
      
      	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
      	uint8_t high = ADCH; // unlocks both
      
      	long result = (high<<8) | low;
      
      	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
      	return result; // Vcc in millivolts
      }
      

      The GW log looks as expected, and repeats every 2 seconds:

      11-8-2018 11:21:18node: b9b6269f.12ee68
      msg.payload : string[73]
      "0;255;3;0;9;2046448 TSF:MSG:READ,6-6-0,s=1,c=1,t=38,pt=7,l=5,sg=0:3319.0↵"
      11-8-2018 11:21:18node: b9b6269f.12ee68
      msg.payload : string[18]
      "6;1;1;0;38;3319.0↵"
      
      11-8-2018 11:21:20node: b9b6269f.12ee68
      msg.payload : string[73]
      "0;255;3;0;9;2048732 TSF:MSG:READ,6-6-0,s=1,c=1,t=38,pt=7,l=5,sg=0:3319.0↵"
      11-8-2018 11:21:20node: b9b6269f.12ee68
      msg.payload : string[18]
      "6;1;1;0;38;3319.0↵"
      

      However, the LED that should be toggled from the ISR, doesn't blink. The LED does blink with the code that I showed at the start of this thread (without any MySensors stuff).

      My goal is to start the measurement and send the result from the ISR and not from the main loop to save more power. The current consumption during sleep is about 3.5uA now. I hope to get to around 1uA if I use timer 2. I've seen examples of people using timer 2 with the RTC, so I don't understand why this doesn't work in my case.

      Hope the issue is more clear now. Does this make any sense to you?

      mfalkviddM 1 Reply Last reply
      0
      • T TSD

        @mfalkvidd
        I was testing without the radio even attached, to try and simplify the problem.

        But I reconnected the radio and expanded my example sketch to include a battery voltage measurement, that is transmitted to the GW with the RFM69 radio. The MySensors part of the sketch runs well, but the LED on pin 3 does not blink.

        #define MY_NODE_ID 6
        #define MY_RADIO_RFM69
        #define MY_IS_RFM69HW
        #define MY_DEBUG
        
        #define LEDPIN 3
        
        #include <MySensors.h>
        
        MyMessage msgVcc(1, V_VOLTAGE);
        
        
        int LEDstate = 0;
        volatile byte counter;
        ISR(TIMER2_OVF_vect) {
        
        	++counter;
        	if (counter == 0) {
        		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
        		LEDstate = !LEDstate;
        	};
        }
        
        void presentation()
        {
        	sendSketchInfo("Vbat", "1.0");
        	present(1, S_MULTIMETER);
        
        }
        
        void setup()
        {
        	// Configure timer 2
        	bitSet(ASSR,AS2);                // Select external clock for timer2
        	TCCR2B = bit(CS22) | bit(CS20);  // Set clock divider to 1024
        	bitSet(TIMSK2, TOIE2);           // Set timer 2 Overflow Interupt Enable (Timer Interupt Mask)
        	
        	// Configure LED
        	pinMode(LEDPIN,OUTPUT);
        	digitalWrite(LEDPIN,HIGH);
        	
        	sei();
        }
        
        void loop()
        {
        	if (counter) {
        		counter = 0;
        //		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
        //		LEDstate = !LEDstate;
        	}
        	
        	long vcc = readVcc();      // Read battery voltage
        	send(msgVcc.set(vcc, 1));  // Send battery voltage
        	sleep(2000);               // Sleep 2s
        
        }
        
        
        long readVcc() {
        	// Read 1.1V reference against AVcc
        	// set the reference to Vcc and the measurement to the internal 1.1V reference
        	#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
        	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        	#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
        	ADMUX = _BV(MUX5) | _BV(MUX0);
        	#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
        	ADMUX = _BV(MUX3) | _BV(MUX2);
        	#else
        	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
        	#endif
        
        	delay(2); // Wait for Vref to settle
        	ADCSRA |= _BV(ADSC); // Start conversion
        	while (bit_is_set(ADCSRA,ADSC)); // measuring
        
        	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
        	uint8_t high = ADCH; // unlocks both
        
        	long result = (high<<8) | low;
        
        	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
        	return result; // Vcc in millivolts
        }
        

        The GW log looks as expected, and repeats every 2 seconds:

        11-8-2018 11:21:18node: b9b6269f.12ee68
        msg.payload : string[73]
        "0;255;3;0;9;2046448 TSF:MSG:READ,6-6-0,s=1,c=1,t=38,pt=7,l=5,sg=0:3319.0↵"
        11-8-2018 11:21:18node: b9b6269f.12ee68
        msg.payload : string[18]
        "6;1;1;0;38;3319.0↵"
        
        11-8-2018 11:21:20node: b9b6269f.12ee68
        msg.payload : string[73]
        "0;255;3;0;9;2048732 TSF:MSG:READ,6-6-0,s=1,c=1,t=38,pt=7,l=5,sg=0:3319.0↵"
        11-8-2018 11:21:20node: b9b6269f.12ee68
        msg.payload : string[18]
        "6;1;1;0;38;3319.0↵"
        

        However, the LED that should be toggled from the ISR, doesn't blink. The LED does blink with the code that I showed at the start of this thread (without any MySensors stuff).

        My goal is to start the measurement and send the result from the ISR and not from the main loop to save more power. The current consumption during sleep is about 3.5uA now. I hope to get to around 1uA if I use timer 2. I've seen examples of people using timer 2 with the RTC, so I don't understand why this doesn't work in my case.

        Hope the issue is more clear now. Does this make any sense to you?

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

        @tsd nice work.
        If you by "send the result from the ISR" mean sending using MySensors, it won't work. Inside an ISR, interrupts and timers are disabled so communicating with the radio is impossible. Also, sending would take way too much time. ISRs are meant to be very short.

        Are you sure timer2 will increment while the mcu is sleeping? I know millis() will never increment during sleep. Maybe the same happens to timer2? What happens if you use wait() instead of sleep()?

        1 Reply Last reply
        0
        • mfalkviddM Offline
          mfalkviddM Offline
          mfalkvidd
          Mod
          wrote on last edited by
          #9

          Might be interesting to check if @ewasscher ever got around to implementing the stuff discussed in https://forum.mysensors.org/topic/2555/support-for-wake-up-by-timer2-instead-of-wd

          1 Reply Last reply
          0
          • scalzS Offline
            scalzS Offline
            scalz
            Hardware Contributor
            wrote on last edited by scalz
            #10

            @TSD
            it's more clear now, because with the stripped version it could have been lot of other things :)

            you'll need to make your own sleep function. because for the moment, powerdown mode only is available in MySensors. and as you may know it's not good for your timer2 (you need powersave mode).

            1 Reply Last reply
            1
            • T Offline
              T Offline
              TSD
              wrote on last edited by
              #11

              @mfalkvidd, @scalz
              Thanks, now we're getting somewhere. When I use wait(), the LED blinks. That makes sense if sleep() uses power down mode, which turns off almost everything, including timer 2.

              I'll read the sensor and send the data (with MySensors) from the counter in the main loop. Then I'll see if I can get the MCU to sleep while leaving timer2 on with extended standby mode.

              Thanks for your help!

              1 Reply Last reply
              1
              • T Offline
                T Offline
                TSD
                wrote on last edited by TSD
                #12

                @mfalkvidd @scalz
                I tried first to disable the RFM69 with the _radio.sleep() function:

                 
                
                #define MY_NODE_ID 6
                #define MY_RADIO_RFM69
                #define MY_IS_RFM69HW
                #define MY_DEBUG
                #define MY_DEBUG_VERBOSE_RFM69
                
                #define LEDPIN 3
                
                #include <MySensors.h>
                
                MyMessage msgVcc(1, V_VOLTAGE);
                
                int LEDstate = 0;
                volatile byte counter = 0;
                int PostScaler = 0;
                
                ISR(TIMER2_OVF_vect) {
                	++counter;
                }
                
                void presentation()
                {
                	sendSketchInfo("Vbat", "1.0");
                	present(1, S_MULTIMETER);
                }
                
                void setup()
                {
                	// Configure timer 2
                	bitSet(ASSR,AS2);                // Select external clock for timer2
                	TCCR2B = bit(CS22) | bit(CS20);  // Set clock divider to 1024
                	bitSet(TIMSK2, TOIE2);           // Set timer 2 Overflow Interupt Enable (Timer Interupt Mask)
                	
                	// Configure LED
                	pinMode(LEDPIN,OUTPUT);
                	digitalWrite(LEDPIN,HIGH);
                }
                
                void loop()
                {
                	if (counter) {
                		counter = 0;
                		
                		// Blink LED
                		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
                		LEDstate = !LEDstate;
                		
                		// Measure battery voltage and send data to gateway
                		if (PostScaler == 2) {
                			
                			_radio.receiveDone();      // Turn on radio
                			long vcc = readVcc();      // Read battery voltage
                			send(msgVcc.set(vcc, 1));  // Send battery voltage
                			_radio.sleep();            // Sleep radio
                			
                			PostScaler = 0;
                		}
                		PostScaler++;
                		sei();
                	}
                	
                	wait(2000);
                	
                }
                
                
                long readVcc() {
                	// Read 1.1V reference against AVcc
                	// set the reference to Vcc and the measurement to the internal 1.1V reference
                	#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
                	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                	#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                	ADMUX = _BV(MUX5) | _BV(MUX0);
                	#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                	ADMUX = _BV(MUX3) | _BV(MUX2);
                	#else
                	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                	#endif
                
                	delay(2); // Wait for Vref to settle
                	ADCSRA |= _BV(ADSC); // Start conversion
                	while (bit_is_set(ADCSRA,ADSC)); // measuring
                
                	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
                	uint8_t high = ADCH; // unlocks both
                
                	long result = (high<<8) | low;
                
                	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
                	return result; // Vcc in millivolts
                }
                

                However, the radio doesn't turn off at all. Is there anything else that needs to be configured before this function can be used?

                mfalkviddM 1 Reply Last reply
                0
                • T TSD

                  @mfalkvidd @scalz
                  I tried first to disable the RFM69 with the _radio.sleep() function:

                   
                  
                  #define MY_NODE_ID 6
                  #define MY_RADIO_RFM69
                  #define MY_IS_RFM69HW
                  #define MY_DEBUG
                  #define MY_DEBUG_VERBOSE_RFM69
                  
                  #define LEDPIN 3
                  
                  #include <MySensors.h>
                  
                  MyMessage msgVcc(1, V_VOLTAGE);
                  
                  int LEDstate = 0;
                  volatile byte counter = 0;
                  int PostScaler = 0;
                  
                  ISR(TIMER2_OVF_vect) {
                  	++counter;
                  }
                  
                  void presentation()
                  {
                  	sendSketchInfo("Vbat", "1.0");
                  	present(1, S_MULTIMETER);
                  }
                  
                  void setup()
                  {
                  	// Configure timer 2
                  	bitSet(ASSR,AS2);                // Select external clock for timer2
                  	TCCR2B = bit(CS22) | bit(CS20);  // Set clock divider to 1024
                  	bitSet(TIMSK2, TOIE2);           // Set timer 2 Overflow Interupt Enable (Timer Interupt Mask)
                  	
                  	// Configure LED
                  	pinMode(LEDPIN,OUTPUT);
                  	digitalWrite(LEDPIN,HIGH);
                  }
                  
                  void loop()
                  {
                  	if (counter) {
                  		counter = 0;
                  		
                  		// Blink LED
                  		digitalWrite(LEDPIN,(LEDstate) ? HIGH : LOW);
                  		LEDstate = !LEDstate;
                  		
                  		// Measure battery voltage and send data to gateway
                  		if (PostScaler == 2) {
                  			
                  			_radio.receiveDone();      // Turn on radio
                  			long vcc = readVcc();      // Read battery voltage
                  			send(msgVcc.set(vcc, 1));  // Send battery voltage
                  			_radio.sleep();            // Sleep radio
                  			
                  			PostScaler = 0;
                  		}
                  		PostScaler++;
                  		sei();
                  	}
                  	
                  	wait(2000);
                  	
                  }
                  
                  
                  long readVcc() {
                  	// Read 1.1V reference against AVcc
                  	// set the reference to Vcc and the measurement to the internal 1.1V reference
                  	#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
                  	ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                  	#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
                  	ADMUX = _BV(MUX5) | _BV(MUX0);
                  	#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
                  	ADMUX = _BV(MUX3) | _BV(MUX2);
                  	#else
                  	ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
                  	#endif
                  
                  	delay(2); // Wait for Vref to settle
                  	ADCSRA |= _BV(ADSC); // Start conversion
                  	while (bit_is_set(ADCSRA,ADSC)); // measuring
                  
                  	uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
                  	uint8_t high = ADCH; // unlocks both
                  
                  	long result = (high<<8) | low;
                  
                  	result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
                  	return result; // Vcc in millivolts
                  }
                  

                  However, the radio doesn't turn off at all. Is there anything else that needs to be configured before this function can be used?

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

                  @tsd this is way to deep for my knowledge unfortunately. Sorry.

                  T 1 Reply Last reply
                  0
                  • mfalkviddM mfalkvidd

                    @tsd this is way to deep for my knowledge unfortunately. Sorry.

                    T Offline
                    T Offline
                    TSD
                    wrote on last edited by
                    #14

                    @mfalkvidd Do you know anyone that might know more about this?

                    1 Reply Last reply
                    0
                    • scalzS Offline
                      scalzS Offline
                      scalz
                      Hardware Contributor
                      wrote on last edited by scalz
                      #15

                      @TSD
                      I've not digged and not time to replicate your setup, but I have a suspicion with wait()
                      Does it help by using delay() instead of wait().
                      you won't use wait() if you make your own sleep() I think, and maybe you'll also need to make your custom wait() if needed.
                      Because wait() purpose is :

                      • handle wdt, leds etc (see doYield)
                      • incoming radio msg, radio link

                      When you sleep radio with low level function like you do, then a few vars may be not updated in mysensors machine (like transportActive I think)
                      So mysensors machine does not know you disabled/slept the radio (whereas when using mysensors and sleep in regular way it knows it of course).
                      Then when you call wait(), mysensors machine will try to check link (as the state variable has not been updated), link check fails and then it reinit radio. no sleep!

                      Not checked on my side, but it could be that :)

                      1 Reply Last reply
                      0
                      • T Offline
                        T Offline
                        TSD
                        wrote on last edited by
                        #16

                        @scalz
                        Your hunch was correct! When I use delay(), the current drops to 4.6mA (from >20mA). So now I can start turning off MCU peripherals to reduce the current further.

                        By the way, is there good documentation to understand how all these MySensors functions work? Or do I just have to work with the Doxygen stuff and plough through all the relevant .h and .cpp files?

                        1 Reply Last reply
                        0
                        • scalzS Offline
                          scalzS Offline
                          scalz
                          Hardware Contributor
                          wrote on last edited by scalz
                          #17

                          @TSD
                          glad to hear i helped you.
                          you have to work with doxygen and sources

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


                          32

                          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