সার্ভগুলি "কাঁপুন" থেকে থামানোর কোনও উপায় আছে কি?


20

খুব সহজভাবে, আমি অন্য কোথাও থেকে পড়া কিছু তথ্যের ভিত্তিতে সার্ভো (9 জি মাইক্রো সার্ভস) নিয়ন্ত্রণ করছি। সার্ভগুলি অবিচ্ছিন্নভাবে "কাঁপুন" ব্যতীত সবকিছু ঠিকঠাক কাজ করে। এটি হ'ল তারা খুব সূক্ষ্ম চলাচলে (1/2 -> 1 সেমি বা এর মাঝে মাঝে চলমান আন্দোলনের সাথে) কম্পন করে।

আমি সফ্টওয়্যারটিতে এই জাতীয় কিছু সংশোধন করার চেষ্টা করেছি:

  do{
    delay(DTIME);
    positionServo();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("X position: ");
    lcd.print(xRead);
    lcd.setCursor(0,1);
    lcd.print("Y position: ");
    lcd.print(yRead);
  }while( readChange() ); //while there has been change

যেখানে করণীয় প্রয়োজন ম্যাপযুক্ত সার্ভো মান (আরডুইনো সারো লাইব্রেরি ব্যবহার করে) সংরক্ষণ করে এমন ভেরিয়েবলগুলি আরম্ভ করতে হবে।

রিড চেঞ্জ () ফাংশনটি এই হিসাবে সংজ্ঞায়িত করা হয়েছে:

int readChange(){
  int x_Temp, y_Temp;

  x_Temp = map(analogRead(x_axisReadPin), 0, 1023, 0, 179);
  y_Temp = map(analogRead(y_axisReadPin), 0, 1023, 0, 179);

  if( abs(x_Temp - xRead) < DEG && abs(y_Temp - yRead) < DEG ) return 0; // no change 
  else return 1; //change
}

যেখানে xRead হল সেই মান যা শুরু করা হয়েছিল (প্রথম, ম্যাপযুক্ত সার্ভো আউটপুট)।

যদিও, এটি সত্যিই একটি ভাল পদ্ধতির নয়। এটি প্রয়োজন যে দুটি মান অবশ্যই ডিইজি (~ 10 ডিগ্রি, বা আমার ক্ষেত্রে 8 0.28V) দ্বারা পরিবর্তন করা উচিত নয়। আমি যদি ফাংশনটি এমনভাবে লিখি যা হয় হয় হয় বা ডিজি এর চেয়ে কম হয়, তবে যদি আমি কেবল একবারে একটি সার্ভ পরিবর্তন করতাম? সুতরাং এখানে একটি সীমানা আছে ..

এটি কি কেবল সার্ভোসের সম্পত্তি (সম্ভবত সস্তা?) বা কোনও কর্মক্ষেত্র রয়েছে?


পেস্টি লিঙ্কটি অন্তর্ভুক্ত করা আরও সহজ হবে। এখানে পূর্ণ কোড: http://pastie.org/8191459

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

এখানে চিত্র বর্ণনা লিখুন


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

সার্ভোসে আপনি কতটা চাপ দিচ্ছেন?
ক্রিস ল্যাপ্লেন্ট

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

1
আপনার সিস্টেমটি এটি আপনার জন্য সমস্যা সমাধানে সক্ষম হতে আমাদের পক্ষে খুব জটিল। এটি সরল করুন, এবং আপনার এখনও সমস্যা আছে কিনা তা দেখুন। আপনার যদি একটি ন্যূনতম সিস্টেম থাকে যা সমস্যাটি পুনরুত্পাদন করে এবং আপনি এখনও এটিকে নিজের থেকে ঠিক করতে পারেন না, তবে সাহায্যের জন্য জিজ্ঞাসা করা উপযুক্ত হয়ে যায়।
ফিল ফ্রস্ট

12
লেজার-পরিচালনা সিস্টেম ডিজাইনের জন্য সাধারণ নোট: সার্ভোসে মিরর রাখুন, তারপরে অন্যটিতে সরাসরি নির্দেশ দিন। এইভাবে আপনাকে অন্যটিতে একটি সার্ভো লাগাতে হবে না, বা সরোসে লেজার লাগানো হবে না এবং তারপরে আপনি এগুলি সমস্ত দৃ them়তার সাথে বোল্ট করতে পারেন।
pjc50

