• Home
  • Firgelli Articles
  • একটি আরডুইনো ব্যবহার করে কীভাবে দুটি ...

একটি আরডুইনো ব্যবহার করে কীভাবে দুটি লিনিয়ার অ্যাকিউটিটারকে সিঙ্ক করবেন

একচেটিয়া লিনিয়ার অ্যাকিউটেটরগুলির মধ্যে সিঙ্ক্রোনাস গতি কিছু গ্রাহক অ্যাপ্লিকেশনগুলির সাফল্যের জন্য অত্যাবশ্যক হতে পারে, একটি সাধারণ দুটি ট্র্যাফোডোর খোলার ক্ষেত্রে দুটি লিনিয়ার অ্যাকিউটিটার। এটি অর্জনের জন্য আমরা নিবেদিত ফির্গেলি ব্যবহার করার পরামর্শ দিই সিঙ্ক্রোনাস কন্ট্রোল বাক্স এফএ-সিওয়াইএনসি -২ এবং এফএ-সিওয়াইএনসি -4। তবে কিছু ডিআইআইআর এবং হ্যাকার একটি মাইক্রোকন্ট্রোলার যেমন আরডুইনো অফার করে এবং তাদের নিজস্ব সিঙ্ক্রোনাস কন্ট্রোল প্রোগ্রাম লেখার পরিবর্তে স্বাধীনতা পছন্দ করে। এই টিউটোরিয়ালটির লক্ষ্য কীভাবে এটি ব্যবহার করে এটি অর্জন করা যায় তার উপর একটি ওভারভিউ সরবরাহ করা অপটিক্যাল সিরিজ লিনিয়ার অ্যাক্টুয়েটার.

মূল শব্দ

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

ওভারভিউ সিঙ্ক্রোনাস কন্ট্রোল

দুটি লিনিয়ার অ্যাকিউটেটরের দৈর্ঘ্যের তুলনা এবং আনুপাতিকভাবে গতি সামঞ্জস্য করে সিঙ্ক্রোনাস নিয়ন্ত্রণ অর্জন করা হয়; যদি একজন অ্যাকিউউটর অন্যের চেয়ে দ্রুত গতিতে শুরু করে তবে আমরা এটিকে ধীর করে দেব। আমরা ইনবিল্ট অপটিকাল এনকোডারটির মাধ্যমে লিনিয়ার অ্যাকুয়েটরের অবস্থানটি পড়তে পারি। অপটিকাল এনকোডারটি একটি ছোট প্লাস্টিকের ডিস্ক যার সাথে 10 টি গর্ত থাকে যা ডিসি মোটরটির সাথে সংযুক্ত থাকে যেমন যখন মোটর স্পিনটি প্লাস্টিকের ডিস্কটি ঘোরানো থাকে। একটি ইনফ্রারেড এলইডি প্লাস্টিকের ডিস্কের দিকে পরিচালিত হয় যাতে এটি আলোককে স্পিন করে যেমন হয় অপটিকাল ডিস্কের ছিদ্রগুলির মাধ্যমে সঞ্চারিত হয় বা ডিস্কের প্লাস্টিক দ্বারা অবরুদ্ধ থাকে। ডিস্কের অপর পাশের একটি ইনফ্রারেড সেন্সর সনাক্ত করে যখন আলোটি গর্তের মধ্য দিয়ে প্রেরণ করা হয় এবং একটি বর্গাকার তরঙ্গ সংকেতকে আউটপুট দেয়। ডাল সংখ্যা গণনা করে রিসিভার সনাক্ত করে আমরা মোটরটির আরপিএম এবং লিনিয়ার অ্যাকুয়েটর যে দূরত্বটি ভ্রমণ করেছেন তার উভয়ই গণনা করতে পারি। ৩৫ এলবি অপটিকাল লিনিয়ার অ্যাক্টিউইটারের ভ্রমণ প্রতি ইঞ্চিতে 50 (+/- 5) অপটিকাল ডাল রয়েছে যখন 200 এলবি এবং 400 এলবি অ্যাকিউটেটর উভয়ই প্রতি ইঞ্চিতে 100 (+/- 5) ডাল রয়েছে। প্রতিটি লিনিয়ার অ্যাকিউউটর কতদূর প্রসারিত করেছে তার তুলনা করে, আমরা দুটি অ্যাকিউটরেটের গতি আনুপাতিকভাবে সামঞ্জস্য করতে সক্ষম হয়েছি যাতে বর্ধনের সময় তারা সর্বদা একই দৈর্ঘ্যে থাকে।

