অকার্যকর লুপের বাইরে ফাংশনগুলি কীভাবে কাজ করে?


9

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

উদাহরণস্বরূপ নীচের কোডে, কখন void receiveData(int byteCount)এবং void sendData()কার্যাবলী চলবে?

//I2C_test

//This code demonstrates communication via an I2C bus between a raspberry pi and an arduino.
//When the Raspberry pi (master) sends data to the Arduino (slave), the Arduino uses this
//data to control a motor. After the Arduino has recieved data from the master, it then collects
//data from the external environment via a sensor and sends this data back to the Raspberry pi.

#include <Wire.h>
int number = 0; //Declare variables
int val = 0;

void setup() {
  //Anything between the curly brackets runs once when the arduino is turned on or reset
  pinMode(0, INPUT);
  //Set pin 0 as input and 3 as output
  pinMode(3, OUTPUT);
  Serial.begin(9600);
  //Set the data rate for serial transmission at 9600bps
  Wire.begin(0x04);
  //Initiate the Wire library, join the Arduino as a slave, and specify its 7 bit slave address
  Wire.onReceive(receiveData);
  //Define callbacks for i2c communication
  Wire.onRequest(sendData);
}

void loop() {
  //The code between the curly brackets keeps repeating
  delay(100);
}

void receiveData(int byteCount) {
  while(Wire.available()) {
    number = Wire.read();
    //Set the variable "number" to the data sent by the master
    analogWrite(3, number);
    //Write this number to pin 3 (PWM). This controls the motor speed
  }
  val = analogRead(0);
  //Read the voltage on pin 0 (connected to the sensor). Map input voltages between 0 and 5 volts into integer values between 0 and 1023
}

void sendData() {
  Wire.write(val);
  //Send the data read from the sensor to the master.
}

এটি আকর্ষণীয় দেখায়। আমি যদি আপনি কোডের উত্সটিতে লিঙ্কগুলি পোস্ট করতে পারেন (এবং আরডুইনো এবং পাই এর মধ্যে সংযোগের বিশদ) লিখতে পারি তবে আমি অবাক হই।
মিলিওয়েজ

1
@ মিলিওয়েজ আমি এই * টিউটোরিয়ালটি আরডুইনো ইউনো এবং রাস্পবেরি পাই (বি + মডেল) এ কোডটি লিখতে ব্যবহার করেছি, তবে আমি কয়েকটি ছোট পরিবর্তন করেছি two দুটি বোর্ডের এসডিএ এবং এসসিএল পিন সংযোগ স্থাপন করুন, পাশাপাশি গ্রাউন্ড পিনগুলি যদি তারা যোগ করে তবে বিভিন্ন বিদ্যুৎ সরবরাহের সাথে সংযুক্ত থাকে। আমি তখন পিন 3 একটি সম্ভাব্য বিভাজক কনফিগারেশনে কনফিগার করা সেন্সরের সাথে সংযুক্ত ছিল, + 5 ভি এবং জেন্ড পিনের মধ্যে সংযুক্ত ছিল। পিন 0 এবং Gnd মোটর ড্রাইভ বোর্ডের সাথে সংযুক্ত।
ব্লু 7

উত্তর:


11

setup()এবং loop()ফাংশন অস্বাভাবিক কারণ তারা যাও Arduino কোড দ্বারা আপনার জন্য স্বয়ংক্রিয়ভাবে বলা হয়। অন্য কোনও ফাংশন এইভাবে আচরণ করে না।

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

উদাহরণস্বরূপ, pinMode()অন্য কোনও মত একটি ফাংশন। এটি কেবল তখনই চালিত হয় যখন আপনি আসলে আপনার কোডটিতে কিছু রাখেন pinMode(3, INPUT)। এই মুহুর্তে, এটি একবারে সঞ্চালিত হয়, শেষ হয় এবং তারপরে কলিং ফাংশনটি যেখানে ছেড়ে যায় সেখান থেকে চালিত হয় (তারা কখনও সমান্তরালে চলবে না)।

আপনি পোস্ট করেছেন উদাহরণ কোডটি বেশ আকর্ষণীয়। এই লাইনগুলিতে দেখুন setup():

Wire.onReceive(receiveData);
Wire.onRequest(sendData);

এই লাইনগুলি আইটেমটিকে Wireকল করতে receiveData()এবং sendData()I2C ইভেন্টের প্রতিক্রিয়া হিসাবে বলছে । এটি ফাংশন পয়েন্টারগুলি যা স্টোর করে এবং ব্যবহার করে তা পাস করে এটি করে Wire

আপনি যদি এই সম্পর্কে আরও জানতে চান তবে অনলাইনে সি / সি ++ ফাংশন পয়েন্টার সম্পর্কিত তথ্য অনুসন্ধানের পরামর্শ দেব । আপনি আরডুইনোর attachInterrupt()কার্যকারিতা অন্বেষণ করতে আগ্রহীও হতে পারেন ।


আপনার উত্তরের জন্য ধন্যবাদ. এটি এখন আরও বুদ্ধিমান হতে শুরু করে। যাইহোক, যদি না বলা হয় receiveData()এবং sendData()ফাংশনগুলি না চালানো হয়, তবে কেন তাদের void setup()ফাংশনটির মধ্যে বলা হয় এবং মূল void loop()ফাংশনটি নয়? নির্দেশের পয়েন্টারটি এখনও void setupফাংশনের মধ্যে থাকা অবস্থায় কোনও আই 2 সি ইভেন্ট থাকার বিরল সুযোগ না পাওয়া পর্যন্ত এই ফাংশনগুলি কখনই ডাকা হবে না ? এই ফাংশনগুলি ফাংশনটির মধ্যে থেকে কল করা ভাল না void loopতাই যখনই কোনও আই 2 সি ইভেন্ট থাকে তখন ফাংশনটি বলা হয়?
নীল 7

