Arduino सीरियल प्रिंट कार्यक्रम के व्यवहार को अवांछनीय रूप से बदलता है


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();
    }      
}

सभी अच्छी तरह से और अच्छा है, जब तक मैं साथ संवाद स्थापित करने की कोशिश Serialuncommenting द्वारा //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);
 }
}

यहाँ "अक्षर" है:


    #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 loop_counter = 0 ; लघु led_matrix [ num_rows ] [ num_cols ];

const short letter_a [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 0 }, { 1 , 0 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 }, { 1 , 0 , 1 , 0 }, { 1 0 , 0 , 0 }, { 0 , 1 , 1 , 0 , 1 }, { 1 , 1 , 1 , 1 }, { 1 , 0 , 0 , 1 } }; const short letter_b [ nrows ] [ ncol ] = {{ 1 , , 1 , 1 , 0 }}; स्थिरांक कम letter_c [ nrows ] [ ncols ] = {{ 0 , 1 , 1 , 1 } { 1 , 0 , 0 , 0 } { 1 , 1 }}; const short letter_t [ nrows ] [ ncols ] = {{ 1 , 1 , 1 , 1 } { 0 , 1 , 0 , 0 } { 0 , 1 , 0 , 0 } { 0 , 1 , 0 , 0 } };

typedef struct letter_node { स्थिरांक कम * डेटा ; letter_node * अगला ; इंट x ; इंट वाई ; } पत्र_नोड ;

letter_node aa = {& letter_a [ 0 ] [ 0 ], NULL , 1 , 1 }; letter_node bb = {& letter_b[0][0],NULL,1,1}; letter_node cc = {&letter_c[0][0],NULL,1,1}; letter_node tt = {&letter_t[0][0], NULL , 1 , 1 };

letter_node letter_map [ NUMBER_OF_CHARACTERS ]; #अगर अंत

कुछ और जानकारी: - मैं एक यूनो का उपयोग कर रहा हूं (ATMega328)


आपका स्टैक आकार क्या है? क्या कोई मौका है कि आप अपने स्टैक को पेंट कर सकते हैं और देख सकते हैं कि क्या यह दूषित हो रहा है। क्या सीरियल प्रिंट में रुकावट आती है, क्या आपका कोड रीइंटरेंट है?
Ktc

सीरियल प्रिंट किसी भी व्यवधान से शुरू नहीं हुआ है, मैं इसे केवल loop()फ़ंक्शन में उपयोग कर रहा हूं । अगर मेरे पास आउटपुट का एकमात्र तरीका है ( Serial.print()) मुझे फेल कर रहा है तो मुझे अपना स्टैक कैसे पेंट करना चाहिए ?
15:25 बजे eqzx

2
प्रतीत होने वाले तुच्छ परिवर्तनों के संभावित गलतियों और गलतफहमी के दुष्प्रभावों को खत्म करने के लिए, कृपया अपने प्रश्न में कोड को समस्या को ट्रिगर करने के लिए आवश्यक न्यूनतम स्केच की एक शाब्दिक, वर्ण-सटीक प्रतिलिपि के साथ बदलें । नहीं "यह मेरा कार्यक्रम है जो विफल हो जाता है अगर मैं .." लेकिन बिल्कुल न्यूनतम कार्यक्रम जो इस तरह से विफल हो जाता है।
क्रिस स्ट्रैटन

जवाबों:


2

मुझे भी इसी तरह की समस्या थी, और मुझे पूरा यकीन है कि आपका भी स्टैक स्पेस से संबंधित है। जितना संभव हो कोड को सिकोड़ने का प्रयास करें।

मेरे मामले में कोड कभी-कभी तब चलता है जब मुझे इसमें एक धारावाहिक संदेश आता है, लेकिन तब ऐसा लगता है कि जब मैं नहीं चलाऊंगा तो यह नहीं चलेगा। मेरे पास एक मामला भी था जहां धारावाहिक संदेश भेजने से arduino अंतहीन रूप से रीसेट हो जाएगा।

मैं भी एक arduino328 का उपयोग कर रहा था। यदि आपके पास स्वीकार्य कोई छोटा आकार है, तो संभवतः आपको अपने सरणी का आकार कम करना चाहिए।


