कैसे Arduino सीरियल बफर अतिप्रवाह संभालता है? क्या यह नवीनतम आने वाले डेटा को फेंक देता है या सबसे पुराना है? बफर कितने बाइट पकड़ सकता है?
कैसे Arduino सीरियल बफर अतिप्रवाह संभालता है? क्या यह नवीनतम आने वाले डेटा को फेंक देता है या सबसे पुराना है? बफर कितने बाइट पकड़ सकता है?
जवाबों:
हार्डवेयर सीरियल पोर्ट के लिए आप HardwareSerial.cpp में देख सकते हैं कि बफ़र का आकार विशेष AVR पर उपलब्ध RAM की मात्रा के आधार पर भिन्न होता है:
#if (RAMEND < 1000)
#define SERIAL_BUFFER_SIZE 16
#else
#define SERIAL_BUFFER_SIZE 64
#endif
SoftwareSerial.h में सॉफ़्टवेयर सीरियल पोर्ट के लिए रिसीवर बफर आकार _SS_MAX_RX_BUFF
को 64 बाइट्स के रूप में परिभाषित किया गया है। दोनों ही मामलों में यह भरा हुआ होने पर प्राप्त डेटा को कतार में सम्मिलित करने का प्रयास करना बंद कर देता है, इसलिए आप कतार से डेटा कैसे प्राप्त कर रहे हैं, इसके आधार पर पुराने और नए डेटा का मिश्रण प्राप्त कर सकते हैं।
आदर्श रूप से यह सुनिश्चित करना सबसे अच्छा होगा कि बफर भरने से बचने के लिए बफर हमेशा एक त्वरित तरीके से खाली हो जाता है। हो सकता है कि टाइमर पर एक नज़र डालें और एक साधारण राज्य मशीन को लागू करें यदि आपकी समस्या मुख्य लूप को अवरुद्ध करने वाले अन्य कोड से संबंधित है।
आप HardwareSerial के स्रोत से देख सकते हैं कि यदि कोई आवक बाइट रिंग बफ़र को पूर्ण पाता है तो उसे छोड़ दिया जाता है:
inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
मुझे यह आभास होता है कि अगर मैं Arduino पर डेटा संचारित करता हूं और Arduino की तरफ डेटा का सक्रिय "खींचने वाला" नहीं है, तो यदि बफर में फिट होने से अधिक डेटा आता है, तो इसे छोड़ दिया जाएगा। क्या आप इसकी पुष्टि कर सकते हैं?
हाँ, इसे छोड़ दिया जाएगा। कोई सॉफ्टवेयर या हार्डवेयर प्रवाह नियंत्रण नहीं है, जब तक कि आप अपना खुद का कार्यान्वयन न करें।
हालाँकि, 64-बाइट बफर के साथ, और 9600 बॉड में (प्राप्त) डेटा प्राप्त होता है, आपको हर 1.04 ms पर एक बाइट मिलता है, और इस तरह बफर को भरने में 66.6 ms लगते हैं। 16 मेगाहर्ट्ज प्रोसेसर पर आप बफर को अक्सर पर्याप्त रूप से जांचने में सक्षम होना चाहिए कि यह नहीं भरता है। आपको बस इतना करना है कि हार्डवेयरस्फीयर बफर से डेटा को अपने आप में स्थानांतरित करना है, अगर आप इसे अभी प्रोसेस नहीं करना चाहते हैं।
आप #if (RAMEND < 1000)
चेक से देख सकते हैं कि 1000+ बाइट रैम वाले प्रोसेसर को 64-बाइट बफर मिलता है, कम रैम में 16-बाइट बफर मिलेगा।
आपके द्वारा लिखा गया डेटा एक समान आकार के बफर (16 या 64 बाइट्स) में रखा गया है। भेजने के मामले में यदि बफर कोड "ब्लॉक" भरता है तो सीरियल पोर्ट से अगले बाइट को भेजने के लिए एक रुकावट की प्रतीक्षा करता है।
यदि इंटरप्ट को बंद कर दिया जाता है तो ऐसा कभी नहीं होगा, इस प्रकार आप एक इंटरप्ट सर्विस सर्विस के अंदर सीरियल प्रिंट नहीं करते हैं।
1/960 = 0.001042 s
- कि हर 1.04 एमएस में एक बाइट है।