4
@ ব্লু 7 এই ফাংশনগুলিতে ডাকা হয় না void setup(), এগুলি প্যারামিটার হিসাবে পাস করা হয় onReceiveএবং onRequest, তারা মন্তব্য বাক্য হিসাবে কলব্যাক । খুব স্বল্প সংক্ষেপে বলা: এই যখন নির্দিষ্ট কিছু ঘটতে (এই ফাংশান কল করার ওয়্যার লাইব্রেরী (থেকে কোড) বলে arduino.cc/en/Reference/WireOnReceive , arduino.cc/en/Reference/WireOnRequest ...)
FredP

পছন্দ করুন লিঙ্কগুলির জন্য ধন্যবাদ, আমি যখন আমার ফোনে থাকি না তখন আমি সেগুলি পরীক্ষা করে দেখব। এর মধ্যেই আমার একটি দ্রুত প্রশ্ন রয়েছে, যদি আপনি কিছু মনে করেন না। এই কলব্যাকগুলি কি সর্বদা প্রস্তুত এবং আই 2 সি ইভেন্টের জন্য অপেক্ষা করে থাকে? উদাহরণস্বরূপ, নির্দেশ পয়েন্টার যেখানেই থাকুক না কেন, এই কলব্যাকগুলি i2c ইভেন্ট হওয়ার সাথে সাথে তত্ক্ষণাত ফাংশনটি কল করবে?
ব্লু 7

1
@ ব্লু 7 এটি সম্ভবত I2C ক্রিয়াকলাপটি নিরীক্ষণ করতে বাধা ব্যবহার করবে। যখন কোনও বাধা কার্যকর করে, এটি সাময়িকভাবে মূল প্রোগ্রাম থেকে নিয়ন্ত্রণ সরিয়ে নেয়।
পিটার ব্লুমফিল্ড

3
@ ব্লু 7 কলব্যাকগুলি অপেক্ষা করছে না (আরডুইনো মাল্টিথ্রেড নয়), যেমনটি @ পিটারআর ব্লুমফিল্ড বলছে, ওয়্যার লাইব্রেরি I2C কে বাধা দেয় twi_init()যখন আপনি কল করেন Wire.begin। যখন আই 2 সি ক্রিয়াকলাপ থাকে তখন µ সি তার বর্তমান কাজটি করা বন্ধ করে দেয় (যদি না ... মুহূর্তের জন্য কিছুই মনে না করে :-) এবং তারের লাইব্রেরির কোডে যায় না, তখন এটি (যথাযথ, যা ঘটছে তার উপর নির্ভর করে) ফাংশনটি হিসাবে আপনি নিবন্ধিত হন কলব্যাক ( receiveDataউদাহরণস্বরূপ)। একটি কলব্যাক মতো কাজগুলির জন্য জেনেরিক নাম receiveDataবা sendDataতারা একটি ডাকা করছি, বিঘ্ন হ্যান্ডলার ওয়্যার ভিতরে।
ফ্রেডপ

2

এটি কি সেই ক্ষেত্রে নয় যা setup()একবার ডাকা হয় এবং loop()বারবার বলা হয়? অর্থাত্ এমন একটি অদৃশ্য রয়েছে main() যা দেখতে এরকম হতে পারে:

void main(){
  setup();
  while(True){
    loop();
  }
}

আমি যেমন আরডুইনো সন্ধান করছি এবং প্রায় কোনও সি / সি ++ অভিজ্ঞতা নেই বলে দুঃখিত; আমি loop()নিজেই এই পরিস্থিতিটি সামলানোর চেষ্টা করছি।


মূলত, হ্যাঁ এছাড়া একটি কল করার init()টাইমার জন্য যাচ্ছে যা পায় millis, delayইত্যাদি সুতরাং init()সাধারণ আরম্ভের জন্য, setup()জন্য আপনার আরম্ভের, এবং loop, লুপিং জন্য, ভাল। আপনি mainপুরো নিয়ন্ত্রণ নিতে চাইলে আপনি নিজের লেখা লিখতে পারেন।
নিক গ্যামন

চমৎকার পোস্ট. BTW ;উপান্ত্য পর প্রয়োজন হয় না }:-)
Greenonline

সিরিয়াল_সেন্টের কলও আছে () না?
Divisadero

2

আমি ডির প্রতিক্রিয়া সম্পর্কে মন্তব্য করতে পারি না। মূল লুপটিতে মৃত্যুদন্ড কার্যকর করা আসল কোডটি এখানে :

    int main(void) {
    init();
    initVariant();

    setup();

    for (;;) {
        loop();
        if (serialEventRun) serialEventRun();
    }   
    return 0;
}

এবং হ্যাঁ, setup()একবার কল হয়ে যায় এবং loop()বার বার ডাকা হয় (কিছু সিরিয়াল স্টাফ সহ)।


0

এটি সাধারণ ফাংশন হিসাবে কাজ করে, এটি বোঝার জন্য অবশ্যই ফোন করা উচিত। লুপ () / সেটআপ () কে মূল () ফাংশন থেকে ডাকা হয় যা আরডুইনো ডিরেক্টরি থেকে সংকলিত হয় এবং সংযুক্ত থাকে receive

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