आर्डिनो पर एक बार में 1 वर्ण के विपरीत मुझे पूरी स्ट्रिंग कैसे प्राप्त होगी?


11

मैंने इस वेबसाइट के निर्देशों का सफलतापूर्वक पालन किया:

http://www.doctormonk.com/2012/04/raspberry-pi-and-arduino.html

और मैं वेबसाइट को निर्दिष्ट करते हुए पीआई और मेरे अरुडिनो मेगा के बीच संचार प्राप्त करने में सक्षम था।

हालाँकि, एलईडी ब्लिंक की संख्या का प्रतिनिधित्व करने वाले पूर्णांक को भेजने के बजाय, मैं ASCII पाठ भेजना चाहता हूं जैसे:

"5 मीटर फॉरवर्ड", "टर्न लेफ्ट", "पी से अरडूइनो के लिए 10 मीटर बैकवर्ड" पर जाएँ।

मैंने निम्नलिखित कोड लिखा है:

char inData[64];
char inChar=-1;

void setup(){
   Serial.begin(9600);
   Serial.begin("Waiting for Raspberry Pi to send a signal...\n");
}


void loop(){
    byte numBytesAvailable= Serial.available();

    // if there is something to read
    if (numBytesAvailable > 0){
        // store everything into "inData"
        int i;
        for (i=0;i<numBytesAvailable;i++){
            inChar= Serial.read();
            inData[i] = inChar;
        }

        inData[i] = '\0';


        Serial.print("Arduino Received: ");
        Serial.println(inData);
    }
}

मैं अपने Arduino मेगा 2560 के लिए सफलतापूर्वक ऊपर कोड फ्लैश किया।

मैंने रास्पबेरी पाई पर अपने अजगर टर्मिनल पर स्विच किया और कंसोल में मैंने टाइप किया:

import serial
ser = serial.Serial('/dev/ttyACM1',9600)
ser.write("MOVE")

मेरे Arduino के सीरियल मॉनिटर पर जो प्रदर्शित होता है वह इस प्रकार है:

Arduino Received: M
Arduino Received: O
Arduino Received: V
Arduino Received: E

लेकिन मुझे क्या चाहिए:

Arduino Received: MOVE

InData बफर में सभी वर्ण प्राप्त करने के लिए मैं ऊपर का कोड कैसे बदलूं?


क्या आप वाकई अपना कोड सही तरीके से कॉपी कर चुके हैं? जिस तरह से मैं आपके कोड को देख रहा हूं, चाहे जो भी हो InData, लाइन "Arduino प्राप्त" केवल एक बार ही मुद्रित होगी। आपको लगता है कि यह सब आपके सेटअप () फ़ंक्शन में है?
NickHalden

आप सही हे। मैंने अब इसे ठीक कर दिया। लेकिन समस्या अभी भी बनी हुई है।
user1068636

जवाबों:


23

समस्या यह है कि Arduino इतनी तेज़ी से घूम रहा है, यह इसे निष्पादित करेगा if (numBytesAvailable > 0) धारावाहिक पोर्ट के माध्यम से आने वाले प्रत्येक चरित्र के बीच कई बार लाइन । इसलिए जैसे ही कोई पात्र आता है, वह इसे पकड़ लेता है, शून्य से एक तक लूप करता है, और एक एकल वर्ण को प्रिंट करता है।

आपको क्या करना चाहिए, अपने पायथन प्रोग्राम से प्रत्येक कमांड के बाद लाइन कैरेक्टर ('\ n') का अंत भेजें। फिर अपने Arduino कोड को प्रत्येक वर्ण को प्राप्त करता है और केवल संदेश पर ही कार्य करता है, क्योंकि यह अंत-पंक्ति वर्ण प्राप्त करता है।

इसलिए यदि आप अपना पायथन कोड बदलते हैं, तो पंक्ति वर्ण का अंत भेजें, जैसे:

import serial
ser = serial.Serial('/dev/ttyACM1',9600)
ser.write("MOVE\n")

फिर आपका Arduino कोड कुछ इस तरह हो सकता है:

// Buffer to store incoming commands from serial port
String inData;

void setup() {
    Serial.begin(9600);
    Serial.println("Waiting for Raspberry Pi to send a signal...\n");
}

void loop() {
    while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);

            inData = ""; // Clear recieved buffer
        }
    }
}

