আরডুইনো সিরিয়াল মুদ্রণ প্রোগ্রামটির আচরণকে অনাকাঙ্ক্ষিতভাবে পরিবর্তন করে


10

আমি একটি লুপ কাউন্টার ব্যবহার করছি, একটি শিরোনামে ঘোষিত:

int loop_counter = 0;

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

void loop() {
    if(loop_counter > 100) loop_counter = 0;
    else loop_counter++;

    //Serial.println("hey");

    if(loop_counter == 0) {
         //do_something_important();
    }      
}

সমস্ত কিছু ভাল এবং ভাল, যতক্ষণ না আমি Serialসংঘাতের মাধ্যমে যোগাযোগের চেষ্টা করব //Serial.println("hey"); ( "hey"এই উদাহরণে কারণ, আমার কাছে, এই আচরণটি অযৌক্তিক)।

কোডের বিভাগটি loop_counterকখনই ট্রিগার না করে এর ফলস্বরূপ do_something_important();। আমি ঘোষণা চেষ্টা loop_counterহিসাবে volatile, যে কিছু পরিবর্তন হয়নি। আমি Serial.printআইএনজি চেষ্টা করেছিলাম loop_counter, এবং আমিও বিজোড় আচরণ পাচ্ছিলাম (এটি লুপটি স্থির করে দেবে)। Serial.println("hey");এই অর্থে কাজ করে যে সিরিয়াল মনিটরে আমি প্রচুর পরিমাণে "হে" পাই, (অর্থাত্ দ্রুত "100" এর চেয়ে অনেক বেশি "কোডের অন্যান্য বিভাগে পুনরাবৃত্তির সংখ্যা)

সম্পূর্ণরূপে সঠিকভাবে কাজ করা থেকে বাঁচতে Serialবাঁধা ডেটা (যতদূর আমি বলতে পারি) এর সাথে বাঁধা ডেটা দিয়ে কী সম্ভবত ব্যবহারের কারণ হতে পারে loop_counter?

সম্পাদনা : এখানে মূল ফাইলটির একটি অংশ যা সমস্যাটি প্রকাশ করে শেষ হয়েছে (ভাল, এতে সর্বাধিক অবদান রাখছে (অত্যধিক স্মৃতি ব্যবহার করে)):



void display_state() {
  int i,j,index=0;
  short alive[256][2];

 for(i=0;i<num_rows;i++) { 
   for(j=0;j<num_cols;j++) {
     if(led_matrix[i][j]==1) { 
       alive[index][0]=i;
       alive[index][1]=j;
       index++;
     }
   }
 }
 alive[index][0]=NULL; //Null-terminate.
 alive[index][1]=NULL;

 //383 is a great number
 for(int idx=0;idx < index; idx++) {
   display(alive[idx][0],alive[idx][1]);
   delayMicroseconds(283);
 }
}

এখানে "letter.h" রয়েছে:


    #ifndef _MY_LETTERS_H
    #define _MY_LETTERS_H

#define nrows 4
#define ncols 4

#define num_rows 16
#define num_cols 16

#define MAX_WORD_LENGTH 16
#define NUMBER_OF_CHARACTERS 26

#include <stdlib.h>

int লুপ_কাউন্টার = 0 ; সংক্ষিপ্ত নেতৃত্বাধীন_ম্যাট্রিক্স [ num_rows ] [ num_col ];

const সংক্ষিপ্ত letter_a [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 0 }, { 1 , 0 , 0 , 1 }, { 1 , 1 , 1 , 1 }, { 1 , 0 , 0 , 1 } }; const সংক্ষিপ্ত letter_b [ nrows ] [ ncols ] = {{ 1 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 }, { 1 , 0 , 1 , 0 }, { 1 , 1 , 1 , 0 }}; const সংক্ষিপ্ত letter_c [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 1 }, { 1 , 0 , 0 , 0 }, { 1 , 0 , 0 , 0 }, { 0 , 1 , 1 , 1 }}; const সংক্ষিপ্ত letter_t [ nrows ] [ ncols ] = {{ 1 , 1 , 1 , 1 }, { 0 , 1 , 0 , 0 }, { 0 , 1 , 0 , 0 }, { 0 , 1 , 0 , 0 } };