উত্তর:


27

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

এটির জন্য ঠিক করা আপনার নিজের ডালটি লেখার জন্য। এটার মতো কিছু:

cli();
long start = micros();
digitalWrite(PIN, HIGH);
while (micros() - start < duration)
  ;
digitalWrite(PIN, LOW);
sei();

এটি অন্যান্য বাধা বন্ধ করে দেবে এবং অনেক ক্লিনার পিডব্লিউএম নাড়ি তৈরি করবে। তবে এটি "মিলিস () টাইমারটিকে কিছু ঘড়ির টিকগুলি মিস করবে (" "মাইক্রো ()" ফাংশনটিকে অন্য কিছু বলা যেতে পারে - আমি ঠিক কী ভুলে গিয়েছি))

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

সার্ভোজে গুঞ্জনের আরও একটি কারণ হ'ল সস্তার সেন্সর সহ সস্তা সার্ভোস, যেখানে সেন্সরগুলি কোলাহলপূর্ণ হয়, বা যখন ডালের সাথে অনুরোধ করা সঠিক অবস্থানটি আসলে সেন্সর দ্বারা এনকোড করা যায় না। সার্ভোটি "1822 পজিশনে স্থানান্তরিত" দেখতে পাবে এবং এটি করার চেষ্টা করবে, তবে 1823 সেন্সরটি পড়ে শেষ হবে The সার্ভোটি "সামান্য পিছনে ফিরে যান" বলবে এবং এটি 1821 সেন্সর পড়ে শেষ হবে Rep পুনরাবৃত্তি করুন! এর সমাধানটি হ'ল উচ্চ-মানের সার্ভস ব্যবহার করা। আদর্শভাবে, শখ সার্ভোগুলি মোটেও নয়, তবে অপটিক্যাল বা চৌম্বকীয় পরম এনকোডারগুলির সাথে বাস্তব সার্ভগুলি।

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


1
আর / সি সার্ভো কন্ট্রোল সিগন্যালগুলি পিডব্লিউএম। পালসের প্রস্থটি নামমাত্র 1-2 মিলিসেকেন্ড, নাড়ি পুনরাবৃত্তি বিরতি 20 থেকে 50 মিলিসেকেন্ডের যে কোনও জায়গায়। আমি নাড়ি প্রস্থে প্রায় 10 টিরও বেশি মাইক্রোসেকেন্ডের বৈচিত্রটি আশা করবো যাতে সার্ভোটি জিটারি হয়। পিআরআই-তে জিটার সাধারণত নাড়ি প্রস্থ স্থিতিশীল থাকলে সমস্যা হবে না। (আমার ময়লা-সরল 555 কন্ট্রোলার বিভিন্ন ডাল প্রস্থ এবং একই পরিমাণে পিআরআই: সার্ভো পাত্তা দেয় না))
জন আর। স্ট্রোহম

আপনি যা বলছেন তা সত্য, জিটটার বাদে - সার্ভোস 10 টি আমাদের দ্বারা নাড়ির প্রস্থকে "বন্ধ" করার আগে জিট করবে। এবং প্লেইন আরডুইনোর জন্য বিঘ্নিত জিটর (আপনি লাইব্রেরি যুক্ত করার আগে) আমাদের হিসাবে 10 এর বেশি যেতে পারে! আমি যে কোডটি আটকিয়েছি সেটি আরডিনো পরিবেশে একটি রক স্থিতিশীল ডাল উত্পন্ন করার উদ্দেশ্যে তৈরি করা হয়েছে, যা সাধারণত উত্সর্গীকৃত 555 সার্কিটের মতো রক স্থিতিশীল সারো ডালগুলিতে ততটা ভাল নয়।
জন ওয়াট

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

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

21

একে বলে "বাজ"।

কয়েকটি কারণ রয়েছে যা এটির কারণ হবে। সরোয়ারের পাওয়ারে অস্থিরতা একটি সাধারণ কারণ। আর / সি সার্ভোস যখন প্রথমবার মোটরটি চালিত করে তখন কিছু বিগ স্পাইক আঁকতে পারে।

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

