Project

General

Profile

Idling in low-power mode

Added by Roj over 6 years ago

I’ve come back to the JeeNode after quite a break (in fact, the battery went flat on the JeeNode I’ve got monitoring my gas meter!). I saw “this article,”http://jeelabs.org/2013/05/28/idling-in-low-power-mode/ took the powerUse.ino sketch and modified it to flash the blue LED on a JeeNode USB (V3) by changing Thread1 to

void Thread1 () {
  while (1) {
    digitalWrite(LED_PIN, LOW);
    chThdSleepMilliseconds(10);
    digitalWrite(LED_PIN, HIGH);
    chThdSleepMilliseconds(490);
  }
}

declared the LED with

const uint8_t LED_PIN = 9;

and set it up (in setup) with

pinMode(LED_PIN, OUTPUT);

and it works fine with LOWPOWER = false. But with LOWPOWER = true, the LED still flashes, but very s l o o o w l y. Rather than 10 milliseconds, the LED stays on for about 8 seconds. Clearly, this is related to the use of Sleepy::loseSomeTime(16), but since the original article makes it seem that this was working, I was wondering if my problem might be related to fuse settings, or something else.

Anybody got any ideas, please?


Replies (6)

RE: Idling in low-power mode - Added by padvinder95 over 6 years ago

You did add the ISR(WDT_vect) { Sleepy::watchdogEvent(); } line?

RE: Idling in low-power mode - Added by Roj over 6 years ago

That line is in the original powerUse.ino sketch, so yes, I did. The interesting thing is that the sketch does run with ‘LOWPOWER = true’, just at about 1/800th of its ‘LOWPOWER = false’ speed.

RE: Idling in low-power mode - Added by martynj over 6 years ago

@Roj,  Some thread priority issue?  I can’t see the big picture - could you post the complete sketch?

RE: Idling in low-power mode - Added by Roj over 6 years ago

Here’s the entire sketch, to run on a JeeNode USB (mine’s a V3):-

#include 
#include 

const bool LOWPOWER = true; // set to true to enable low-power sleeping

// must be defined in case we're using the watchdog for low-power waiting
ISR(WDT_vect) { Sleepy::watchdogEvent(); }

const uint8_t LED_PIN = 9;      // define the LED
static WORKING_AREA(waThread1, 50);

// turn the LED on for 10 milliseconds, off for 490
void Thread1 () {
  while (1) {
    digitalWrite(LED_PIN, LOW);
    chThdSleepMilliseconds(10);
    digitalWrite(LED_PIN, HIGH);
    chThdSleepMilliseconds(490);
  }
}

void setup () {
  Serial.begin(57600);
  rf12_initialize(1, RF12_868MHZ);
  rf12_sleep(RF12_SLEEP);
  pinMode(LED_PIN, OUTPUT);  // initialise for the LED

  chBegin(mainThread);
}

void mainThread () {
  chThdCreateStatic(waThread1, sizeof (waThread1),
                    NORMALPRIO + 2, (tfunc_t) Thread1, 0);

  while (true)
    loop();
}

void loop () {
  if (LOWPOWER)
    Sleepy::loseSomeTime(16); // minimum watchdog granularity is 16 ms
  else
    delay(16);
}

I think the problem is that the ChibiOS virtual timers don’t know that time has passed when they wake up from low power mode. If that’s right, it needs the tickless timers that are coming in ChibiOS V3. I think I’ll just recharge the battery on my monitor and worry about something else!

Thanks for your help.

RE: Idling in low-power mode - Added by martynj over 6 years ago

Roj, is the ChibiOS using timer0 for its internal scheduling?  That would clash with Sleepy::watchdogEvent() etc using the same timer.

RE: Idling in low-power mode - Added by Roj over 6 years ago

I guess it does. This is board-specific code, the only place in the ChibiOS source where there’s any mention of TIMSKn or TIMERn

// WHG Arduino
#include "ch.h"
#include "hal.h"
CH_IRQ_HANDLER(TIMER0_COMPA_vect) {
  CH_IRQ_PROLOGUE();
  chSysLockFromIsr();
  chSysTimerHandlerI();
  chSysUnlockFromIsr();
  CH_IRQ_EPILOGUE();
}
/*
 * Board-specific initialization code.
 */
void boardInit(void) {
  /*
   * Timer 0 setup.
   */
  OCR0A = 128;
  TIMSK0  |= (1 << OCIE0A);                               /* IRQ on compare.  */
}
    (1-6/6)