মধ্যে typedef struct হয় letter_node { const সংক্ষিপ্ত * ডেটা ; চিঠি_নোড * পরবর্তী ; ইন্ট এক্স ; int y ; } চিঠি_নোড ;

চিঠি_নোড আ = {& চিঠি_এ [ 0 ] [ 0 ], নুল , 1 , 1 }; লেটার_নোড বিবি = {& লেটার_বি [ 0 ] [ 0 ], নুল , 1 , 1 }; লেটার_নোড সিসি = {এবং লেটার_সি [0][0],NULL,1,1}; letter_node tt = {&letter_t[0][0], নুল , 1 , 1 };

চিঠি_নোড লেটার_ম্যাপ [ NUMBER_OF_CHARACTERS ]; #শেষ যদি

আরও কিছু তথ্য: - আমি একটি ইউনো (এটিএমটিগা 328) ব্যবহার করছি


আপনার স্ট্যাকের আকার কত? এমন কোনও সুযোগ রয়েছে যে আপনি নিজের স্ট্যাকটি আঁকতে পারেন এবং দেখতে পারেন এটি দুর্নীতিগ্রস্থ হচ্ছে কিনা। সিরিয়াল মুদ্রণটি কি বাধা ব্যবহার করে, আপনার কোডটি প্রেরণকারী?
কেটিসি

সিরিয়াল মুদ্রণটি কোনও বিঘ্ন দ্বারা ট্রিগার করা হয়নি, আমি এটি কেবল loop()ফাংশনে ব্যবহার করছি । যদি আমার একমাত্র আউটপুট পদ্ধতি ( Serial.print()) আমাকে ব্যর্থ করে তবে আমার স্ট্যাকটি কীভাবে আঁকতে হবে?
ইকজেক্স

2
আপাতদৃষ্টিতে তুচ্ছ পরিবর্তনগুলির সম্ভাব্য ভুল এবং ভুল বোঝাবুঝি পার্শ্ব প্রতিক্রিয়াগুলি দূর করতে, দয়া করে আপনার প্রশ্নের কোডটি একটি আক্ষরিক, চরিত্র-সঠিক কপি দিয়ে স্কেচটির পরিবর্তিত করুন, যাতে সমস্যাটি ট্রিগার করার জন্য প্রয়োজনীয় সর্বনিম্ন প্রয়োজন হয় । "এটি আমার প্রোগ্রাম যা আমি ব্যর্থ হলে .." নয় তবে সর্বনিম্ন প্রোগ্রামটি যা এইভাবে ব্যর্থ হয়।
ক্রিস স্ট্রাটন

উত্তর:


2

আমারও এর সাথে একই রকম সমস্যা ছিল এবং আমি নিশ্চিত যে আপনারও স্ট্যাকের সাথে সম্পর্কিত স্থানের বাইরে। কোডটি যতটা সম্ভব সঙ্কুচিত করার চেষ্টা করুন।

আমার ক্ষেত্রে কোডটি মাঝে মধ্যে চলত যখন আমার এটিতে একটি সিরিয়াল বার্তা ছিল, তবে তখন মনে হবে এটি যখন আমি না করি তখন চলবে না। আমার এমন একটি মামলাও ছিল যেখানে সিরিয়াল বার্তা প্রেরণের ফলে আরডুইনো অবিরাম পুনরায় সেট হয়ে যায়।

আমি একটি আরডুইনো 328ও ব্যবহার করছিলাম। আপনার যদি স্বল্প আকারে গ্রহণযোগ্য হয় তবে আপনার অ্যারের আকার হ্রাস করা উচিত।


