โค้ดด้านล่างนี้บรรลุสิ่งที่คุณต้องการ:
#include <avr/sleep.h>
#include <avr/power.h>
const byte AWAKE_LED = 8;
const byte GREEN_LED = 9;
const unsigned long WAIT_TIME = 5000;
ISR (PCINT2_vect)
{
  // handle pin change interrupt for D0 to D7 here
}  // end of PCINT2_vect
void setup() 
{
  pinMode (GREEN_LED, OUTPUT);
  pinMode (AWAKE_LED, OUTPUT);
  digitalWrite (AWAKE_LED, HIGH);
  Serial.begin (9600);
} // end of setup
unsigned long lastSleep;
void loop() 
{
  if (millis () - lastSleep >= WAIT_TIME)
  {
    lastSleep = millis ();
    noInterrupts ();
    byte old_ADCSRA = ADCSRA;
    // disable ADC
    ADCSRA = 0;  
    // pin change interrupt (example for D0)
    PCMSK2 |= bit (PCINT16); // want pin 0
    PCIFR  |= bit (PCIF2);   // clear any outstanding interrupts
    PCICR  |= bit (PCIE2);   // enable pin change interrupts for D0 to D7
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
    power_adc_disable();
    power_spi_disable();
    power_timer0_disable();
    power_timer1_disable();
    power_timer2_disable();
    power_twi_disable();
    UCSR0B &= ~bit (RXEN0);  // disable receiver
    UCSR0B &= ~bit (TXEN0);  // disable transmitter
    sleep_enable();
    digitalWrite (AWAKE_LED, LOW);
    interrupts ();
    sleep_cpu ();      
    digitalWrite (AWAKE_LED, HIGH);
    sleep_disable();
    power_all_enable();
    ADCSRA = old_ADCSRA;
    PCICR  &= ~bit (PCIE2);   // disable pin change interrupts for D0 to D7
    UCSR0B |= bit (RXEN0);  // enable receiver
    UCSR0B |= bit (TXEN0);  // enable transmitter
  }  // end of time to sleep
  if (Serial.available () > 0)
  {
    byte flashes = Serial.read () - '0';
    if (flashes > 0 && flashes < 10)
      {
      // flash LED x times 
      for (byte i = 0; i < flashes; i++)
        {
        digitalWrite (GREEN_LED, HIGH);
        delay (200);  
        digitalWrite (GREEN_LED, LOW);
        delay (200);  
        }
      }        
  }  // end of if
}  // end of loop
ฉันใช้การขัดจังหวะการเปลี่ยนพินบนพิน Rx เพื่อแจ้งให้ทราบเมื่อมีข้อมูลซีเรียลมาถึง ในการทดสอบนี้บอร์ดจะเข้าสู่โหมดสลีปหากไม่มีกิจกรรมหลังจาก 5 วินาที (LED "ตื่น" ดับ) ข้อมูลอนุกรมที่เข้ามาทำให้การขัดจังหวะการเปลี่ยนพินเพื่อปลุกบอร์ด มันจะมองหาตัวเลขและกะพริบไฟ LED "สีเขียว" จำนวนครั้งนั้น
วัดกระแสไฟฟ้า
ทำงานที่ 5 V ฉันวัดกระแสประมาณ 120 nA เมื่อหลับ (0.120 µA) 
ข้อความตื่นขึ้น
อย่างไรก็ตามปัญหาคือว่าไบต์แรกที่มาถึงจะหายไปเนื่องจากฮาร์ดแวร์อนุกรมคาดว่าระดับที่ลดลงของ Rx (บิตเริ่มต้น) ซึ่งมาถึงแล้วเมื่อถึงเวลาที่มันตื่นเต็มที่
ผมขอแนะนำให้ (ในขณะที่คำตอบของ geometrikal) ให้คุณส่งข้อความ "ตื่น" แล้วหยุดเป็นเวลาสั้น ๆ การหยุดชั่วคราวคือเพื่อให้แน่ใจว่าฮาร์ดแวร์ไม่ได้แปลไบต์ถัดไปเป็นส่วนหนึ่งของข้อความที่ปลุก หลังจากนั้นควรทำงานได้ดี
เนื่องจากสิ่งนี้ใช้การขัดจังหวะการเปลี่ยนขาโดยไม่ต้องใช้ฮาร์ดแวร์อื่น
รุ่นที่แก้ไขโดยใช้ SoftwareSerial
รุ่นด้านล่างประมวลผลไบต์แรกที่ได้รับเป็นผลสำเร็จ มันทำได้โดย:
ได้รับแรงบันดาลใจจาก FarO ในความคิดเห็นสิ่งนี้ทำให้โปรเซสเซอร์ตื่นขึ้นในรอบ 6 นาฬิกา (750 ns) ที่ 9600 baud ในแต่ละ bit เวลาเท่ากับ 1/9600 (104.2 )s) ดังนั้นการหน่วงเวลาเพิ่มเติมจึงไม่มีนัยสำคัญ
#include <avr/sleep.h>
#include <avr/power.h>
#include <SoftwareSerial.h>
const byte AWAKE_LED = 8;
const byte GREEN_LED = 9;
const unsigned long WAIT_TIME = 5000;
const byte RX_PIN = 4;
const byte TX_PIN = 5;
SoftwareSerial mySerial(RX_PIN, TX_PIN); // RX, TX
void setup() 
{
  pinMode (GREEN_LED, OUTPUT);
  pinMode (AWAKE_LED, OUTPUT);
  digitalWrite (AWAKE_LED, HIGH);
  mySerial.begin(9600);
} // end of setup
unsigned long lastSleep;
void loop() 
{
  if (millis () - lastSleep >= WAIT_TIME)
  {
    lastSleep = millis ();
    noInterrupts ();
    byte old_ADCSRA = ADCSRA;
    // disable ADC
    ADCSRA = 0;  
    set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
    power_adc_disable();
    power_spi_disable();
    power_timer0_disable();
    power_timer1_disable();
    power_timer2_disable();
    power_twi_disable();
    sleep_enable();
    digitalWrite (AWAKE_LED, LOW);
    interrupts ();
    sleep_cpu ();      
    digitalWrite (AWAKE_LED, HIGH);
    sleep_disable();
    power_all_enable();
    ADCSRA = old_ADCSRA;
  }  // end of time to sleep
  if (mySerial.available () > 0)
  {
    byte flashes = mySerial.read () - '0';
    if (flashes > 0 && flashes < 10)
      {
      // flash LED x times 
      for (byte i = 0; i < flashes; i++)
        {
        digitalWrite (GREEN_LED, HIGH);
        delay (200);  
        digitalWrite (GREEN_LED, LOW);
        delay (200);  
        }
      }        
  }  // end of if
}  // end of loop
การใช้พลังงานเมื่อนอนหลับวัดได้ที่ 260 nA (0.260 µA) ดังนั้นจึงสิ้นเปลืองพลังงานน้อยมากเมื่อไม่ต้องการใช้
โปรดทราบว่าด้วยฟิวส์ที่ตั้งไว้เช่นนั้นโปรเซสเซอร์จะทำงานที่ 8 MHz ดังนั้นคุณต้องบอก IDE เกี่ยวกับเรื่องนั้น (เช่นเลือก "Lilypad" เป็นประเภทกระดาน) ด้วยวิธีนี้ความล่าช้าและ SoftwareSerial จะทำงานด้วยความเร็วที่ถูกต้อง