এটি নিয়ন্ত্রণে আমার সার্ভো জুড়ে এটি 220 ইউএফ নিয়েছে।

ইলেক্ট্রোলাইটিক ক্যাপাসিটার স্থাপন করতে চেষ্টা করুন, কমপক্ষে কমপক্ষে 100 ইউএফ, সরাসরি সরোতে বিদ্যুৎ সরবরাহের জুড়ে, ইলেকট্রিকভাবে সারোটির যতটা সম্ভব তার কাছাকাছি, এবং দেখুন যে এটি সাহায্য করে কিনা।

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

সার্ভোর অভ্যন্তরে সারো পাত্রের ময়লার কারণে এটিও হতে পারে। প্রথমে ক্যাপাসিটারটি ব্যবহার করে দেখুন।


6

আপনার গুঞ্জন / কাঁপুনি কি কেবল যখন সরো সীমা (0 ডিগ্রি বা 180 ডিগ্রি) এর কাছাকাছি থাকলে বা ঘটছে? যদি তা হয় তবে আপনার জন্য একটি সহজ ফিক্স থাকতে পারে। আমি খুঁজে পেয়েছি যে সস্তা সার্ভগুলি কীভাবে তাদের চলাফেরার সীমাতে খুব ভালভাবে থাকতে হয় তা জানে না, যা আপনার উল্লেখ করা গুঞ্জন / কাঁপুনির কারণ হতে পারে। তবে, আপনি যদি কেবল তাদের সীমার সীমা 10 ~ 170 ডিগ্রি সীমাবদ্ধ করেন তবে সমস্যাটি স্থির হবে।

যদি এটি আপনার পক্ষে যথেষ্ট ভাল না হয় তবে আপনি অন্যান্য উত্তরে উল্লিখিত আরও জটিল সমাধানগুলি যেমন আরও ভাল শক্তি, আরও ভাল সার্ভো সেন্সর ইত্যাদি অনুসরণ করতে পারেন etc.


হ্যাঁ, আমার এসজি 90 এর জন্য এই মানগুলি 18 থেকে 162 টি It এটি আসলে 32 ডিগ্রিটি অ্যাক্সেসযোগ্য হয়নি, সম্ভবত এর অর্ধেক।
ম্যাক্সিম কচুরভস্কি

5

আমি এটিকে সরানোর পরে "সার্ভো বন্ধ করে" দিয়ে আমার সমস্যাটি সমাধান করেছি। উদাহরণ:

pinMode(PIN, OUTPUT);
myservo.write(degree);
//give servo time to move
delay(5000);
pinMode(PIN, INPUT);

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


আমি অন্যান্য সমাধানগুলি চেষ্টা করেছিলাম, এটিই একমাত্র কাজ, +1। গ্রেট আইডিয়া যখন সমস্ত ব্যর্থ হয়!
স্নাপওয়াপা

3

আমার এমজি 90 এস সার্ভোস (জিটারিং) নিয়ে একই সমস্যা ছিল, আমার সিগন্যাল লাইনগুলি তুলনামূলকভাবে দীর্ঘ (60 ~ 70 সেমি), সিগন্যালের উপরে 103 (10nF) ক্যাপাসিটার রেখে আমার জন্য সমস্যাটি স্থির করে (আমি ক্যাপাসিটারটি কোথাও কোথাও রেখেছি) মাঝখানে, সেই স্থানে যেখানে মূল সার্ভো কেবলটি আমার অভ্যন্তরীণ তারের সাথে সংযুক্ত থাকে)।

এ ছাড়া আমি স্ট্যান্ডার্ড সার্ভো লাইব্রেরিটি ব্যবহার করতে পারিনি কারণ এটি আড়ডিনো মেগায় প্রথম টাইমারটি টাইমার -5 এবং এটি আমার ফ্রিকোয়েন্সি পরিমাপের জন্য প্রয়োজন need আমি কেবল 10 সার্ভো ব্যবহার করার সাথে সাথে আমি সরো লাইব্রেরি থেকে কী কোডটি বের করে এটিকে টাইমার -1 ব্যবহার করে পরিবর্তন করেছি (প্রতিটি টাইমার মেগায় সর্বাধিক 12 সার্ভো সমর্থন করে)।