আপনাকে ধন্যবাদ, আপনি এবং ডেভ ট্যুইড পেয়েছেন। আমি অতিরিক্ত অতিরিক্ত বরাদ্দ প্রয়োজন হয় না জন্য প্রদর্শন_স্টেট () ফাংশন রিফেক্টর। আমি খুব কমই এম্বেড প্রসেসিং করি, আমি মনে করি আমাদের সকলকে কোনও কোনও মুহুর্তে স্মৃতি প্রাচীরে আঘাত করতে হবে!
ইকজেক্স

হ্যালো, আমারও একই অবস্থা। আমি অ্যারের আকার 128 থেকে 96 এ পরিবর্তন করছি এবং আমার প্রোগ্রামটি ঠিকঠাক কাজ করে। তবে আমি মনে করি এই সমস্যাটি সত্যই ডিবাগের সন্ধান ছাড়াই, কারণ আমার অ্যারের আকারটি ঘোষিত স্ট্যাকের আকারের চেয়ে ছোট। আপনি কি জানেন যে এই ধরণের সমস্যা মোকাবেলায় আমি কোথায় তথ্য পেতে পারি?
সিংহ লাই

4

আপনার কোডটি কি সিরিয়াল বন্দরটির সূচনা করে? যেমন।

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

এটি করতে ব্যর্থ হওয়ার ফলে সিরিয়ালটির প্রথম ব্যবহারে ক্রাশ হতে পারে।


হ্যাঁ, আমি এটা আছে।
ইকজ্যাক্স

3

আপনি কি স্মৃতিশক্তি হারিয়েছেন? সিরিয়াল.প্রিন্ট ("কিছু") দিয়ে আপনি মুদ্রিত সমস্ত স্ট্রিংগুলি এসআরএমে স্থান নেয়, string 0 টার্মিনেটরের জন্য স্ট্রিং + 1 এর অক্ষরের সংখ্যার সমান। আপনার স্কেচের সংকলিত আকারটি আরডিনো ফ্ল্যাশ মেমরির চেয়ে অনেক ছোট হলেও মেমরির বাইরে চলে যাওয়া সম্ভব, কারণ এসআরএমে আতমেগা 328 এর জন্য কেবল 2048 বাইট এবং আতমেগা 168 এর জন্য 1024 বাইট রয়েছে I আমারও একই সমস্যা ছিল, যা আমি সমস্ত সংক্ষিপ্ত করে সমাধান করেছি পাঠ্য এবং অপ্রয়োজনীয় ডিবাগ বার্তা অপসারণ।


হুম। আমার শিরোনামে আমার বেশ কয়েকটি বহুমাত্রিক অ্যারে ঘোষিত হয়েছে, সম্ভবত এটিই সমস্যা? সেগুলি কি এসআরএমে সংরক্ষণ করা হয়েছে?
ইকজএক্স

1
@ nrhine1: যে ক্ষেত্রে, আপনি সম্ভবত আপনার সমগ্র স্কেচ, শুধু অংশ যেখানে দেখানো উচিত আপনি মনে মিথ্যা সমস্যা।
ডেভ টুইট করেছেন

@ ডেভটুইড হ্যাঁ, করবে।
ইকজএক্স

1
আমি লক্ষ্য করেছি যে আপনি নিজের শিরোনামের ফাইলটিতে প্রচুর স্টোরেজ সংজ্ঞায়িত করছেন, কেবল এটি সেখানে ঘোষণা করার পরিবর্তে (যদি আপনি এই পার্থক্যটি বুঝতে না পারেন )। এটি কোনও সি প্রোগ্রামে অস্বাভাবিক হবে; এটি কি আরডুইনোতে স্বাভাবিক অনুশীলন? আপনি এই কাঠামোর একাধিক অনুলিপিগুলি সহ শেষ করতে পারেন। এছাড়াও, আপনি কিছু খুব বড় স্বয়ংক্রিয় ভেরিয়েবলগুলি সংজ্ঞায়িত করছেন, যেমন প্রদর্শন_স্টেট () এ "জীবিত" অ্যারে, যার জন্য স্ট্যাক স্পেসের 1024 বাইটের বেশি প্রয়োজন। আমি নিশ্চিত যে আপনি কেবল স্মৃতিশক্তি হারিয়েছেন।
ডেভ টুইট করেছেন

