रूप mclopez ने कहा, उनका कहना है के बजाय एक अच्छा जवाब प्रदान करने के लिए केवल क्या खामियां हैं बेहतर है अन्य लोगों की, तो ... हम यहाँ जाते हैं।
मेरी राय में आईएसआर समाधान एक अच्छा विकल्प नहीं है, क्योंकि आईएसआर सामान्य निष्पादन को अवरुद्ध करता है। इंटरप्ट्स का उपयोग करने वाला एकमात्र व्यवहार्य कार्यान्वयन पिन परिवर्तन रिकॉर्ड करना है और फिर एसएमएस भेजना है।
हालांकि, यह मेरी राय में एक अच्छा समाधान नहीं है। इस समस्या के लिए, मैं एसएमएस भेजने के लिए एक राज्य मशीन के साथ जाऊंगा; चूंकि आपके पास राज्य हैं, इसलिए आप बटन की जांच करने जैसी अन्य चीजें करते समय संक्रमण की प्रतीक्षा कर सकते हैं।
मुझे नहीं पता कि सिम 9 00 एसएमएस भेजता है, इसलिए मैं अपना वर्कफ़्लो ले रहा हूं और इसे एक राज्य मशीन में कार्यान्वित कर रहा हूं। मुझे यकीन नहीं है कि यह इष्टतम समाधान है, विशेष रूप से क्योंकि मुझे नहीं लगता कि आपको हर बार मॉड्यूल को रीबूट करने की ज़रूरत है, लेकिन आप इसे बाद में ट्रिम कर सकते हैं।
अब, वर्कफ़्लो में आपके पास सात क्रियाएं हैं, प्रत्येक के बाद प्रतीक्षा करें। मैं इसे यहाँ लिख तो यह आसान है हर कार्रवाई को देखने के लिए:
SIM900.print("AT+CMGF=1\r");
delay(100);
SIM900.println("AT + CMGS = \"+212xxxxxxx\"");
delay(100);
SIM900.println("Message you want");
delay(100);
SIM900.println((char)26);
delay(100);
SIM900.println();
delay(100);
digitalWrite(9 ,HIGH);
delay(1000);
digitalWrite(9 ,LOW);
delay(5000);
तो हम आठ राज्यों है: एक निष्क्रिय एक, पांच के बाद (जब आप राज्य मशीन शुरू करने के लिए, SIM_IDLE नामित के लिए इंतजार कर रहे हैं) "भेजें" राज्य (मैं उन्हें SIM_SEND1..5 नाम देता हूं) और दो राज्यों को पावर रीसेट करने के लिए (SIM_COW1 और SIM_POW2 नाम दिया गया)। आप आम तौर पर निष्क्रिय राज्य में होते हैं; जब एक या अधिक बटन दबाए जाते हैं, तो आप पहले प्रेषण, चक्र के माध्यम से चक्र पर स्विच करते हैं और फिर शक्ति को रीसेट करते हैं और निष्क्रिय होने पर वापस जाते हैं।
दबाए गए बटन केवल राज्य SIM_SEND3 को बदलते हैं (जब आप वास्तव में संदेश भेजते हैं), इसलिए जब भी बटन दबाया जाता है तो एक बूलियन चर सेट होता है (राज्य मशीन निष्पादन के दौरान भी एक बटन प्रेस का पता लगाया जाता है) और केवल रीसेट किया जाता है सही संदेश भेजने के बाद, वह राज्य।
अब, यहाँ कोड है जो इस को लागू करता है:
const uint8_t DI = 2;
const uint8_t DT = 3;
const uint8_t DGP1 = 4;
const uint8_t DGP2 = 5;
const uint8_t SIMPOW = 9;
uint8_t value1_old = 0;
uint8_t value2_old = 0;
uint8_t value3_old = 0;
uint8_t value4_old = 0;
boolean value1_changed = false;
boolean value2_changed = false;
boolean value3_changed = false;
boolean value4_changed = false;
/********************************/
// SIM STATES
#define SIM_IDLE 0
//SEND1: SIM900.print("AT+CMGF=1\r");delay(100);
#define SIM_SEND1 1
//SEND2: SIM900.println("AT + CMGS = \"+212xxxxxxx\"");delay(100);
#define SIM_SEND2 2
//SEND3: SIM900.println("Message you want");delay(100);
#define SIM_SEND3 3
//SEND4: SIM900.println((char)26);delay(100);
#define SIM_SEND4 4
//SEND5: SIM900.println();delay(100);
#define SIM_SEND5 5
//POW1: digitalWrite(SIMPOW,HIGH);delay(1000);
#define SIM_POW1 6
//POW2: digitalWrite(SIMPOW,LOW);delay(5000);
#define SIM_POW2 7
/********************************/
unsigned long previousMillis;
uint8_t currentSimState;
#include<SoftwareSerial.h>
SoftwareSerial SIM900 (7, 8);
void setup()
{
pinMode(DI, INPUT);
pinMode(DT, INPUT);
pinMode(DGP1, INPUT);
pinMode(DGP2, INPUT);
pinMode(SIMPOW, OUTPUT);
SIM900.begin(19200);
digitalWrite(SIMPOW,HIGH);
delay(1000);
digitalWrite(SIMPOW,LOW);
delay(25000);
currentSimState = -1; // Force a state transition
}
void loop()
{
uint8_t value1 = digitalRead (DI);
uint8_t value2 = digitalRead (DT);
uint8_t value3 = digitalRead (DGP1);
uint8_t value4 = digitalRead (DGP2);
unsigned long currentMillis = millis();
if (value2 != value2_old && value2 == HIGH)
value2_changed = true;
if (value3 != value3_old && value3 == HIGH)
value3_changed = true;
if (value4 != value4_old && value4 == HIGH)
value4_changed = true;
value1_old = value1;
value2_old = value2;
value3_old = value3;
value4_old = value4;
// Check if a state transition is needed
uint8_t newSimState = currentSimState;
switch (currentSimState)
{
case SIM_IDLE: // Start sending if a value changed
if ((value2_changed) || (value3_changed) || (value4_changed))
newSimState = SIM_SEND1;
break;
case SIM_SEND1: // Wait 100 ms
if ((currentMillis - previousMillis) >= 100)
newSimState = SIM_SEND2;
break;
case SIM_SEND2: // Wait 100 ms
if ((currentMillis - previousMillis) >= 100)
newSimState = SIM_SEND3;
break;
case SIM_SEND3: // Wait 100 ms
if ((currentMillis - previousMillis) >= 100)
newSimState = SIM_SEND4;
break;
case SIM_SEND4: // Wait 100 ms
if ((currentMillis - previousMillis) >= 100)
newSimState = SIM_SEND5;
break;
case SIM_SEND5: // Wait 100 ms
if ((currentMillis - previousMillis) >= 100)
newSimState = SIM_POW1;
break;
case SIM_POW1: // Wait 1000 ms
if ((currentMillis - previousMillis) >= 1000)
newSimState = SIM_POW2;
break;
case SIM_POW2: // Wait 1000 ms
if ((currentMillis - previousMillis) >= 1000)
newSimState = SIM_IDLE;
break;
default:
newSimState = SIM_IDLE;
break;
}
// If there was a transition, do the appropriate action
if (newSimState != currentSimState)
{
case SIM_IDLE:
// Do nothing
break;
case SIM_SEND1:
SIM900.print("AT+CMGF=1\r");
previousMillis = millis();
break;
case SIM_SEND2:
SIM900.println("AT + CMGS = \"+212xxxxxxx\"");
previousMillis = millis();
break;
case SIM_SEND3:
if (value2_changed)
{
SIM900.println("Station 85: Defaut electrique");
value2_changed = false;
}
else if (value3_changed)
{
SIM900.println("Station 85: DefautGP1");
value2_changed = false;
}
else if (value4_changed)
{
SIM900.println("Station 85:DD>1000");
value2_changed = false;
}
else
{
// Should never arrive here. Just in case, you
// can either abort the SMS sending if you can
// or send another message
}
previousMillis = millis();
break;
case SIM_SEND4:
SIM900.println((char)26);
previousMillis = millis();
break;
case SIM_SEND5:
SIM900.println();
previousMillis = millis();
break;
case SIM_POW1:
digitalWrite(SIMPOW,HIGH);
previousMillis = millis();
break;
case SIM_POW2:
digitalWrite(SIMPOW,LOW);
previousMillis = millis();
break;
}
}
// Advance state
currentSimState = newSimState;
}
यह जटिल लग सकता है, लेकिन यह वास्तव में बहुत सरल है। लूप तीन "ब्लॉक" द्वारा बनाया जाता है।
पहला बटन बटन चेक है। यदि कोई बटन दबाया जाता है, तो संबंधित valueX_changed
ध्वज सेट किया गया है। यह एक बहुत ही छोटा हिस्सा है, बस जांचें कि क्या किसी बटन के पास एक अलग राज्य है और फिर ध्वज सेट करें।
दूसरा भाग राज्य संक्रमण के लिए चेक है। इस स्विच स्टेटमेंट में प्रोग्राम निर्धारित करता है कि राज्य मशीन की स्थिति को बदलने की जरूरत है या नहीं। ऐसा तब होता है जब राज्य निष्क्रिय होता है, या यदि एसएमएस भेजने की प्रक्रिया में निर्दिष्ट समय बीत चुका है तो एक बटन दबाया गया था।
तीसरा हिस्सा एक राज्य में परिवर्तन होने पर किया जाने वाला कार्य है। तो अगर राज्य बदल गया है, तो राज्य कार्रवाई करें, जिसका मतलब निष्क्रिय राज्य के लिए कुछ नहीं है, सिम_एसईएनएक्सएक्स राज्यों के लिए कुछ भेजें और सिम_POWx राज्यों के लिए पिन बदलें।
बस एक नोट: सेटअप में आपने 20 सेकेंड देरी को सामान्य वर्कफ़्लो में प्रस्तुत नहीं किया है। अगर आप इसे हटाना चाहते हैं, तो आप रीसेट करने वाले सेटअप से चार लाइनों को हटा सकते हैं औरको को के बजाय newSimState = SIM_POW1;
सेट करने के लिए पहले स्विच में संशोधित कर सकते हैं।
छोटे कीड़े, इस कोड में नहीं हो सकता है के बाद से मैं यह परीक्षण नहीं किया है, लेकिन यह है कि तुम क्या चाहते थे
आप कहना है कि देरी का उपयोग करके आप चीजों पर इंतजार कर चक्र बर्बाद कर रहे बजाय कर रही है इसका मतलब यह है क्या करना चाहिए अधिक अन्य संभावित (समय महत्वपूर्ण) कार्यों? यदि ऐसा है, तो मुझे लगता है कि आपको इंटरप्ट्स (आईएसआर में समय-महत्वपूर्ण कार्य करने के लिए) या एवीआर पर मौजूद हार्डवेयर टाइमर का उपयोग करने की दिशा में देखने की आवश्यकता है। – initramfs
इसके बजाय मिलिस() फ़ंक्शन का उपयोग करें। ट्यूटोरियल उदाहरण [यहां है] (http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay)। –
मुझे लगता है कि मुझे देरी के स्थान पर मिलिस() का उपयोग करने की आवश्यकता है, लेकिन मुझे नहीं पता कि कैसे, क्योंकि मैं एक नौसिखिया हूं:/ –