धन्यवाद, आपको और डेव ट्वीड को मिला। मैंने प्रदर्शन_स्टैट () फ़ंक्शन को अतिरिक्त आवंटन की आवश्यकता नहीं होने के लिए वापस ले लिया। मैं शायद ही कभी एम्बेडेड प्रसंस्करण करता हूं, मुझे लगता है कि हम सभी को किसी न किसी बिंदु पर मेमोरी वॉल को हिट करना होगा!
1

नमस्कार, मेरी भी ऐसी ही स्थिति है। मैं सरणी का आकार 128 से 96 तक बदलता हूं और मेरा कार्यक्रम ठीक काम करता है। लेकिन मुझे लगता है कि यह समस्या वास्तव में डीबग करने के लिए ट्रेस से बाहर है, क्योंकि मेरे सरणी का आकार घोषित स्टैक आकार से छोटा है। क्या आप जानते हैं कि इस तरह की समस्या से निपटने के लिए मुझे कहां से जानकारी मिल सकती है?
सिंह लाई

4

क्या आपका कोड सीरियल पोर्ट को इनिशियलाइज़ करता है? उदाहरण के लिए।

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

ऐसा करने में विफल होने के कारण सीरियल के पहले उपयोग पर दुर्घटना हो सकती है।


हां, मेरे पास वह है।
eqzx 14

3

शायद आप स्मृति से बाहर चल रहे हैं? सभी स्ट्रिंग जो आप Serial.print ("कुछ") के साथ प्रिंट करते हैं, SRAM में होते हैं, जो उस स्ट्रिंग के पात्रों की संख्या के बराबर होता है + 1 टर्मिनेटर के लिए। यदि आपके स्केच का संकलित आकार Arduino फ़्लैश मेमोरी से बहुत छोटा है, तो भी मेमोरी से बाहर भागना संभव है, क्योंकि SRAM Atmega328 के लिए केवल 2048 बाइट्स और Atmega 168 के लिए 1024 बाइट्स हैं। मेरे पास एक समान समस्या थी, जिसे मैंने सभी को छोटा करके हल किया था ग्रंथों और अनावश्यक डिबग संदेशों को हटाना।


हम्म। मेरे हेडर में कई बहुआयामी सरणियाँ घोषित हैं, शायद यही समस्या है? क्या वे SRAM में संग्रहीत हैं?
eqzx

1
@ nrhine1: उस स्थिति में, आपको शायद हमें अपना पूरा स्केच दिखाना चाहिए, न कि केवल उन हिस्सों पर जहाँ आपको लगता है कि समस्या है।
डेव ट्वीड

@DaveTweed हां, करेंगे।
eqzx

1
मुझे लगता है कि आप अपनी हेडर फ़ाइल में बहुत सारे स्टोरेज को परिभाषित कर रहे हैं, बजाय इसे वहां घोषित करने के (यदि आप इस पेज को देखते हुए अंतर को नहीं समझते हैं )। यह एक सी कार्यक्रम में असामान्य होगा; क्या यह Arduino पर सामान्य अभ्यास है? आप इन संरचनाओं की कई प्रतियों के साथ समाप्त हो सकते हैं। इसके अलावा, आप कुछ बहुत बड़े स्वचालित चर को परिभाषित कर रहे हैं, जैसे कि डिस्प्ले_स्टेट () में "जीवित" सरणी, जिसे स्टैक स्थान के 1024 बाइट्स की आवश्यकता होती है। मुझे पूरा यकीन है कि आप बस स्मृति से बाहर चल रहे हैं।
डेव ट्वीड

@DaveTweed धन्यवाद, आपको और रेजा को मिला। मैंने display_state()उस अतिरिक्त आबंटन की आवश्यकता नहीं होने के लिए समारोह को रद्द कर दिया । मैं शायद ही कभी एम्बेडेड प्रसंस्करण करता हूं, मुझे लगता है कि हम सभी को किसी न किसी बिंदु पर मेमोरी वॉल को हिट करना होगा!
1

1

आपने वह कोड नहीं दिखाया है जो चर "loop_counter" को आरंभ करता है। क्या वह पाश () दिनचर्या से बाहर है?

क्या आपने संभवतः इस तरह से घोषित किया है कि यह एक अन्य मेमोरी स्टोरेज एरिया से सटा हुआ है जो अपने घोषित आकार से बाहर काम कर रहा है और यह लूप_काउंटर चर पर ट्रॉमपिंग है?


