আরডুইনোতে একবারে 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);
    }
}

আমি আমার আরডুইনো মেগা 2560 তে সফলতার সাথে কোডের উপরে ফ্ল্যাশ করেছি।

আমি আমার অজগর টার্মিনালটিতে রাস্পবেরি পাই এবং যে কনসোলে টাইপ করেছি তা স্যুইচ করেছি:

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

আমার আরডুইনোর সিরিয়াল মনিটরে যা প্রদর্শিত হবে তা নিম্নরূপ:

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

তবে আমি যা চাই তা হ'ল:

Arduino Received: MOVE

ইনটাটা বাফারে সমস্ত অক্ষর পেতে আমি কীভাবে উপরের কোডটি পরিবর্তন করব?


আপনি কি নিশ্চিত আপনার কোডটি সঠিকভাবে অনুলিপি করেছেন? আপনার কোডটি আমি যেভাবে দেখছি, ইন ডেটায় যা আছে তা বিবেচনা না করেই "আরডুইনো রিসিভড" লাইনটি কেবল একবারই মুদ্রিত হবে। আপনি কি নিশ্চিত যে এটি আপনার সেটআপ () ফাংশনে রয়েছে?
নিকহ্যালডেন

তুমি ঠিক বলছো. আমি এখন এটি স্থির। তবে সমস্যা এখনও রয়ে গেছে।
ব্যবহারকারী 1068636

উত্তর:


23

সমস্যাটি হচ্ছে যে আরডুইনো এত দ্রুত ঘুরে বেড়াচ্ছে, এটি if (numBytesAvailable > 0)সিরিয়াল বন্দর দিয়ে আগত প্রতিটি চরিত্রের মধ্যে কয়েকবার লাইনটি কার্যকর করবে । সুতরাং কোনও চরিত্র আসার সাথে সাথেই এটি এটিকে ধরে ফেলবে, শূন্য থেকে একের মধ্যে লুপ করে এবং একটি একক অক্ষর ছাপিয়ে দেয়।

আপনাকে যা করা উচিত তা হ'ল আপনার পাইথন প্রোগ্রাম থেকে প্রতিটি কমান্ডের পরে লাইন চরিত্রের একটি সমাপ্তি ('\ n') প্রেরণ করা। তারপরে আপনার আরডুইনো কোড বাফারটি প্রতিটি অক্ষর গ্রহণ করে এবং বার্তাটি শেষ হওয়ার পরে একবারে অক্ষরটি গ্রহণ করে কেবল তারই জন্য কাজ করে।

সুতরাং আপনি যদি নিজের পাইথন কোড পরিবর্তন করেন তবে লাইন চরিত্রের একটি সমাপ্তি প্রেরণ করুন:

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

তাহলে আপনার আরডুইনো কোডটি এরকম কিছু হতে পারে:

// 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
এছাড়াও, আরও জেনেরিক ব্যবহারের জন্য এটির জন্য একটি সম্ভাব্য মোড় (যেমন স্ট্রেস আপ সি যেখানে আপনার কাছে স্ট্রিং ক্লাসের সুবিধা নেই) আপনি বাফারে কী আছে তা দেখার জন্য আপনি এখনও কোনও received n পেয়েছেন কিনা তা দেখুন। আপনি এর অনুলিপি তৈরি করার আগে এইভাবে আপনি অভ্যন্তরীণ বাফারে সবকিছু রাখেন। এখানে পতনটি হ'ল অভ্যন্তরীণ বাফারটি আপনাকে আপনার দীর্ঘতম একক লাইন ক্যাপচার করার জন্য যথেষ্ট বড় হতে হবে। অন্যথায়, আপনি স্ট্রিংয়ের মতো পছন্দগুলি এড়িয়ে চলার কারণে সম্ভাব্যভাবে প্রক্রিয়াজাতকরণের গতি অর্জন করতে পারবেন (সম্ভবত: এটি) পুনঃনির্মাণ এবং মেমরিকে বরাদ্দ করার জন্য নিজেকে প্রসারিত করতে।
টবি লরেন্স