@ ডেভিডওয়েদ আপনাকে ধন্যবাদ, আপনি এবং রেজা পেয়েছেন। display_state()অতিরিক্ত বরাদ্দের প্রয়োজন না হওয়ার জন্য আমি ফাংশনটি রিফেক্টর করেছি । আমি খুব কমই এম্বেড প্রসেসিং করি, আমি মনে করি আমাদের সকলকে কোনও কোনও মুহুর্তে স্মৃতি প্রাচীরে আঘাত করতে হবে!
ইকজেক্স

1

আপনি কোডটি দেখান নি যা ভেরিয়েবল "লুপ_কাউন্টার" আরম্ভ করে। এটি কি লুপের () রুটিনের বাইরে ?

আপনি কি সম্ভবত এমনভাবে ঘোষণা করেছেন যে এটি অন্য মেমরি স্টোরেজ এরিয়ার সংলগ্ন যা এর ঘোষিত আকারের বাইরে কাজ করছে এবং এই লুপ_কাউন্টার ভেরিয়েবলের উপর ট্রাম্পিং করবে?


আমি এটি বিভিন্নভাবে বিভিন্ন জায়গায়, বিভিন্ন জায়গায় ঘোষণা করার চেষ্টা করেছি। শীর্ষে, ঠিক উপরে loop(), ইত্যাদি। আপনি কি বলছেন যে Serial.print()পদ্ধতিটি কোনওভাবে এটি ওভাররাইট করা হতে পারে?
ইকজএক্স

পূর্ববর্তী মন্তব্যে আমি যা বোঝাতে চেয়েছি তা হল আমি প্রায় ইতিবাচক যে সিরিয়াল.প্রিন্ট () এর অস্তিত্বের জন্য আমি 'খারাপ' আচরণকে বিচ্ছিন্ন করে দিয়েছি। যখন এটি সেখানে নেই, জিনিসগুলি ভাল কাজ করে।
ইকজএক্স

@ nrbine1 - আমার কাছে মনে হচ্ছে যে আপনার গ্লোবাল ভেরিয়েবল ভেরিয়েবল "লুপ_কাউন্টার" সিরিয়াল.প্রিন্ট () পদ্ধতি অনুসারে আমার উত্তরটিতে পরামর্শ দেওয়ার মতো পদক্ষেপ নিয়ে চলেছে। পোসিপাইটের উত্তরে আপনাকে জিজ্ঞাসা করা হয়েছিল যে সিরিয়াল অবজেক্টটি সঠিকভাবে শুরু করা হয়েছে কিনা। যদি এটি না করা হয়ে থাকে তবে এটি আপনার কাউন্টারে "ট্রাম্পিং" ব্যাখ্যা করতে পারে কারণ এটি সিরিয়াল.প্রিন্ট () সঠিকভাবে বরাদ্দ না করা এবং সেটআপ না করা একটি বাফার ব্যবহারের চেষ্টা করে।
মাইকেল কারাস

আমি আমার উত্স সমস্ত যোগ করেছি।
eqzx

1

আপনি কোথায় ফোন করছেন আমি আপনার কোডটিতে দেখতে পাচ্ছি না loop()। আপনি loop_counterএই ফাংশনের বাইরে ব্যবহার করছেন এমনটিও মনে হচ্ছে না । আপনি এটিকে বিশ্বব্যাপী ঘোষণা করার কোনও কারণ আছে? আমি ধরে নিচ্ছি কারণ এটি আপনি কলগুলির মধ্যে এর মান ধরে রাখতে চান। আপনি এটি স্থিতিশীল স্থানীয় ভেরিয়েবলের পরিবর্তে এটি করতে পারেন।

