नीचे दिए गए कोड से आप क्या पूछ रहे हैं:
#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 सेकंड के बाद कोई गतिविधि नहीं होती है ("जाग" एलईडी बाहर जाती है)। आने वाले सीरियल डेटा के कारण बोर्ड को जगाने के लिए पिन-चेंज में रुकावट आती है। यह एक संख्या की तलाश करता है और कई बार "हरी" एलईडी को फ्लैश करता है।
मापा वर्तमान
5 वी पर चल रहा है, मैंने सोते समय (0.120 VA) के बारे में वर्तमान के 120 एनए को मापा।
जागृति संदेश
हालांकि एक समस्या यह है कि पहली बार आने वाली बाइट इस तथ्य के कारण खो जाती है कि धारावाहिक हार्डवेयर आरएक्स (शुरुआती बिट) पर गिरने के स्तर की उम्मीद करता है जो पहले से ही पूरी तरह से जाग चुका है।
मेरा सुझाव है (जैसा कि ज्यामितीय उत्तर में) है कि आप पहले "जाग" संदेश भेजें, और फिर थोड़े समय के लिए रुकें । ठहराव यह सुनिश्चित करने के लिए है कि हार्डवेयर जागृत संदेश के हिस्से के रूप में अगले बाइट की व्याख्या नहीं करता है। उसके बाद ठीक काम करना चाहिए।
चूंकि यह पिन-चेंज इंटरप्ट का उपयोग करता है इसलिए किसी अन्य हार्डवेयर की आवश्यकता नहीं है।
SoftwareSerial का उपयोग करके संशोधित संस्करण
नीचे दिया गया संस्करण सीरियल पर प्राप्त पहली बाइट को सफलतापूर्वक संसाधित करता है। यह इसके द्वारा करता है:
SoftwareSerial का उपयोग करना जो पिन-चेंज इंटरप्ट का उपयोग करता है। पहले सीरियल बाइट के शुरू होने के कारण जो व्यवधान होता है, वह प्रोसेसर को भी जगाता है।
फ़्यूज़ सेट करना ताकि हम उपयोग करें:
- आंतरिक आरसी थरथरानवाला
- BOD अक्षम है
- फ़्यूज़ थे: निम्न: 0xD2, उच्च: 0xDF, विस्तारित: 0xFF
एक टिप्पणी में फरओ से प्रेरित होकर, यह प्रोसेसर को 6 घड़ी चक्र (750 एनएस) में जागने देता है। 9600 बॉड में प्रत्येक बिट समय 1/9600 (104.2 each) है, इसलिए अतिरिक्त देरी महत्वहीन है।
#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 एनए (0.260 soA) के रूप में मापी गई थी, ताकि जब जरूरत न हो तो बहुत कम खपत हो।
ध्यान दें कि जैसे फ़्यूज़ सेट होता है, प्रोसेसर 8 मेगाहर्ट्ज़ पर चलता है। इस प्रकार आपको उस बारे में IDE बताने की आवश्यकता है (उदाहरण के लिए "लिलिपैड" को बोर्ड प्रकार के रूप में चुनें)। इस तरह देरी और SoftwareSerial सही गति से काम करेंगे।