2010-07-17 13 views
7

पर फ्लोट भेजने के लिए कैसे करें float, double, और int16 को Arduino पर धारावाहिक पर भेजने का सबसे अच्छा तरीका क्या है?सीरियल

Serial.print() केवल ASCII एन्कोडेड के रूप में मान भेजता है। लेकिन मैं मानों को बाइट्स के रूप में भेजना चाहता हूं। Serial.write() बाइट और बाइट्रेरे स्वीकार करता है, लेकिन मानों को बाइट्स में परिवर्तित करने का सबसे अच्छा तरीका क्या है?

मैंने भाग्य के बिना int16 को byte* पर डालने का प्रयास किया। मैंने memcpy भी इस्तेमाल किया, लेकिन यह कई CPU चक्रों का उपयोग करता है। Arduino सादे सी/सी ++ का उपयोग करता है। यह ATmega328 माइक्रोकंट्रोलर है।

+0

संभावित डुप्लिकेट [बाइनरी में एक int आउटपुट कैसे करें?] (Http://stackoverflow.com/questions/3269767/how-to-output-an-int-in-binary) –

उत्तर

9

हाँ, इन नंबरों आपको पहले उन्हें ASCII तार को बदलने के लिए है भेजने के लिए। यदि आप सी, sprintf() के साथ काम कर रहे हैं, तो आईएमओ, इस रूपांतरण को करने का सबसे आसान तरीका है:

[बाद में जोड़ा गया: आहाग! मैं भूल गया कि ints/longs के लिए, फ़ंक्शन का इनपुट तर्क हस्ताक्षरित होना चाहता है। इसी तरह प्रारूप स्ट्रिंग के लिए sprintf() को सौंप दिया गया। तो मैंने इसे नीचे बदल दिया। मेरी भयानक निगरानी के बारे में खेद है, जो एक कठिन खोजने वाला बग होता। इसके अलावा, ulong यह एक छोटे से अधिक सामान्य बनाता है।]

char * 
int2str(unsigned long num) { 
    static char retnum[21];  // Enough for 20 digits plus NUL from a 64-bit uint. 
    sprintf(retnum, "%ul", num); 
    return retnum; 
} 

और तैरता और युगल के लिए इसी तरह की। रूपांतरण करने वाला कोड अग्रिम में जाना जाता है। इसे बताया जाना चाहिए - यह किस प्रकार की इकाई परिवर्तित कर रहा है, ताकि आप char *float2str(float float_num) और char *dbl2str(double dblnum) कार्यों के साथ समाप्त हो सकें।

आपको रूपांतरण से बाहर एक एनयूएल-समाप्त बाएं समायोजित (कोई अग्रणी रिक्त स्थान या शून्य) वर्ण स्ट्रिंग नहीं मिलेगी।

आप कहीं भी/कहीं भी रूपांतरण कर सकते हैं; ये कार्य सिर्फ चित्र हैं।

10

एचएम। कैसे इस बारे में:

void send_float (float arg) 
{ 
    // get access to the float as a byte-array: 
    byte * data = (byte *) &arg; 

    // write the data to the serial 
    Serial.write (data, sizeof (arg)); 
} 
+0

मुझे इसे हराया .. – hjhill

+2

यदि इन्हें बाइट्स के रूप में भेजा जाता है - निश्चित रूप से बाइनरी - तो यह काम नहीं कर सकता है: कुछ बाइट नियंत्रण वर्णों की तरह दिखने जा रहे हैं जो रिसीवर शायद कार्य करेगा। तो संख्याओं को असीमित होना चाहिए। इसके अलावा, वर्णों को लगभग सीरियल लाइन पर लगभग सात बिट्स के रूप में भेजा जाता है, इसलिए उन्हें 8-बिट बाइट्स भेजने की कोशिश करने से उच्च-आदेश बिट कम हो जाएगा। –

+1

डेटा ट्रांसमिट करने का यह तरीका काम नहीं करेगा अगर एमिटर और रिसीवर के पास एक अलग अंतराल है। –

0

आकार का मामला क्या है? यदि ऐसा होता है, तो आप ASCII85 का उपयोग करके प्रत्येक 32 बिट समूह को 5 ASCII वर्णों में एन्कोड कर सकते हैं, http://en.wikipedia.org/wiki/Ascii85 देखें।

3

Firmata प्रोटोकॉल का उपयोग करें। उद्धरण:

फर्मटा माइक्रोकंट्रोलर के साथ होस्ट कंप्यूटर पर सॉफ़्टवेयर से संचार करने के लिए एक सामान्य प्रोटोकॉल है। यह किसी भी मेजबान कंप्यूटर सॉफ्टवेयर पैकेज के साथ काम करना है। अभी भाषाओं की संख्या में एक मिलान करने वाली वस्तु है। पर अन्य सॉफ़्टवेयर के लिए ऑब्जेक्ट्स को जोड़ना आसान है इस प्रोटोकॉल का उपयोग करें। असल में, यह फर्मवेयर मेजबान सॉफ़्टवेयर से Arduino से बात करते हुए के लिए प्रोटोकॉल स्थापित करता है। इसका उद्देश्य लोगों को मेजबान कंप्यूटर पर सॉफ़्टवेयर से Arduino को पूरी तरह से नियंत्रित करने की अनुमति देना है।

2

शब्दकोष शब्द जिसे आप देखना चाहते हैं वह "क्रमबद्धता" है।

यह एक धारावाहिक कनेक्शन पर एक दिलचस्प समस्या है, जिसके पर पात्रों का अंत हो सकता है कि कौन से पात्र समाप्त हो सकते हैं, और शायद प्रति चरित्र आठ बिट्स पास करने में सक्षम नहीं हो सकते हैं।

कुछ वर्ण कोडों पर प्रतिबंध काफी आम हैं। सॉफ्टवेयर प्रवाह नियंत्रण उपयोग में है

  • है, तो पारंपरिक नियंत्रण वर्ण DC1 और DC3 (Ctrl-क्यू और Ctrl-एस, भी कभी कभी Xon और XOFF कहा जाता है) के रूप में प्रसारित नहीं किया जा सकता: यहाँ कफ से कुछ है डेटा क्योंकि वे केबल के दूसरे छोर पर प्रेषक को शुरू करने और रोकने के लिए भेजे जाते हैं।

  • कुछ उपकरणों पर, एनयूएल और/या डीएल वर्ण (0x00 और 0x7F) रिसीवर के फीफो से गायब हो सकते हैं।

  • यदि रिसीवर यूनिक्स टीटीआई है, और टर्मियो मोड सही ढंग से सेट नहीं हैं, तो चरित्र Ctrl-D (EOT या 0x04) Tty ड्राइवर को प्रक्रिया के अंत-फ़ाइल को सिग्नल करने का कारण बन सकता है टीटी खुला है।

एक धारावाहिक कनेक्शन आमतौर पर बाइट चौड़ाई और एक समता बिट के संभावित शामिल करने के लिए विन्यास योग्य है। कुछ कनेक्शनों की आवश्यकता होगी कि 8-बिट बाइट की बजाय समानता वाले 7-बिट बाइट का उपयोग किया जाए। 5-बिट और 6-बिट बाइट्स के लिए कई धारावाहिक बंदरगाहों को कॉन्फ़िगर करने के लिए विरासत हार्डवेयर (गंभीरता से पुराना) कनेक्शन के लिए भी संभव है। यदि प्रति बाइट से 8-बिट उपलब्ध हैं, तो बाइनरी डेटा को संभालने के लिए एक और जटिल प्रोटोकॉल की आवश्यकता होती है।

ASCII85 7-बिट डेटा और नियंत्रण वर्णों पर प्रतिबंधों के आसपास काम करने के लिए एक लोकप्रिय तकनीक है। यह केवल 85 ध्यान से चुने गए ASCII चरित्र कोड का उपयोग करके बाइनरी डेटा को फिर से लिखने के लिए एक सम्मेलन है।

इसके अतिरिक्त, आपको निश्चित रूप से प्रेषक और रिसीवर के बीच बाइट ऑर्डर के बारे में चिंता करने की ज़रूरत है। आपको फ्लोटिंग पॉइंट प्रारूप के बारे में चिंता करने की भी आवश्यकता हो सकती है, क्योंकि प्रत्येक सिस्टम आईईईई -754 फ्लोटिंग पॉइंट का उपयोग नहीं करता है।

नीचे की रेखा यह है कि अक्सर एक शुद्ध ASCII प्रोटोकॉल चुनने का पर्याप्त उत्तर बेहतर जवाब होता है। इसका लाभ यह है कि इसे मानव द्वारा समझा जा सकता है, और धारावाहिक कनेक्शन के साथ मुद्दों के प्रति अधिक प्रतिरोधी है। जब तक आप फ़्लोटिंग पॉइंट डेटा के gobs भेज रहे हैं, तो कार्यान्वयन की आसानी से प्रतिनिधित्व की अक्षमता से अधिक हो सकता है।

जो कुछ आप स्वीकार करते हैं उसमें उदार रहें, और जो भी आप उत्सर्जित करते हैं उसके बारे में रूढ़िवादी हो।

0

शायद फ़्लोट से बाइट और बाइट को फ़्लोट में परिवर्तित करने का सबसे अच्छा तरीका है, -ममिद रेजा।

int breakDown(int index, unsigned char outbox[], float member) 
{ 
    unsigned long d = *(unsigned long *)&member; 

    outbox[index] = d & 0x00FF; 
    index++; 

    outbox[index] = (d & 0xFF00) >> 8; 
    index++; 

    outbox[index] = (d & 0xFF0000) >> 16; 
    index++; 

    outbox[index] = (d & 0xFF000000) >> 24; 
    index++; 
    return index; 
} 


float buildUp(int index, unsigned char outbox[]) 
{ 
    unsigned long d; 

    d = (outbox[index+3] << 24) | (outbox[index+2] << 16) 
    | (outbox[index+1] << 8) | (outbox[index]); 
    float member = *(float *)&d; 
    return member; 
} 

संबंध। `

0

संरचनाएं और संघ इस मुद्दे को हल करते हैं। संरचना से मेल खाने वाले बाइट आकार वाले संघ के साथ एक पैक की गई संरचना का उपयोग करें। पॉइंटर्स को संरचना और संघ (या संरचना में संघ जोड़ें) को ओवरलैप करें। स्ट्रीम भेजने के लिए Serial.write का उपयोग करें। अंत प्राप्त करने पर एक मिलान संरचना/संघ है। जब तक बाइट ऑर्डर किसी भी मुद्दे से मेल नहीं खाता है अन्यथा आप "सी" hto (s..l) फ़ंक्शंस का उपयोग करके अनपैक कर सकते हैं। विभिन्न संरचनाओं/संघों को डीकोड करने के लिए "हेडर" जानकारी जोड़ें।

संबंधित मुद्दे