আপনার কোড কাজ করেছে! আমাকে ডেটা = "" এবং ইনডাটা + = প্রাপ্তের মতো কয়েকটি লাইন পরিবর্তন করতে হয়েছিল। আমি মনে করি না যে সংকলকটি এটি পছন্দ করেছে।
ব্যবহারকারী 1068636

6

তোমার পাইথন স্ক্রিপ্ট চার বাইট পাঠাচ্ছে, M, O, V, এবং E। আরডুইনো কীভাবে জানতে পারে যে এটি একটি একক স্ট্রিং? পাইথন কোডটি বিবেচনা করুন:

ser.write("MOVE")

হয় সম্পূর্ণরূপে অভিন্ন করার

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

আরডুইনোর দৃষ্টিকোণ থেকে সিরিয়াল পোর্টগুলি স্থানান্তর অক্ষর, স্ট্রিং নয়।

আপনার কোডে, আরডুইনো দ্রুত (9600 বাউড হারের তুলনায়) দ্রুত, সুতরাং যতবার এটি কল করে Serial.available(), কেবলমাত্র এই চারটি অক্ষরের মধ্যে একটি দেখতে পাবে। এজন্য আপনি যে আউটপুট করেছিলেন তা পেয়েছেন।

আপনাকে যা করতে হবে তা হ'ল কিছু সীমানার স্ট্রিংয়ের উপায় নিয়ে আসে, অর্থ্যাৎ পাইথন থেকে কোনওভাবে এগুলিকে চিহ্নিত করা যাতে আরডুইনো পৃথক অক্ষরগুলিকে যুক্ত করতে পারে যা এটি আপনার স্ট্রিংয়ের উচ্চ-স্তরের ধারণায় আসে ।

লাইনগুলি ব্যবহার করা সহজবোধ্য: প্রতিটি স্ট্রিংকে একটি নতুন লাইনের অক্ষর ( '\n') দিয়ে শেষ করুন send আরডুইনোগুলিতে, অক্ষরগুলি পড়ুন এবং সেগুলি আপনার স্ট্রিংয়ে যুক্ত করুন। আপনি যখন একটি দেখেন '\n', স্ট্রিংটি শেষ হয়ে যায় এবং আপনি এটি মুদ্রণ করতে পারেন।


কেবলমাত্র নতুন লাইন চরিত্রের জন্য অপেক্ষা করা এবং নতুন লাইনের চরিত্রটি প্রাপ্ত হওয়ার পরে পুরো অক্ষর ক্রমটি একবারে পড়ার চেয়ে ধীরে ধীরে স্বতন্ত্র অক্ষরগুলিকে যুক্ত করা হচ্ছে না।
ভিভান্দিয়ারের

2
আপনি কী প্রস্তাব করছেন তা নিশ্চিত নন - আপনি কোনও নতুন লাইন চরিত্রটি পড়া না করে "অপেক্ষা" করতে পারবেন না, এবং আপনি যখন এটি পড়েছেন তখন অগত্যা পূর্ববর্তী সমস্ত অক্ষরগুলিও পড়তে হবে (যার অর্থ তাদের প্রয়োজন কোনও উপায়ে সংরক্ষণ করা হয়েছে - তা "স্ট্রিংয়ের সাথে সংযুক্তি" বা সেগুলি সংরক্ষণের কোনও অন্য পদ্ধতি আপনার উপর নির্ভর করে)।
জিম প্যারিস

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

উপরের কোডটি পাই এবং আরডুইনোর মধ্যে আমার সংযোগে নিখুঁতভাবে কাজ করে


1

.readlineপরিবর্তে ব্যবহার করুন.read

আমার একই সমস্যা ছিল এবং এটি এই মুহুর্তে এটি ঠিক করে দিয়েছে। আশা করি এটি সাহায্য করেছে!


EE.SE এ উত্তরের জন্য এটি কিছুটা পাতলা is বিশেষত বিবেচনা করুন যে এটি 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 = "";
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.