void loop() {
    static int loop_counter = 0;

    if(loop_counter > 100)
    {
        loop_counter = 0;
    }
    else
    {
        loop_counter++;
    }

    Serial.println("hey");

    if(loop_counter == 0)
    {
         //do_something_important();
    }      
}

এটি নিশ্চিত হওয়া উচিত যে অন্য কোনও বাহ্যিক ক্রিয়া এতে স্টম্প না করতে পারে। অযাচিত আচরণ এড়াতে আপনার সর্বদা আপনার ক্ষুদ্রতর স্কোলে আপনার পরিবর্তনশীলগুলি ঘোষণা করা উচিত।

যদি এটি কাজ না করে, আপনার সত্যিকার অর্থে আপনার স্মৃতি ব্যবহার বিশ্লেষণ করতে হবে। একটি আরডুইনোর মধ্যে এটি করতে বিভিন্ন নমুনা কোডের জন্য এই EE.SE প্রশ্নোত্তর পরীক্ষা করে দেখুন ।


আমি ইতিমধ্যে এটি স্থির করার চেষ্টা করেছি। এটি কোনও উপকারে আসেনি। এটি একটি পৃথক পুনরাবৃত্তি। setup()এবং loop()ফাংশনগুলি যা আরডুইনো ডিফল্টরূপে চালিত হয়, setup()প্রথম, loop()দ্বিতীয়। loop()মূলত main()এটির মতো , এটি বারবার বলা ছাড়া। রেফারেন্স: arduino.cc/en/References/loop আমি সেই লিঙ্কটি চেক করব।
eqzx

আবার, আমি অন্যান্য মন্তব্যে যেমন উল্লেখ করেছি, আমি ডিবাগ করতে পারি না Serial.print()। দেখে মনে হচ্ছে আমি সাধারণ processingIDE এর বাইরে থাকতে চাই যদি আমি জিডিবি ব্যবহার করতে সক্ষম হতে চাই
eqzx

@ nrhine1 আপনি বলেছেন যে এটি Serial.print()খুব ভাল কাজ করছে যে এটি "আরে" প্রচুর মুদ্রণ করছিল। এটি loop_counterআপনাকে একটি সমস্যা দিচ্ছে। if(loop_counter == 0)কোডটি সরিয়ে এবং কোডটি রাখার চেষ্টা করুন get_free_memory()( loop_counterবর্ধিতত্বটি ছেড়ে দিন ) এবং এটিকে চালিয়ে যান। আপনার মেমরি বরাদ্দে আপনার কোনও বড় সমস্যা আছে কিনা তা এটি কমপক্ষে আপনাকে জানায়।
embedded.kyle

1

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


0

কিছু সময় আগে আমি একই সমস্যা থাকার ছাপ ছিল। এরপরে, আমি সামনে বা সিরিয়াল পরে একটি বিলম্ব (1) যোগ করে এটি সমাধান করেছি pr এটি ছিল লিনাক্সে আরডুইনো 0022 এর সাথে। এটি কোন বোর্ড ছিল তা নিশ্চিত নয়, সম্ভবত একটি বোর্ডুইনো সিরিয়াল। এটি পুনরুত্পাদনও করতে পারেন।

বর্তমানে, এটি উইন্ডোজটিতে আরডুইনো 1.01 সহ একটি বোর্ডুইনো ইউএসবিতে আমার জন্য কাজ করে:

int loop_counter = 0;
int led = 13;

void setup() {
  Serial.begin(9600);
  pinMode(led, OUTPUT);}

void loop() {
    if(loop_counter > 100) {
      loop_counter = 0;
    }
    else {
      loop_counter++;
    }

    Serial.println(loop_counter);

    if(loop_counter == 0) {
      Serial.println("hey hey orange, hey hey!");
    }      
}

পরামর্শের জন্য ধন্যবাদ. দুর্ভাগ্যক্রমে এটি সমস্যার সমাধান করেনি।
eqzx
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.