একক কোডটি রেফারেন্সের জন্য নীচে, আপনি যদি এটি নিজের প্রকল্পে অন্তর্ভুক্ত করতে চান তবে আপনি কেবল উপরের অংশটি ব্যবহার করতে পারেন, নীচের অংশটি শীর্ষ অংশটি পরীক্ষা করতে হবে (এটি সিরিয়াল পোর্টে শুনবে, আপনি এসএক্স দিতে পারেন) এবং ভিএক্স কমান্ড, যেখানে এসএক্স একটি সার্ডো নির্বাচন করে, এস 0 প্রথম সার্ভো নির্বাচন করবে, ভিএক্স আমাদের মধ্যে সার্ভো অবস্থান নির্ধারণ করবে, সুতরাং v1500 সার্ভো 0 মাঝারি অবস্থানে স্থাপন করবে, ধরে নিবেন আপনি প্রথমে একটি এস 0 কমান্ড দিয়েছেন)।

//----------------------------------------------------------------
// This is the actual servo code extracted from the servo library
//----------------------------------------------------------------

#include <avr/pgmspace.h>

//----converts microseconds to tick (assumes prescale of 8)
#define usToTicks(_us)    (( clockCyclesPerMicrosecond()* _us) / 8)

#define MIN_PULSE_WIDTH     544     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH     2400    // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH 1500    // default pulse width when servo is attached
#define REFRESH_INTERVAL    20000   // minumim time to refresh servos in microseconds

#define TRIM_DURATION       2       // compensation ticks to trim adjust for digitalWrite delays // 12 August 2009

struct s_servar {
    //----counter for the servo being pulsed for each timer (or -1 if refresh interval)
    int8_t  channel;
};
static volatile struct s_servar gl_vars;

//----maximum number of servos controlled by one timer 
#define SERVOS_PER_TIMER    12
//----this can not be higher than SERVOS_PER_TIMER
#define SERVO_AMOUNT        6

struct s_servo {
    volatile unsigned int   ticks;
    unsigned char           pin;
};
struct s_servo  gl_servos[SERVO_AMOUNT] = {
    { usToTicks(DEFAULT_PULSE_WIDTH), 22 },
    { usToTicks(DEFAULT_PULSE_WIDTH), 23 },
    { usToTicks(DEFAULT_PULSE_WIDTH), 24 },
    { usToTicks(DEFAULT_PULSE_WIDTH), 25 },
    { usToTicks(DEFAULT_PULSE_WIDTH), 26 },
    { usToTicks(DEFAULT_PULSE_WIDTH), 27 },
};

ISR(TIMER1_COMPA_vect) {
    unsigned char       servooff;
    if(gl_vars.channel < 0 ) {
        //----channel set to -1 indicated that refresh interval completed so reset the timer
        TCNT1 = 0;
    }
    else{
        servooff = gl_vars.channel;
        if(servooff < SERVO_AMOUNT) {
            //----end the pulse
            digitalWrite(gl_servos[servooff].pin, LOW);
        }
    }
    //----increment to the next channel
    gl_vars.channel++;
    servooff = gl_vars.channel;
    if(servooff < SERVO_AMOUNT) {
        //----set timer interrupt for pulse length
        OCR1A = TCNT1 + gl_servos[servooff].ticks;
        //----start the pulse
        digitalWrite(gl_servos[servooff].pin, HIGH);
    }
    else {
        // finished all channels so wait for the refresh period to expire before starting over
        //----allow a few ticks to ensure the next OCR1A not missed
        if(((unsigned)TCNT1) + 4 < usToTicks(REFRESH_INTERVAL)) {
            OCR1A = (unsigned int)usToTicks(REFRESH_INTERVAL);
        }
        else {
            //----at least REFRESH_INTERVAL has elapsed
            OCR1A = TCNT1 + 4; 
        }
        //----this will get incremented at the end of the refresh period to start again at the first channel
        gl_vars.channel = -1;
    }
}