मैंने इसे कई अलग-अलग तरीकों से, कई अलग-अलग जगहों पर घोषित करने की कोशिश की है। हेडर में, ठीक ऊपर loop(), आदि। क्या आप कह रहे हैं कि यह Serial.print()विधि किसी भी तरह से लिखी जा सकती है?
eqzx

पिछली टिप्पणी से मेरा तात्पर्य यह है कि मैं लगभग सकारात्मक हूं कि मैंने 'खराब' व्यवहार को सीरीयल प्रिंट () के अस्तित्व के लिए अलग कर दिया है। जब यह नहीं होता है, तो चीजें ठीक होती हैं।
eqzx

@ nrbine1 - यह मुझे लगता है कि आपके वैश्विक वैरिएबल "लूप_काउंटर" को Serial.print () विधि द्वारा आगे बढ़ाया जा रहा है, जैसा कि मैंने अपने उत्तर में सुझाया था। पॉज़िटि के उत्तर में आपसे पूछा गया है कि क्या सीरियल ऑब्जेक्ट को ठीक से इनिशियलाइज़ किया गया है। यदि ऐसा नहीं किया गया है तो यह आपके काउंटर पर "ट्रॉम्पिंग" की व्याख्या कर सकता है क्योंकि यह Serial.print () एक बफर का उपयोग करने का प्रयास करता है जिसे ठीक से आवंटित और सेटअप नहीं किया गया है।
माइकल करास

मैंने अपने सभी स्रोत जोड़े हैं।
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();
    }      
}

यह सुनिश्चित करना चाहिए कि कोई अन्य बाहरी कार्य उस पर दबाव न बना सके। अवांछित व्यवहार से बचने के लिए आपको हमेशा अपने चर को सबसे छोटे दायरे में घोषित करना चाहिए।

यदि वह काम नहीं करता है, तो आपको वास्तव में अपने मेमोरी उपयोग का विश्लेषण करने की आवश्यकता होगी। एक Arduino के भीतर यह करने के लिए विभिन्न नमूना कोड के लिए इस EE.SE Q & A की जाँच करें


मैंने इसे पहले से ही स्थिर बनाने की कोशिश की। इससे कोई फायदा नहीं हुआ। यह एक अलग पुनरावृत्ति है। setup()और loop()ऐसे कार्य हैं जो अर्डिनो डिफ़ॉल्ट रूप से चलता है, setup()पहला, loop()दूसरा। loop()अनिवार्य रूप से पसंद है main(), सिवाय इसके कि इसे बार-बार कहा जाता है। संदर्भ: arduino.cc/en/Reference/loop मैं उस लिंक को देखूंगा
eqzx

फिर से, जैसा कि मैंने अन्य टिप्पणियों में उल्लेख किया है, मैं साथ डिबग नहीं कर सकता Serial.print()। ऐसा लगता है कि मुझे सामान्य processingIDE के बाहर होना होगा अगर मैं GDB का उपयोग करने में सक्षम होना चाहता हूं
eqzx

@ nrhine1 आपने कहा Serial.print()था कि यह ठीक काम कर रहा था कि यह "हे" को बहुत प्रिंट कर रहा था। यह है loop_counterकि आप एक समस्या दे रहा है। if(loop_counter == 0)कोड को हटाने और कोड में डालने की कोशिश करें get_free_memory()( loop_counterवेतन वृद्धि छोड़ें ) और इसे चलाएं। यह कम से कम आपको बताएगा कि क्या आपके मेमोरी आवंटन में कोई बड़ी समस्या है।
एम्बेडेड.काले

1

Arduino सॉफ़्टवेयर सीरियल लाइब्रेरी इंटरप्ट का उपयोग करता है। ("softwareSerial.cpp, .h" देखें)। आपके पास एक मुद्दा हो सकता है जहां आईएसआर मुख्य कोड (या इसके विपरीत) पर "कदम" है। इंटरलॉक झंडे का उपयोग करने का प्रयास करें, ताकि प्रिंट के पूरा होने के दौरान कोड प्रतीक्षा करे।


0

कुछ समय पहले मुझे एक ही समस्या होने का आभास हुआ था। इसके बाद, मैंने इसे विलंब (1) को सामने या धारावाहिक के बाद हल करके जोड़ा। यह लिनक्स पर Arduino 0022 के साथ था। यकीन नहीं होता कि यह कौन सा बोर्ड था, शायद बोर्डूइनो सीरियल। खिचड़ी भाषा इसे या तो पुन: पेश करती है।

वर्तमान में, यह विंडोज पर Arduino 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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.