1
इसके अलावा, अधिक सामान्य उपयोगों के लिए इस पर एक संभावित मोड़ (जैसे सीधे सी में जहां आपके पास एक सुविधाजनक स्ट्रिंग वर्ग नहीं है) यह है कि आप बफर में क्या देख रहे हैं, यह देखने के लिए कि क्या आपने अभी तक एक \ n प्राप्त किया है। इस तरह से आप इसकी प्रतिलिपि बनाने से पहले हर चीज को आंतरिक बफर में रखते हैं। यहाँ कमी यह है कि आंतरिक बफर को आपको अपनी सबसे लंबी सिंगल लाइन पर कब्जा करने के लिए पर्याप्त होना चाहिए। अन्यथा, आप संभावित रूप से प्रसंस्करण की गति में लाभ प्राप्त करते हैं क्योंकि आप स्ट्रिंग (वर्तमान में, जैसे) से बचने और स्मृति का विस्तार करने के लिए खुद को विस्तारित करने के लिए आवंटित करते हैं।
टोबी लॉरेंस

आपका कोड काम कर गया! मुझे inData = "" और inData + = जैसी कुछ पंक्तियों को बदलना पड़ा। मुझे नहीं लगता कि संकलक को यह पसंद आया।
user1068636

6

आपका पायथॉन लिपि चार बाइट्स भेज रहा है, M, O, V, और E। Arduino को कैसे पता चलेगा कि यह एक स्ट्रिंग है? विचार करें कि पायथन कोड:

ser.write("MOVE")

के लिए पूरी तरह से समान है

ser.write("MO")
ser.write("VE")

Arduino के दृष्टिकोण से। सीरियल पोर्ट पात्रों को स्थानांतरित करते हैं, तार नहीं।

आपके कोड में, Arduino तेज है (9600 बॉड दर की तुलना में), इसलिए हर बार जब यह कॉल करता है Serial.available(), तो यह केवल उन चार वर्णों में से एक को देखता है। इसलिए आपको अपने द्वारा किया गया आउटपुट मिला।

आपको जो कुछ करने की आवश्यकता होगी, वह स्ट्रिंग के परिसीमन के कुछ तरीकों के साथ आएगा, अर्थात उन्हें पायथन से किसी तरह से चिह्नित करना ताकि Arduino व्यक्तिगत वर्णों को जोड़ सके जो इसे एक स्ट्रिंग के उच्च-स्तरीय अवधारणा में प्राप्त करता है ।

लाइनों का उपयोग करना सीधा है: एक नई लाइन वर्ण ( '\n') के साथ समाप्त किए गए प्रत्येक स्ट्रिंग को भेजें । Arduino पर, वर्ण पढ़ें और उन्हें अपने स्ट्रिंग में जोड़ें। जब आप एक देखते हैं '\n', स्ट्रिंग खत्म हो गई है और आप इसे प्रिंट कर सकते हैं।


नए वर्ण की प्रतीक्षा करने की तुलना में व्यक्तिगत पात्रों को एक स्ट्रिंग धीमे में जोड़ना नहीं है, और जब नया वर्ण प्राप्त होता है तो एक ही बार में पूरे वर्ण क्रम में पढ़ना।
विवान्डीयर

2
निश्चित नहीं है कि आप क्या प्रस्ताव कर रहे हैं - आप इसे पढ़कर छोड़कर किसी नए वर्ण के लिए "प्रतीक्षा" नहीं कर सकते, और जब तक आप इसे पढ़ते हैं, तब तक आप आवश्यक रूप से सभी पिछले वर्णों को पढ़ लेते हैं (जिसका अर्थ है कि उन्हें इसकी आवश्यकता है किसी तरह से बचा लिया गया है - चाहे वह "स्ट्रिंग के लिए जोड़ना" हो या उन्हें बचाने का कोई अन्य तरीका आपके ऊपर हो)।
जिम पेरिस

2
  if(Serial.available() > 0) {
     str = Serial.readStringUntil('\n');
     Serial.println(str);

उपरोक्त कोड Pi और Arduino के बीच मेरे संबंध पर सटीक काम करता है


1

के .readlineबजाय का उपयोग करें.read

मेरे पास एक ही मुद्दा था और इसने इसे ठीक कर दिया। उम्मीद है कि इस मदद की!


यह EE.SE पर एक उत्तर के लिए थोड़ा पतला है। विशेष रूप से यह देखते हुए कि यह 2 साल पुराना धागा है। कृपया विस्तार से बताएं।
निक एलेक्सीव

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

0

ऐसा मैंने पहले उदाहरण से किया है:

String readString;

void setup()
{
    Serial.begin(9600); // initialization
}

void loop()
{
    char incomingByte;
    while (Serial.available() > 0)
    {
        delay(10); // if the data came
        incomingByte = Serial.read(); // read byte
        //Serial.println(incomingByte);
        readString += incomingByte;
    }

    if(readString != "")
    {
        Serial.print("arduino recived this : ");
        Serial.println(readString);
    }
    readString = "";
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.