প্রয়োজনীয় উপাদান

তারের ডায়াগ্রাম

একটি আরডুইনো ব্যবহার করে কীভাবে দুটি লিনিয়ার অ্যাকিউয়টারকে সিঙ্ক করবেন

উপরের তারের সংযোগ তৈরি করুন। লিনিয়ার অ্যাকিউুয়েটার থেকে বেরিয়ে আসা তারের রংগুলি সর্বদা পরীক্ষা করে নিন কারণ রঙিন সম্মেলন উপরের চিত্রটিতে প্রদর্শিত চিত্র থেকে পরিবর্তিত হতে পারে।

    দ্রুত টিউটোরিয়াল

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

    • ওয়্যারিং ডায়াগ্রামে প্রদর্শিত সংযোগগুলি তৈরি করুন।
    • নীচে প্রথম প্রোগ্রামটি আপলোড করুন এবং চালান।
    • এই প্রোগ্রামটি দ্বারা দুটি মান আউটপুট অনুলিপি করুন নীচের দ্বিতীয় প্রোগ্রামের 23 লাইনে।
    • দ্বিতীয় প্রোগ্রামটি আপলোড করুন এবং চালান।
    • আপনার সিস্টেমটি ভেরিয়েবল কে_পি (লাইন 37, দ্বিতীয় প্রোগ্রাম) পরিবর্তিত করে সূক্ষ্ম টিউন করুন। এটি সহজেই এনালগ পিন A0 তে কোনও পেন্টিওমিটার সংযুক্ত করে এবং পেন্টিয়োমিটারটি পড়ার জন্য কোডটি পরিবর্তন করে এবং মানচিত্র () ফাংশনটি ব্যবহার করে করা হয়: কে_পি = মানচিত্র (এনালগ রিড (এ 0), 0, 1023, 0, 20000);

    এই টিউটোরিয়ালটির বাকি অংশগুলিতে প্রোগ্রামগুলির কয়েকটি মূল বৈশিষ্ট্য আরও বিশদে দেখা যাবে। আবার আমরা পুনরুক্তি করি যে এটি কোনও বিস্তৃত টিউটোরিয়াল নয়, বরং আপনার নিজের প্রোগ্রাম তৈরি করার সময় বিবেচনার জন্য বিষয়গুলির একটি ওভারভিউ।

    ক্রমাঙ্কন প্রোগ্রামের ওভারভিউ

    সিঙ্ক্রোনাস নিয়ন্ত্রণ অর্জনের আগে আমাদের প্রথমে সিস্টেমটি ক্যালিব্রেট করতে হবে। এর মধ্যে প্রতি অনুচ্ছেদে চক্রের ডালের সংখ্যা গণনা জড়িত কারণ পণ্য বিবরণীতে যেমন বলা হয়েছে সেখানে ভ্রমণ প্রতি ইঞ্চি (+/- 5) ডাল সহনশীলতা রয়েছে। প্রোগ্রামটি আপলোড করুন এবং নীচে চালান। এই প্রোগ্রামটি সম্পূর্ণরূপে অ্যাকিউইটরেটরে (লাইন 53) প্রত্যাহার করবে এবং অপটিকাল পালস কাউন্টার ভেরিয়েবলটি শূন্যে সেট করবে এটি পুরোপুরি প্রসারিত এবং পুরোপুরি প্রত্যাহার করবে (যথাক্রমে line৩ এবং line৪ লাইন)। এই অ্যাক্টিচুয়েশন চক্র চলাকালীন ডালের সংখ্যা বিঘ্নিত পরিষেবা রুটিন (আইএসআর), লাইন 153 এবং 166 দ্বারা গণনা করা হবে act

    https://gist.github.com/Will-Firgelli/89978da2585a747ef5ff988b2fa53904

    COPY
    /* Written by Firgelli Automations
     * Limited or no support: we do not have the resources for Arduino code support
     * This code exists in the public domain
     * 
     * Program requires two (or more) of our supported linear actuators:
     * FA-OS-35-12-XX
     * FA-OS-240-12-XX
     * FA-OS-400-12-XX
     * Products available for purchase at https://www.firgelliauto.com/collections/linear-actuators/products/optical-sensor-actuators
     */
    
    #include <elapsedMillis.h>
    elapsedMillis timeElapsed;
    
    #define numberOfActuators 2 
    int RPWM[numberOfActuators]={6, 11}; //PWM signal right side
    int LPWM[numberOfActuators]={5,10}; 
    int opticalPins[numberOfActuators]={2,3}; //connect optical pins to interrupt pins on Arduino. More information: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
    volatile long lastDebounceTime_0=0; //timer for when interrupt was triggered
    volatile long lastDebounceTime_1=0;
    
    int Speed = 255; //choose any speed in the range [0, 255]
    
    #define falsepulseDelay 20 //noise pulse time, if too high, ISR will miss pulses. 
    volatile int counter[numberOfActuators]={}; 
    volatile int prevCounter[numberOfActuators]={}; 
    int Direction; //-1 = retracting
                   // 0 = stopped
                   // 1 = extending
    
    int extensionCount[numberOfActuators] = {}; 
    int retractionCount[numberOfActuators] = {}; 
    int pulseTotal[numberOfActuators]={}; //stores number of pulses in one full extension/actuation
    
    void setup(){
      for(int i=0; i<numberOfActuators; i++){
        pinMode(RPWM[i],OUTPUT);
        pinMode(LPWM[i], OUTPUT);
        pinMode(opticalPins[i], INPUT_PULLUP);
        counter[i]=0; //initialize variables as array of zeros
        prevCounter[i]=0;
        extensionCount[i] = 0;
        retractionCount[i] = 0;
        pulseTotal[i] = 0;
      }
      attachInterrupt(digitalPinToInterrupt(opticalPins[0]), count_0, RISING);
      attachInterrupt(digitalPinToInterrupt(opticalPins[1]), count_1, RISING); 
    
      Serial.begin(9600);
      Serial.println("Initializing calibration");
      Serial.println("Actuator retracting...");
      Direction = -1;
      moveTillLimit(Direction, 255); 
      Serial.println("Actuator fully retracted");
      delay(1000);
    
      for(int i=0; i<numberOfActuators; i++){
        Serial.print("\t\t\t\tActuator ");
        Serial.print(i);
      }
    
      Direction = 1;
      moveTillLimit(Direction, 255); //extend fully and count pulses
      Serial.print("\nExtension Count:");
      for(int i=0; i<numberOfActuators; i++){
      extensionCount[i]=counter[i];
      Serial.print("\t\t"); 
      Serial.print(extensionCount[i]);
      Serial.print("\t\t\t"); 
      }
      delay(1000);
    
      Direction = -1;
      moveTillLimit(Direction, 255); //retract fully and count pulses
      Serial.print("\nRetraction Count:");
      for(int i=0; i<numberOfActuators; i++){
      retractionCount[i]=counter[i];
      Serial.print("\t\t"); 
      Serial.print(abs(retractionCount[i]));
      Serial.print("\t\t\t"); 
      }
      Serial.print("\n");
    
      for(int i=0; i<numberOfActuators; i++){
        Serial.print("\nActuator ");
        Serial.print(i);
        Serial.print(" average pulses: ");
        pulseTotal[i]=(extensionCount[i]+abs(retractionCount[i]))/2; //takes the average of measurements
        Serial.print(pulseTotal[i]); 
      } 
      Serial.println("\n\nEnter these values in the synchronous control progam.");
    }
    
    void loop() { 
    }
    
    void moveTillLimit(int Direction, int Speed){
      //this function moves the actuator to one of its limits
      for(int i = 0; i < numberOfActuators; i++){
        counter[i] = 0; //reset counter variables
        prevCounter[i] = 0;
      } 
      do {
        for(int i = 0; i < numberOfActuators; i++) {
          prevCounter[i] = counter[i];
        }
        timeElapsed = 0;
        while(timeElapsed < 200){ //keep moving until counter remains the same for a short duration of time
          for(int i = 0; i < numberOfActuators; i++) {
            driveActuator(i, Direction, Speed);
          }
        }
      } while(compareCounter(prevCounter, counter)); //loop until all counts remain the same
    }
    
    bool compareCounter(volatile int prevCounter[], volatile int counter[]){
      //compares two arrays and returns false when every element of one array is the same as its corresponding indexed element in the other array
      bool areUnequal = true;
      for(int i = 0; i < numberOfActuators; i++){
        if(prevCounter[i] == counter[i]){
          areUnequal = false;
        } 
        else{ //if even one pair of elements are unequal the entire function returns true
          areUnequal = true;
          break;
        }
      }
      return areUnequal;
    }
    
    void driveActuator(int Actuator, int Direction, int Speed){
      int rightPWM=RPWM[Actuator];
      int leftPWM=LPWM[Actuator];
    
      switch(Direction){
      case 1: //extension
        analogWrite(rightPWM, Speed);
        analogWrite(leftPWM, 0);
      break;
    
      case 0: //stopping
        analogWrite(rightPWM, 0);
        analogWrite(leftPWM, 0);
      break;
    
      case -1: //retraction
        analogWrite(rightPWM, 0);
        analogWrite(leftPWM, Speed);
      break;
      }
    }
    
    void count_0(){
      //This interrupt function increments a counter corresponding to changes in the optical pin status
      if ((millis() - lastDebounceTime_0) > falsepulseDelay) { //reduce noise by debouncing IR signal 
        lastDebounceTime_0 = millis();
        if(Direction==1){
          counter[0]++;
        }
        if(Direction==-1){
          counter[0]--;
        }
      }
    }
    
    void count_1(){
      if ((millis() - lastDebounceTime_1) > falsepulseDelay) { 
        lastDebounceTime_1 = millis();
        if(Direction==1){
          counter[1]++;
        }
        if(Direction==-1){
          counter[1]--;
        }
      }
    }

    সিঙ্ক্রোনাস প্রোগ্রামের ওভারভিউ

    সিঙ্ক্রোনাস কন্ট্রোল প্রোগ্রামটি আপলোড করার আগে, আপনাকে অবশ্যই প্রথমে ক্যালিব্রেশন প্রোগ্রামের মাধ্যমে মূল্যগুলি আউটপুটে 23 লাইনে অনুলিপি করতে হবে এবং বর্তমান অ্যারেটি প্রতিস্থাপন করতে হবে: {908, 906। আপনার নিজস্ব মান সহ। অতিরিক্ত হিসাবে, আপনি যদি 35lb লিনিয়ার অ্যাকিউউটার ব্যবহার করছেন তবে আপনাকে লাইন 29-র ভেরিয়েবলের মান 20 মিলিসেকেন্ড থেকে 8 মিলিসেকেন্ডে পরিবর্তন করতে হবে।

    একবার সম্পূর্ণরূপে প্রত্যাহার করার পরে (মূলটি সনাক্ত করতে) আপনি এক্সটেনশন, প্রত্যাহার এবং স্টপ কমান্ডের সাথে সম্পর্কিত তিনটি বোতাম টিপতে উভয় লিনিয়ার অ্যাকিউটিটরকে সিঙ্ক্রোনাসে সরিয়ে নিতে পারেন। অ্যাকিউটেটরগুলি তাদের আপেক্ষিক পালস কাউন্টারগুলির সাথে তুলনা করে এবং তাদের মধ্যে সর্বদা সিঙ্ক্রোনাসে থাকার জন্য গতি সামঞ্জস্য করে এমনকি অসম লোডের মধ্যেও সমকালীন অবস্থায় থাকবে। পরামর্শ দিন যে বর্তমান প্রোগ্রামটি একটি সাধারণ আনুপাতিক নিয়ামক, লাইন 93 প্রয়োগ করে, যেমন ভারসাম্য ও ভারসাম্যহীনতার আশেপাশের দোলনের বিষয়। আপনি লাইন 37-এ সংজ্ঞায়িত কে-পি চলকটি পরিবর্তিত করে এটি টিউন করতে পারেন। এটি সহজেই এনালগ পিন A0 তে কোনও পেন্টিওমিটার সংযুক্ত করে এবং পেন্টিয়োমিটারটি পড়ার জন্য কোডটি পরিবর্তন করে এবং মানচিত্র () ফাংশনটি ব্যবহার করে করা হয়: কে_পি = মানচিত্র (এনালগ রিড (এ 0), 0, 1023, 0, 20000);

    সর্বোত্তম ফলাফলের জন্য আমরা আনুপাতিক নিয়ামককে অপসারণ এবং একটি পিআইডি নিয়ন্ত্রণ লুপ বাস্তবায়নের দৃ strongly়ভাবে পরামর্শ দিই; তবে এটি এই প্রবর্তক টিউটোরিয়ালের সুযোগের বাইরে এবং ইচ্ছাকৃতভাবে বাদ দেওয়া হয়েছে।

    https://gist.github.com/Will-Firgelli/44a14a4f3cac3209164efe8abe3285b6

    COPY
    /* Written by Firgelli Automations
     * Limited or no support: we do not have the resources for Arduino code support
     * This code exists in the public domain
     * 
     */
    
    #include <elapsedMillis.h>
    elapsedMillis timeElapsed;
    
    #define numberOfActuators 2       
    int downPin = 7;
    int stopPin = 8;
    int upPin = 9;        
    int RPWM[numberOfActuators]={6, 11};                                  //PWM signal right side
    int LPWM[numberOfActuators]={5,10};        
    int opticalPins[numberOfActuators]={2,3};                             //connect optical pins to interrupt pins on Arduino. More information: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
    volatile unsigned long lastDebounceTime[numberOfActuators]={0,0};     //timer for when interrupt is triggered
    int pulseTotal[numberOfActuators]={908, 906};                         //values found experimentally by first running two-optical-actuators-sync-calibration.ino
    
    int desiredSpeed=255;                            
    int adjustedSpeed;
    int Speed[numberOfActuators]={};    
    
    #define falsepulseDelay 20                                            //noise pulse time, if too high, ISR will miss pulses. If using 35lb actuator, set to 8ms                          
    volatile int counter[numberOfActuators]={};   
    volatile int prevCounter[numberOfActuators]={};     
    volatile float normalizedPulseCount[numberOfActuators]={};
    int Direction;                                                        //-1 = retracting
                                                                          // 0 = stopped
                                                                          // 1 = extending
    float error;
    int K_p=12000;                                                        //optimized experimentally. adjust this to fine tune your system
    int laggingIndex, leadingIndex;                                       //index of the slowest/fastest actuator
    
    void setup(){ 
      pinMode(stopPin, INPUT_PULLUP);
      pinMode(downPin, INPUT_PULLUP);
      pinMode(upPin, INPUT_PULLUP);
      for(int i=0; i<numberOfActuators; i++){
        pinMode(RPWM[i],OUTPUT); 
        pinMode(LPWM[i], OUTPUT);
        pinMode(opticalPins[i], INPUT_PULLUP);
        Speed[i]=desiredSpeed;
      }
      attachInterrupt(digitalPinToInterrupt(opticalPins[0]), count_0, RISING);
      attachInterrupt(digitalPinToInterrupt(opticalPins[1]), count_1, RISING);  
      Serial.begin(9600);
      Serial.println("Calibrating the origin");
      Serial.println("Actuator retracting...");
      Direction = -1;
      moveTillLimit(Direction, 255);  
      for(int i=0; i<numberOfActuators; i++){
        counter[i]=0;                                                     //reset variables 
        prevCounter[i]=0;
        normalizedPulseCount[i] = 0;
      }
      delay(1000);
      Serial.println("Actuator fully retracted");
    } 
    
    void loop() {  
      checkButtons();
    
      if(Direction==1){                                                   //based on direction of motion identify the leading and lagging actuator by comparing pulse counts
        if(normalizedPulseCount[0] < normalizedPulseCount[1]){
          laggingIndex = 0; 
          leadingIndex = 1;
        }
        else{
          laggingIndex = 1;
          leadingIndex = 0;
        }
      }
      else if(Direction==-1){
        if(normalizedPulseCount[0] > normalizedPulseCount[1]){
          laggingIndex = 0;
          leadingIndex = 1;
        }
        else{
          laggingIndex = 1;
          leadingIndex = 0;
        }
      }
      
      error=abs(normalizedPulseCount[laggingIndex]-normalizedPulseCount[leadingIndex]);
      if(Direction!=0){       
        adjustedSpeed=desiredSpeed-int(error*K_p);                 
        Speed[leadingIndex]=constrain(adjustedSpeed, 0, 255);               //slow down fastest actuator
        Speed[laggingIndex]=desiredSpeed;
      }
      for(int i=0; i<numberOfActuators; i++){
        Serial.print("  ");
        Serial.print(Speed[i]);
        Serial.print("  ");
        Serial.print(normalizedPulseCount[i]*1000);
        driveActuator(i, Direction, Speed[i]);
      }
      Serial.println();
    }
    
    void checkButtons(){
      //latching buttons: direction remains the same when let go
      if(digitalRead(upPin)==LOW){ Direction=1; }                           //check if extension button is pressed
      if(digitalRead(downPin)==LOW){ Direction=-1; }  
      if(digitalRead(stopPin)==LOW){ Direction=0; }
    }
    
    void moveTillLimit(int Direction, int Speed){
      //function moves the actuator to one of its limits
      for(int i = 0; i < numberOfActuators; i++){
        counter[i] = 0;                                                     //reset counter variables
        prevCounter[i] = 0;
      }  
      do {
        for(int i = 0; i < numberOfActuators; i++) {
          prevCounter[i] = counter[i];
        }
        timeElapsed = 0;
        while(timeElapsed < 200){                                           //keep moving until counter remains the same for a short duration of time
          for(int i = 0; i < numberOfActuators; i++) {
            driveActuator(i, Direction, Speed);
          }
        }
      } while(compareCounter(prevCounter, counter));                        //loop until all counters remain the same
    }
    
    bool compareCounter(volatile int prevCounter[], volatile int counter[]){
      //compares two arrays and returns false when every element of one array is the same as its corresponding indexed element in the other array
      bool areUnequal = true;
      for(int i = 0; i < numberOfActuators; i++){
        if(prevCounter[i] == counter[i]){
          areUnequal = false;
        } 
        else{                                                               //if even one pair of elements are unequal the entire function returns true
          areUnequal = true;
          break;
        }
      }
      return areUnequal;
    }
    
    void driveActuator(int Actuator, int Direction, int Speed){
      int rightPWM=RPWM[Actuator];
      int leftPWM=LPWM[Actuator];
      switch(Direction){
        case 1:       //extension
          analogWrite(rightPWM, Speed);
          analogWrite(leftPWM, 0);
          break;  
        case 0:       //stopping
          analogWrite(rightPWM, 0);
          analogWrite(leftPWM, 0);
          break;
        case -1:      //retraction
          analogWrite(rightPWM, 0);
          analogWrite(leftPWM, Speed);
          break;
      }
    }
    
    void count_0(){
      //This interrupt function increments a counter corresponding to changes in the optical pin status
      if ((millis() - lastDebounceTime[0]) > falsepulseDelay) {             //reduce noise by debouncing IR signal with a delay
        lastDebounceTime[0] = millis();
        if(Direction==1){
          counter[0]++;
        }
        if(Direction==-1){
          counter[0]--;
        }
        normalizedPulseCount[0]=float(counter[0])/float(pulseTotal[0]);
      }
    }
    
    void count_1(){
      if ((millis() - lastDebounceTime[1]) > falsepulseDelay) {   
        lastDebounceTime[1] = millis();
        if(Direction==1){
          counter[1]++;
        }
        if(Direction==-1){
          counter[1]--;
        }
        normalizedPulseCount[1]=float(counter[1])/float(pulseTotal[1]);
      } 
    }

    বুলেট 36 এবং বুলেট 50 অ্যাকিউইটরে সিঙ্ক্রোনাসে ব্যবহার করা

    আমাদের অপটিক্যাল সিরিজ লিনিয়ার অ্যাকিউুয়েটার ছাড়াও আমরা ইনবিল্ট এনকোডারগুলির সাথে দুটি অফার লিনিয়ার অ্যাকিউটিটর অফার করি: বুলেট 36 ক্যাল। এবং বুলেট 50 ক্যাল, উভয়েরই অভ্যন্তরীণ চতুর্ভুজ হল ইফেক্ট এনকোডার রয়েছে। হল এফেক্টটি এনকোডার অপটিক্যাল এনকোডার হিসাবে একই নীতিটিতে কাজ করে তবে হালকা ব্যবহারের পরিবর্তে এটি চৌম্বকত্বকে কাজে লাগায়। তদুপরি এটি একটি চতুর্ভুজ এনকোডার হিসাবে এটির দুটি সিগন্যাল আউটপুট রয়েছে, প্রতিটি ফেজের বাইরে 90 ডিগ্রি হয়। এর জন্য আপনার 4 বা ততোধিক বিঘ্নিত পিনের সাথে একটি আরডুইনো বোর্ড ব্যবহার করতে হবে (আরডুইনো ইউনোতে কেবল দুটি রয়েছে) এবং অ্যাক্টুয়েটর প্রতি দুটি সংকেত থেকে ইনপুট প্রক্রিয়া করার জন্য কোডটি পরিবর্তন করতে হবে। তদ্ব্যতীত, ডিবাউন সময় পরিবর্তনশীল, ফলপুলসডিলে কে_পি সহ সুর করা দরকার।

    আপনার নিজের প্রোগ্রামটি লেখার জন্য টিপস

    দুটিরও বেশি লিনিয়ার অ্যাকিউটিউটর

    দুই বা ততোধিক লিনিয়ার অ্যাকিউটিটর ব্যবহার করার সময় আরডুইনো ইউনো আর কাজ করবে না কারণ এতে কেবল দুটি বাধা পিন রয়েছে। আপনার কাছে একটি আরডুইনো বোর্ড ব্যবহার করা উচিত যাতে আরও বিঘ্নিত পিনের সংখ্যার অ্যাসোসিয়েট নম্বর পাওয়া যায়, আরও তথ্য: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/

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

    ডিবেস করা হচ্ছে

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

    হ্যান্ডলিং রোল উপর

    আপনি যদি কোডটি পরিবর্তন করেন তবে মিলিস () ফাংশনের সাথে ডিল করার সময় রোলওভার সম্পর্কে সচেতন হন। মিলিস () এবং সর্বশেষ ডেবিউনটাইম অ্যারে উভয়ই স্বাক্ষরবিহীন দীর্ঘ ভেরিয়েবল হিসাবে ঘোষিত হয় যার অর্থ তারা 4,294,967,295 (32 ^ 2-1) পর্যন্ত মান সংরক্ষণ করতে পারে। এটি প্রায় 49.7 দিনের একটি রোলওভার সময়কালে অনুবাদ করে। বর্তমান প্রোগ্রামটি আইএসআর (বিঘ্নিত পরিষেবার রুটিন) ফাংশনগুলিতে রোলওভার হ্যান্ডেল করার জন্য ডিজাইন করা হয়েছে: count_0 & count_1, তবে আপনি যদি এই প্রোগ্রামটি পরিবর্তন করেন তবে ভেরিয়েবল রোলওভারটি সঠিকভাবে পরিচালনা করতে ভুলবেন না, অন্যথায় আপনার প্রোগ্রামটি continuous 49.7 দিন অবিচ্ছিন্ন ব্যবহারের পরে ক্রাশ হয়ে যাবে। আরও তথ্যের জন্য দেখুন: https://www.norwegiancreations.com/2018/10/arduino-tutorial-avoiding-the-overflow-issue-when-using-millis-and-micros/

     

    Share This Article
    Tags: