Beispiel #1
0
// Called from loop().
void loopAlt()
  {

  // Sleep in low-power mode (waiting for interrupts) until seconds roll.
  // NOTE: sleep at the top of the loop to minimise timing jitter/delay from Arduino background activity after loop() returns.
  // DHD20130425: waking up from sleep and getting to start processing below this block may take >10ms.
#if 0 && defined(DEBUG)
  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*E"); // End-of-cycle sleep.
#endif
  powerDownSerial(); // Ensure that serial I/O is off.
  // Power down most stuff (except radio for hub RX).
  minimisePowerWithoutSleep();
  static uint_fast8_t TIME_LSD; // Controller's notion of seconds within major cycle.
  uint_fast8_t newTLSD;
  while(TIME_LSD == (newTLSD = getSecondsLT()))
    {
    sleepUntilInt(); // Normal long minimal-power sleep until wake-up interrupt.
    }
  TIME_LSD = newTLSD;
#if 0 && defined(DEBUG)
  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*S"); // Start-of-cycle wake.
#endif


  // START LOOP BODY
  // ===============
 
  DEBUG_SERIAL_PRINTLN_FLASHSTRING("tick...");



  DEBUG_SERIAL_PRINTLN_FLASHSTRING("int count: ");
  DEBUG_SERIAL_PRINT(interruptCount);
  DEBUG_SERIAL_PRINTLN();





  }