void InitServoISR() {
    unsigned char   ct;
    gl_vars.channel = -1;
    //----init timer 1
    TCCR1A = 0;             // normal counting mode
    TCCR1B = _BV(CS11);     // set prescaler of 8
    TCNT1 = 0;              // clear the timer count
    TIFR1 |= _BV(OCF1A);    // clear any pending interrupts;
    TIMSK1 |= _BV(OCIE1A);  // enable the output compare interrupt
    //----set all servo pins to output
    for(ct = 0; ct < SERVO_AMOUNT; ct++) {
        pinMode(gl_servos[ct].pin, OUTPUT); 
    }
}

void SetServoMicroSecs(unsigned char servooff, unsigned short value) {
    uint8_t oldSREG;
    if(servooff < SERVO_AMOUNT) {
        //----ensure pulse width is in range
        if(value < MIN_PULSE_WIDTH) { value = MIN_PULSE_WIDTH; }
        else {
            if(value > MAX_PULSE_WIDTH) { value = MAX_PULSE_WIDTH; }
        }
        value -= TRIM_DURATION;
        value = usToTicks(value);
        oldSREG = SREG;
        cli();
        gl_servos[servooff].ticks = value;
        SREG = oldSREG;
    }
}

//------------------------------------------------
// This is code to test the above servo functions
//------------------------------------------------

#define ERR_OK          0
#define ERR_UNKNOWN     1
#define ERR_OUTOFRANGE  2

#define SERDEBUG_CODE
#define MAX_SER_BUF     12

void setup() { 
    InitServoISR();

    #ifdef SERDEBUG_CODE
    Serial.begin(9600);
    Serial.println(F("Start"));
    #endif
}


void loop() {
    #ifdef SERDEBUG_CODE
    uint8_t         ct, chr;
    char            buf[MAX_SER_BUF];
    ct = 0;
    #endif   
    //----main while loop
    while(1) {
        #ifdef SERDEBUG_CODE
        //--------------------
        // Serial Port
        //--------------------
        while (Serial.available() > 0) {
            chr = Serial.read();
            if(chr == '\n') {
                ProcSerCmd(buf, ct);
                ct = 0;
            }
            else {
                //----if for some reason we exceed buffer size we wrap around
                if(ct >= MAX_SER_BUF) { ct = 0; } 
                buf[ct] = chr;
                ct++;
            }
        }
        #endif
    }
}

//------------------------------
// Serial Port Code
//------------------------------

#ifdef SERDEBUG_CODE
uint16_t RetrieveNumber(char *buf, uint8_t size) {
    //--------------------------------------------------------------
    // This function tries to convert a string into a 16 bit number
    // Mainly for test so no strict checking
    //--------------------------------------------------------------
    int8_t  ct;
    uint16_t    out, mult, chr;
    out = 0;
    mult = 1;
    for(ct = size - 1; ct >= 0; ct--) {
        chr = buf[ct];
        if(chr < '0' || chr > '9') { continue; }
        chr -= '0';
        chr *= mult;
        out += chr;
        mult *= 10;
    }
    return(out);
}

void ProcSerCmd(char *buf, uint8_t size) {
    //-----------------------------------------------------------
    // supported test commands
    // sX   X = 0 to SERVO_AMOUNT       Sets the servo for test
    // vX   X = MIN to MAX PULSE WIDTH  Sets the test servo to value X
    //-----------------------------------------------------------
    static unsigned char    lgl_servooff = 0;
    uint8_t                 chr, errcode;
    uint16_t                value;
    errcode = 0;
    while(1) {
        chr = buf[0];
        //----test commands (used during development)
        if(chr == 's') {
            value = RetrieveNumber(buf + 1, size - 1);
            if(value < 0 || value >= SERVO_AMOUNT) { errcode = ERR_OUTOFRANGE; break; }
            lgl_servooff = (unsigned char)value;
            break;
        }
        if(chr == 'v') {
            value = RetrieveNumber(buf + 1, size - 1);
            if(value < MIN_PULSE_WIDTH || value > MAX_PULSE_WIDTH) { errcode = ERR_OUTOFRANGE; break; }
            SetServoMicroSecs(lgl_servooff, value);
            break;
        }
        errcode = ERR_UNKNOWN;
        break;
    }
    if(errcode == 0) {
        Serial.println(F("OK"));
    }
    else {
        Serial.write('E');    
        Serial.println(errcode);
    }
}
#endif

