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 Offline
    T Offline
    TSD
    wrote on last edited by TSD
    #5

    @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 1 Reply Last reply
    1
    • 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


                            11

                            Online

                            11.7k

                            Users

                            11.2k

                            Topics

                            113.0k

                            Posts


                            Copyright 2019 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