Beispiel #2
0
// Called from loop().
void loopAlt()
{
    // Sleep in low-power mode (waiting for interrupts) until seconds roll.
    // NOTE: sleep at the top of the loop to minimise timing jitter/delay from Arduino background activity after loop() returns.
    // DHD20130425: waking up from sleep and getting to start processing below this block may take >10ms.
#if 0 && defined(DEBUG)
    DEBUG_SERIAL_PRINTLN_FLASHSTRING("*E"); // End-of-cycle sleep.
#endif

#if !defined(ENABLE_MIN_ENERGY_BOOT)
    OTV0P2BASE::powerDownSerial(); // Ensure that serial I/O is off.
    // Power down most stuff (except radio for hub RX).
    minimisePowerWithoutSleep();
#endif
    static uint_fast8_t TIME_LSD; // Controller's notion of seconds within major cycle.
    uint_fast8_t newTLSD;
    while(TIME_LSD == (newTLSD = OTV0P2BASE::getSecondsLT()))
    {
        // Poll I/O and process message incrementally (in this otherwise idle time)
        // before sleep and on wakeup in case some IO needs further processing now,
        // eg work was accrued during the previous major slow/outer loop
        // or the in a previous orbit of this loop sleep or nap was terminated by an I/O interrupt.
        // Come back and have another go if work was done, until the next tick at most.
        if(handleQueuedMessages(&Serial, true, &PrimaryRadio)) {
            continue;
        }

// If missing h/w interrupts for anything that needs rapid response
// then AVOID the lowest-power long sleep.
#if defined(ENABLE_CONTINUOUS_RX) && !defined(PIN_RFM_NIRQ)
#define MUST_POLL_FREQUENTLY true
#else
#define MUST_POLL_FREQUENTLY false
#endif
        if(MUST_POLL_FREQUENTLY /** && in hub mode */ )
        {
            // No h/w interrupt wakeup on receipt of frame,
            // so can only sleep for a short time between explicit poll()s,
            // though allow wake on interrupt anyway to minimise loop timing jitter.
            OTV0P2BASE::nap(WDTO_15MS, true);
        }
        else
        {
            // Normal long minimal-power sleep until wake-up interrupt.
            // Rely on interrupt to force fall through to I/O poll() below.
            OTV0P2BASE::sleepUntilInt();
        }
//    DEBUG_SERIAL_PRINTLN_FLASHSTRING("w"); // Wakeup.

//    idle15AndPoll(); // Attempt to crash the board!

    }
    TIME_LSD = newTLSD;

#if 0 && defined(DEBUG)
    DEBUG_SERIAL_PRINTLN_FLASHSTRING("*S"); // Start-of-cycle wake.
#endif


    // START LOOP BODY
    // ===============

//  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*");

//  // Power up serial for the loop body.
//  // May just want to turn it on in POSTalt() and leave it on...
//  const bool neededWaking = powerUpSerialIfDisabled();




//#if defined(ENABLE_FHT8VSIMPLE)
//  // Try for double TX for more robust conversation with valve?
//  const bool doubleTXForFTH8V = false;
//  // FHT8V is highest priority and runs first.
//  // ---------- HALF SECOND #0 -----------
//  bool useExtraFHT8VTXSlots = localFHT8VTRVEnabled() && FHT8VPollSyncAndTX_First(doubleTXForFTH8V); // Time for extra TX before UI.
////  if(useExtraFHT8VTXSlots) { DEBUG_SERIAL_PRINTLN_FLASHSTRING("ES@0"); }
//#endif



    switch(TIME_LSD)
    {
#ifdef ENABLE_STATS_TX
    // Regular transmission of stats if NOT driving a local valve (else stats can be piggybacked onto that).
    case 10:
    {
//      if((OTV0P2BASE::getMinutesLT() & 0x3) == 0) // Send once every 4 minutes.
        {
            // Send it!
            // Try for double TX for extra robustness unless:
            //   * this is a speculative 'extra' TX
            //   * battery is low
            //   * this node is a hub so needs to listen as much as possible
            // This doesn't generally/always need to send binary/both formats
            // if this is controlling a local FHT8V on which the binary stats can be piggybacked.
            // Ie, if doesn't have a local TRV then it must send binary some of the time.
            // Any recently-changed stats value is a hint that a strong transmission might be a good idea.
            const bool doBinary = false; // !localFHT8VTRVEnabled() && OTV0P2BASE::randRNG8NextBoolean();
            bareStatsTX(false, false, false);
        }
        break;
    }
#endif

    // Poll ambient light level at a fixed rate.
    // This allows the unit to respond consistently to (eg) switching lights on (eg TODO-388).
    case 20: {
        AmbLight.read();
        break;
    }

#if defined(ENABLE_PRIMARY_TEMP_SENSOR_DS18B20)
    case 30: {
        TemperatureC16.read();
        break;
    }
#endif // ENABLE_PRIMARY_TEMP_SENSOR_DS18B20

#if defined(ENABLE_VOICE_SENSOR)
    // read voice sensor
    case 40: {
        Voice.read();
        break;
    }
#endif // (ENABLE_VOICE_SENSOR)

#ifdef ENABLE_OCCUPANCY_SUPPORT
    case 50: {
        Occupancy.read();    // Needs regular poll.
        break;
    }
#endif // ENABLE_OCCUPANCY_SUPPORT
    }


    PrimaryRadio.poll();



//#if defined(ENABLE_FHT8VSIMPLE)
//  if(useExtraFHT8VTXSlots)
//    {
//    // Time for extra TX before other actions, but don't bother if minimising power in frost mode.
//    // ---------- HALF SECOND #1 -----------
//    useExtraFHT8VTXSlots = localFHT8VTRVEnabled() && FHT8VPollSyncAndTX_Next(doubleTXForFTH8V);
////    if(useExtraFHT8VTXSlots) { DEBUG_SERIAL_PRINTLN_FLASHSTRING("ES@1"); }
//    }
//#endif





//#if defined(ENABLE_FHT8VSIMPLE) && defined(V0P2BASE_TWO_S_TICK_RTC_SUPPORT)
//  if(useExtraFHT8VTXSlots)
//    {
//    // ---------- HALF SECOND #2 -----------
//    useExtraFHT8VTXSlots = localFHT8VTRVEnabled() && FHT8VPollSyncAndTX_Next(doubleTXForFTH8V);
////    if(useExtraFHT8VTXSlots) { DEBUG_SERIAL_PRINTLN_FLASHSTRING("ES@2"); }
//    }
//#endif





//#if defined(ENABLE_FHT8VSIMPLE) && defined(V0P2BASE_TWO_S_TICK_RTC_SUPPORT)
//  if(useExtraFHT8VTXSlots)
//    {
//    // ---------- HALF SECOND #3 -----------
//    useExtraFHT8VTXSlots = localFHT8VTRVEnabled() && FHT8VPollSyncAndTX_Next(doubleTXForFTH8V);
////    if(useExtraFHT8VTXSlots) { DEBUG_SERIAL_PRINTLN_FLASHSTRING("ES@3"); }
//    }
//#endif


//#ifdef HAS_DORM1_VALVE_DRIVE
//  // Move valve to new target every minute to try to upset it!
//  // Targets at key thresholds and random.
//  if(0 == TIME_LSD)
//    {
//    switch(OTV0P2BASE::randRNG8() & 1)
//      {
//      case 0: ValveDirect.set(OTRadValve::DEFAULT_VALVE_PC_MIN_REALLY_OPEN-1); break; // Nominally shut.
//      case 1: ValveDirect.set(OTRadValve::DEFAULT_VALVE_PC_MODERATELY_OPEN); break; // Nominally open.
//      // Random.
////      default: ValveDirect.set(OTV0P2BASE::randRNG8() % 101); break;
//      }
//    }
//
//  // Simulate human doing the right thing after fitting valve when required.
//  if(ValveDirect.isWaitingForValveToBeFitted()) { ValveDirect.signalValveFitted(); }
//
//  // Provide regular poll to motor driver.
//  // May take significant time to run
//  // so don't call when timing is critical or not much left,
//  // eg around critical TXes.
//  const uint8_t pc = ValveDirect.read();
//  DEBUG_SERIAL_PRINT_FLASHSTRING("Pos%: ");
//  DEBUG_SERIAL_PRINT(pc);
//  DEBUG_SERIAL_PRINTLN();
//#endif



//  // Reading shaft encoder.
//  // Measure motor count against (fixed) internal reference.
//  power_intermittent_peripherals_enable(true);
//  const uint16_t mc = analogueNoiseReducedRead(MOTOR_DRIVE_MC_AIN, INTERNAL);
//  void power_intermittent_peripherals_disable();
//  DEBUG_SERIAL_PRINT_FLASHSTRING("Count input: ");
//  DEBUG_SERIAL_PRINT(mc);
//  DEBUG_SERIAL_PRINTLN();














//  // Force any pending output before return / possible UART power-down.
//  flushSerialSCTSensitive();
//  if(neededWaking) { OTV0P2BASE::powerDownSerial(); }
}
Beispiel #3
0
// Called from loop().
void loopAlt()
  {
  // Sleep in low-power mode (waiting for interrupts) until seconds roll.
  // NOTE: sleep at the top of the loop to minimise timing jitter/delay from Arduino background activity after loop() returns.
  // DHD20130425: waking up from sleep and getting to start processing below this block may take >10ms.
#if 0 && defined(DEBUG)
  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*E"); // End-of-cycle sleep.
#endif

#if defined(WAKEUP_32768HZ_XTAL) // Normal 32768Hz crystal driving main timing.
  powerDownSerial(); // Ensure that serial I/O is off.
  // Power down most stuff (except radio for hub RX).
  minimisePowerWithoutSleep();
//  RFM22ModeStandbyAndClearState();
  static uint_fast8_t TIME_LSD; // Controller's notion of seconds within major cycle.
  uint_fast8_t newTLSD;
  while(TIME_LSD == (newTLSD = getSecondsLT()))
    {
    sleepUntilInt(); // Normal long minimal-power sleep until wake-up interrupt.
//    DEBUG_SERIAL_PRINTLN_FLASHSTRING("w"); // Wakeup.
    }
  TIME_LSD = newTLSD;
#else // Keep running on main RC clock, simulating normal-ish sleep length.
  delay(2000);
#endif

#if 0 && defined(DEBUG)
  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*S"); // Start-of-cycle wake.
#endif


  // START LOOP BODY
  // ===============

  DEBUG_SERIAL_PRINTLN_FLASHSTRING("*");



//  const bool neededWaking = powerUpSerialIfDisabled();


//  const int heat = TemperatureC16.read();
//#if 1 && defined(DEBUG)
//  DEBUG_SERIAL_PRINT_FLASHSTRING("temp: ");
//  DEBUG_SERIAL_PRINT(heat);
//  DEBUG_SERIAL_PRINTLN();
//#endif


//#if defined(DIRECT_MOTOR_DRIVE_V1) && defined(ALT_MAIN_LOOP) && defined(DEBUG)
//  // Ensure that end-stop current-sense feedback is enabled before starting the motor.
//  cb.hitEndStop = false;
//  hd.enableFeedback(true, cb);
//  // Ensure that the motor is running...
//  static bool open = true;
//  if(open) { DEBUG_SERIAL_PRINTLN_FLASHSTRING("opening"); } else { DEBUG_SERIAL_PRINTLN_FLASHSTRING("closing"); }
//  hd.motorRun(open ? HardwareMotorDriverInterface::motorDriveOpening : HardwareMotorDriverInterface::motorDriveClosing);
//  // Try to ride through any start-up transients...
//  nap(WDTO_120MS);
//  nap(WDTO_120MS);
//  nap(WDTO_120MS);
//  nap(WDTO_120MS);
//  // Spin the motor for up to about 1.5s polling for end-stop hit, etc.
//  while(!cb.hitEndStop && (getSubCycleTime() < 0xc0))
//    {
//    hd.enableFeedback(true, cb);
//    }
//  // Stop motor.
//  hd.motorRun(HardwareMotorDriverInterface::motorOff);
//  // Iff the end-stop was hit then reverse the motor.
//  if(cb.hitEndStop)
//    {
//    DEBUG_SERIAL_PRINTLN_FLASHSTRING("Hit end stop; reversing...");
//    open = !open;
//    }
//#endif

//  static bool boilerOut;
//  boilerOut = !boilerOut;
//  if(boilerOut) { LED_HEATCALL_ON() } else { LED_HEATCALL_OFF(); }
//  fastDigitalWrite(OUT_HEATCALL, boilerOut ? HIGH : LOW);
//#if defined(LED_UI2_L)
//  if(boilerOut) { LED_UI2_OFF() } else { LED_UI2_ON(); }
//#endif



//  uint8_t addr[8];
//
//  if(!MinOW.search(addr))
//    {
//    Serial.println("No more slaves found...");
//    MinOW.reset_search();
//    return;
//    }
//
//  // Found a device.
//  Serial.print("addr:");
//  for(int i = 0; i < 8; ++i)
//    {
//    Serial.write(' ');
//    Serial.print(addr[i], HEX);
//    }
//  Serial.println();
//
//  if(0x28 != addr[0])
//    {
//    Serial.println("Not a DS18B20...");
//    return;
//    }
//
//#define DS1820_PRECISION_MASK 0x60
//#define DS1820_PRECISION_9 0x00
//#define DS1820_PRECISION_10 0x20
//#define DS1820_PRECISION_11 0x40 // 1/8C @ 375ms.
//#define DS1820_PRECISION_12 0x60 // 1/16C @ 750ms.
//
//#define DS1820_PRECISION DS1820_PRECISION_11 // 1/8C @ 375ms.
//
//
//  // Force any pending output before return / possible UART power-down.
//  flushSerialSCTSensitive();
//  if(neededWaking) { powerDownSerial(); }
//
//  DEBUG_SERIAL_PRINTLN_FLASHSTRING("Setting precision...");
//  MinOW.reset();
//  // Write scratchpad/config
//  MinOW.select(addr);
//  MinOW.write(0x4e);
//  MinOW.write(0); // Th: not used.
//  MinOW.write(0); // Tl: not used.
//  MinOW.write(DS1820_PRECISION | 0x1f); // Config register; lsbs all 1.
//
//  const unsigned long usStart = micros();
//
//  // Start a temperature reading.
//  MinOW.reset();
//  MinOW.select(addr);
//  MinOW.write(0x44); // Start conversion without parasite power.
//  //delay(1000); // 750ms should be enough.
//  while(MinOW.read_bit() == 0) { /*nap(WDTO_30MS);*/ } // Poll for conversion complete (bus released)...
//
//  // Fetch temperature (scratchpad read).
//  MinOW.reset();
//  MinOW.select(addr);    
//  MinOW.write(0xbe);
//  byte data[2]; // Read first two bytes of 9 available.
//  for(uint8_t i = 0; i < sizeof(data); ++i)
//    { 
//    data[i] = MinOW.read();
////    Serial.print(data[i], HEX);
////    Serial.print(" ");
//    }
//  Serial.println();
//  MinOW.reset();
//
//  const unsigned long usEnd = micros();
//  // Nominal loop time should be 2s x 1MHz clock, ie 2,000,000 if CPU running all the time.
//  // Should generally be <2000 (<0.1%) for leaf, <20000 (<1%) for hub.
//  const unsigned long usApparentTaken = usEnd - usStart;
//#if 1 && defined(DEBUG)
//  DEBUG_SERIAL_PRINT_FLASHSTRING("us apparent: ");
//  DEBUG_SERIAL_PRINT(usApparentTaken);
//  DEBUG_SERIAL_PRINTLN();
//#endif
//
//  if(neededWaking) { powerUpSerialIfDisabled(); }
//
//  // Extract raw temperature, masking any undefined lsbits.
//  const int16_t rawC16 = (data[1] << 8) | (data[0] & ~1);
//  Serial.print("C16=");
//  Serial.print(rawC16);
////  Serial.print(" = ");
////  Serial.print(rawC16 / 16.0f);
//  Serial.println();

//  // Force any pending output before return / possible UART power-down.
//  flushSerialSCTSensitive();
//
//  if(neededWaking) { powerDownSerial(); }
  }