2

এক্ষেত্রে আমার সেরা বিকল্পটি ছিল প্রতিটি ক্রিয়াকলাপে সার্ভোস সংযুক্ত করা এবং আলাদা করা।

servo1.attach(pinServo1);
for (pos = 0; pos <= servoMax; pos += 1) {
    servo1.write(pos);
    delay(10);
}
servo1.detach(pinServo1);

পুনশ্চ. এটি আসলে কোনও মানের নয়, কেবলমাত্র একগুণ।


1

অন্যরা এই থ্রেড এবং অন্যান্য আরডুইনো ফোরামে এই সারো গুঞ্জন ইস্যুটির বিভিন্ন সমাধানের পরামর্শ দিয়েছেন, যেমন:

  • নিজস্ব নাড়ি তৈরি করুন
  • 5V শক্তি আলাদাভাবে সরবরাহ করুন
  • এর সীমাতে ঠেলাঠেলি করা থেকে বিরত থাকুন (যেমন 0-180 এর পরিবর্তে 10-170 ব্যবহার করুন)
  • একটি ক্যাপাসিটার জুড়ে চালান
  • সরানোর পরে বিচ্ছিন্ন

আমার ক্ষেত্রে, আমি দেখতে পেলাম যে যখন 9V / 2A বিদ্যুৎ সরবরাহ আরডুইনো বোর্ডে প্লাগ করা হয় তখন গুঞ্জন বন্ধ হয়ে যায়। তবে সবচেয়ে সহজ চূড়ান্ত সমাধানটি ছিল সরো আস্তে আস্তে সরানো:

for (pos = servo.read(); pos < 180; pos += 2) {
  servo.write(pos);
  delay(40);
}

YMMV।


1
#include <Servo.h>             //Servo library
Servo servo_test;        //initialize a servo object for the connected servo  

int angle = 0;
int sw1 = 7;   // pushbutton connected to digital pin 7
int val=0;

void setup()
{
   servo_test.attach(2);     // attach the signal pin of servo to pin2 of arduino
   pinMode(sw1, INPUT_PULLUP);
}

void loop()
{
    val = digitalRead(sw1);
    if (val == LOW)
    {  
        servo_test.attach(2);     // attach the signal pin of servo to pin2 of arduino
        for(angle = 0; angle < 90; angle += 1)   // command to move from 0 degrees to 90 degrees 
        {                                  
            servo_test.write(angle);                 //command to rotate the servo to the specified angle
            delay(5);                     
        } 
    }
    else
    {
        servo_test.detach();// After servo motor stops we need detach commmand to stop vibration
    }
}

0

আমার কাছে এটির মতামত লুপটির ত্রুটি বা ভুল সুরের মতো দেখাচ্ছে। হাই-এন্ড সার্ভো কন্ট্রোল সিস্টেমে মোটর বৈশিষ্ট্যগুলি সম্পর্কে কিছু জ্ঞান রয়েছে (আনয়নতা, টর্ক, পিক কারেন্ট, পোল গণনা), বোঝা (জড়তার মুহূর্ত) এবং তাত্ক্ষণিক অবস্থার (অবস্থান, আরপিএম, ব্যাক-ইম্ফ, বর্তমান)। এই তথ্যের সাহায্যে মোটর কন্ট্রোল প্রোগ্রাম নিয়ামক (যেমন বর্তমান / ভোল্টেজ ইনপুট) থেকে প্রদত্ত ইনপুটটির প্রতিক্রিয়াতে सर्वोটি কী করবে সে সম্পর্কে পূর্বাভাস দিতে পারে এবং সেই ভিত্তিতে কাঙ্ক্ষিত আউটপুট অর্জনের জন্য সর্বোত্তম ইনপুট উত্পন্ন করে।

আপনি যেমন কল্পনা করতে পারেন, এটি কিছুটা জটিল জিনিস, তবে সার্ডো প্রতিক্রিয়ায় একটি ইন্টারনেট অনুসন্ধান আপনাকে শুরু করবে।

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