क्या "हिलने" से सर्वो को रोकने का एक तरीका है?


20

बहुत सरलता से, मैं कहीं से पढ़े गए कुछ आंकड़ों के आधार पर सर्वो (9g माइक्रो सर्वोस) को नियंत्रित कर रहा हूं। सब कुछ ठीक काम करता है सिवाय इसके कि सर्वो लगातार "हिलाएगा।" यही है, वे बहुत सूक्ष्म आंदोलनों (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

जहां आवश्यक है, मैप किए गए सर्वो मूल्य (arduino सर्वो पुस्तकालय) का उपयोग करने वाले चर को इनिशियलाइज़ करना आवश्यक है।

ReadChange () फ़ंक्शन को इस प्रकार परिभाषित किया गया है:

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 डिग्री, या ~ 0.28V मेरे मामले में) के एक कारक द्वारा नहीं बदला जाना चाहिए। अगर मैं फ़ंक्शन ऐसा लिखूं जो या तो या DEG से कम हो, तो क्या होगा अगर मैं एक बार में केवल एक सर्वो बदल रहा हूं? इसलिए एक परिसीमन है ।।

क्या यह बस सर्वोस (शायद सस्ते वाले?) की संपत्ति है या कोई वर्कअराउंड है?


एक पेस्टी लिंक को शामिल करना बहुत सरल होगा। यहाँ पूर्ण कोड है: http://pastie.org/8191459

मैंने दो सर्वर्स को एक साथ लेजर पॉइंटर के साथ दो डिग्री की स्वतंत्रता (एक्स, वाई) के लिए अनुमति दी है। विभिन्न तरीकों से सर्वो को नियंत्रित करने के लिए कई बटन की स्थिति के आधार पर विकल्प हैं। पहला "मोशन" है जहां मेरे पास दो फोटोरिस्टोर हैं जो प्रकाश जोखिम की मात्रा के आधार पर, सर्वो की स्थिति को प्रभावित करते हैं। मैंने अभी तक किसी Xbox नियंत्रक द्वारा सर्वो को नियंत्रित करने के लिए कोड लागू नहीं किया है। और तीसरा विकल्प सिर्फ यादृच्छिक गति है।

यहां छवि विवरण दर्ज करें


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

आप सर्वोस पर कितना भार डाल रहे हैं?
क्रिस लैपलंते जूल

4
@ ओलिनथ्रोप - (एस) वह मानक रेडियो-नियंत्रित मॉडल सर्वोस का उपयोग कर रहा है, जिसमें पूरे सर्वो लूप को डिवाइस में बेक किया गया है। Sherrellbc - "सर्वो" एक बहुत ही सामान्य शब्द है। दुर्भाग्य से, आरसी मॉडल घटक निर्माताओं ने उपकरणों के उत्पादन के लिए कम से कम वर्णनात्मक शब्द चुना। चूंकि हम यहां विभिन्न प्रकार के सर्वो और सर्वो-सिस्टम से निपटते हैं, यह निर्दिष्ट करते हुए कि आपके "सर्वो" रेडियो-नियंत्रित मॉडल हैं, शायद एक अच्छा विचार है।
कॉनर वुल्फ

1
आपका सिस्टम हमारे लिए बहुत जटिल है जो आपके लिए इसका निवारण करने में सक्षम है। इसे सरल करें, और देखें कि क्या आपको अभी भी समस्या है। जब आपके पास एक न्यूनतम प्रणाली होती है जो समस्या को पुन: पेश करती है, और आप अभी भी इसे अपने आप को ठीक नहीं कर सकते हैं, तो मदद मांगना उचित है।
फिल फ्रॉस्ट

12
लेजर-निर्देशन प्रणाली को डिजाइन करने के लिए सामान्य नोट: सर्वोस पर दर्पण डालें, फिर एक पर दूसरे को निर्देशित करें। इस तरह आपके पास एक सर्वो नहीं होना चाहिए दूसरे पर घुड़सवार, और न ही लेजर सर्वो पर घुड़सवार, और फिर आप उन्हें मजबूती से नीचे सभी को बोल्ट कर सकते हैं।
pjc50

जवाबों:


27

जब Arduino पर सर्वो लाइब्रेरी का उपयोग किया जाता है, तो सर्वो चर्चा का एक सामान्य स्रोत यह है कि अंतःक्रिया चालित सर्वो रूटीन वास्तव में बहुत स्थिर आउटपुट पल्स नहीं देते हैं। क्योंकि AVR Arduino रनटाइम में मिलिस () घड़ी और अन्य चीजों की सर्विसिंग के लिए हस्तक्षेप करता है, इमदादी लाइब्रेरी में घबराहट कई माइक्रोसेकंड के आदेश पर होती है, जो सर्वो में बहुत सारे आंदोलन का अनुवाद करता है।

इसके लिए फिक्स अपनी खुद की नब्ज लिखना है। कुछ इस तरह:

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

यह अन्य अवरोधों को बंद कर देगा, और एक बहुत क्लीनर PWM पल्स उत्पन्न करेगा। हालांकि, यह "मिलिस () टाइमर को कुछ घड़ी की टिक याद आती है। (" micros () "फ़ंक्शन को कुछ और कहा जा सकता है - मैं बिल्कुल भूल जाता हूं।)

सामान्य तौर पर, महत्वपूर्ण कोड के समय के लिए, आप Arduino रनटाइम से पूरी तरह से छुटकारा पाना चाहते हैं, और अपने खुद के एर-जीसीसी कंपाइलर और एवीआर-लिबास लाइब्रेरी का उपयोग करके लिख सकते हैं जो Arduino पर्यावरण को शक्ति प्रदान करता है। तब आप माइक्रोसेकंड प्रति 4 गुना, या यहां तक ​​कि माइक्रोसेकंड प्रति 16 बार टिक करने के लिए एक टाइमर सेट कर सकते हैं, और अपने पीडब्लूएम में एक बेहतर समाधान प्राप्त कर सकते हैं।

सर्वोस में चर्चा का एक अन्य कारण सस्ते सेंसर के साथ सस्ता सर्वो है, जहां सेंसर शोर होते हैं, या जब पल्स के साथ अनुरोध की गई सटीक स्थिति वास्तव में सेंसर द्वारा एन्कोड नहीं की जा सकती है। इमदादी "1822 की स्थिति में कदम" देखेगा और इसे करने की कोशिश करेगा, लेकिन 1823 पढ़ने वाले सेंसर के साथ समाप्त होता है। सर्वो तब कहेंगे "थोड़ा पीछे हटो" और यह 1821 पढ़ने वाले सेंसर के साथ समाप्त होता है। दोहराएं! इसके लिए उच्च-गुणवत्ता वाले सर्वो का उपयोग करना है। आदर्श रूप से, सर्व में शौक नहीं, बल्कि ऑप्टिकल या चुंबकीय निरपेक्ष एनकोडर के साथ वास्तविक सर्वो।

अंत में, यदि सर्वो को पर्याप्त शक्ति नहीं मिलती है, या यदि आप Arduino पर 5V रेल से अपनी शक्ति को चलाने की कोशिश करते हैं, तो यह सर्वो में वोल्टेज-साग-प्रेरित बज़ उत्पन्न करेगा, जैसा कि ऊपर बताया गया है। आप इसे बड़े इलेक्ट्रोलाइटिक कैपेसिटर (जो वैसे भी सामान्य फ़िल्टरिंग के लिए एक अच्छा विचार है) के साथ ठीक करने में सक्षम हो सकते हैं, लेकिन आप यह सुनिश्चित करना चाहते हैं कि आपका सर्वो पावर स्रोत वास्तव में सर्वो वोल्टेज पर वर्तमान के कई एम्पों को वितरित कर सकता है।


1
आर / सी सर्वो नियंत्रण संकेत PWM हैं। पल्स की चौड़ाई नाममात्र 1-2 मिलीसेकंड है, पल्स पुनरावृत्ति अंतराल 20 से 50 मिलीसेकंड तक कहीं भी है। मैं पल्स चौड़ाई में भिन्नता के 10 से अधिक माइक्रोसेकंड की अपेक्षा करता हूं ताकि सर्वो को घबराहट हो। पीआरआई में घबराना आमतौर पर एक समस्या नहीं होगी यदि पल्स की चौड़ाई स्थिर है। (मेरी गंदगी-सरल 555 नियंत्रक विविध पल्स चौड़ाई और एक ही राशि से पीआरआई: सर्वो की परवाह नहीं की।)
जॉन आर। स्ट्रॉहम

आप जो कुछ भी कहते हैं वह सच है, सिवाय घबराहट के - सर्व 10 दिन तक नाड़ी की चौड़ाई "बंद" होने से पहले घबराना होगा। और सादे Arduino के लिए बाधा घबराना (इससे पहले कि आप पुस्तकालयों को जोड़ दें) 10 के रूप में उच्च जा सकते हैं! जिस कोड को मैंने चिपकाया है, वह अरुडिनो वातावरण में एक रॉक स्टेबल पल्स उत्पन्न करने के लिए है, जो आमतौर पर एक समर्पित 555 सर्किट के रूप में रॉक स्टेबल सर्वो दालों में उतना अच्छा नहीं है।
जॉन वाटे

4
मैंने सिर्फ एक लेख लिखा है जिसमें बताया गया है कि उपरोक्त कोड की तरह Arduino पर सटीक दालें कैसे उत्पन्न की जाती हैं , सिवाय इसके कि टाइमर हार्डवेयर का उपयोग करता है -और कोई अवरोधों को बंद करने की आवश्यकता नहीं है और Arduino रन-टाइम को गड़बड़ कर देता है।
बिगजॉश

ध्यान दें कि Arduino कुछ पिंस (PWM पिन) पर केवल टाइमर आउटपुट का समर्थन करता है और आप इस विधि के लिए Timer0 पिन का उपयोग नहीं कर सकते हैं। इस प्रकार, केवल 4 पिन हैं यह वास्तव में एक नियमित Arduino UNO पर काम करता है। यदि आपको 4 या उससे कम सर्वो ड्राइव करने की आवश्यकता है, और कुछ और के लिए टाइमर की आवश्यकता नहीं है, तो यह एक अच्छा विकल्प है।
जॉन वेट

21

इसे "बज़" कहा जाता है।

कुछ चीजें हैं जो इसका कारण बनेंगी। सर्वो के लिए शक्ति में अस्थिरता एक सामान्य कारण है। जब वे पहली बार मोटर को गति में रखते हैं तो R / C सर्वोस कुछ BIG स्पाइक्स खींच सकते हैं।

कई साल पहले, मैंने एक टॉवर शौक रॉयल टाइटन स्टैंडर्ड सर्वो के साथ खेला था, इसे 555 और एक-ट्रांजिस्टर इन्वर्टर से नियंत्रित किया। डेड-सिंपल कंट्रोल सर्किट। मुझे पता चला कि इमदादी मोटर ने निरंतर गति में रहते हुए 5V आपूर्ति से 250 mA आकर्षित किया। बज़िंग, यह आसानी से आधा-amp spikes आकर्षित किया। (शायद और अधिक: मैं अपनी बेंच आपूर्ति पर वर्तमान मीटर की निगरानी कर रहा था, न कि एक वर्तमान-संवेदी शंट का परिमार्जन।)

इसे सम्‍मिलित करने के लिए मेरे सर्वो पर सीधे 220 यूएफ लगे।

इलेक्ट्रोलाइटिक कैपेसिटर लगाने की कोशिश करें, कम से कम 100 यूएफ, सीधे इमदादी को बिजली की आपूर्ति के रूप में, जैसा कि आप कर सकते हैं, इलेक्ट्रो के करीब करें और देखें कि क्या मदद करता है।

उन प्रयोगों के आधार पर, मैं कभी भी कैपेसिटर को जोड़े बिना RTH / C सर्वो का उपयोग करने पर विचार नहीं करूंगा। जिसमें रेडियो-नियंत्रित मॉडल शामिल हैं।

यह सर्वो के अंदर सर्वो पॉट में गंदगी के कारण भी हो सकता है। पहले संधारित्र का प्रयास करें।


6

क्या आपका buzzing / झटके केवल तब हो रहा है जब सर्वो की सीमा (0 डिग्री या 180 डिग्री) के करीब या उससे अधिक हो? यदि हां, तो आपके लिए एक साधारण सुधार हो सकता है। मैंने पाया है कि सस्ते सर्वोस को पता नहीं है कि उनके आंदोलन की सीमाओं पर बहुत अच्छी तरह से कैसे रहना है, जो आपके द्वारा उल्लिखित गुलजार / झटकों का कारण बन सकता है। हालाँकि, यदि आप उनकी सीमा को 10 ~ 170 डिग्री तक सीमित करते हैं, तो समस्या ठीक हो जाएगी।

यदि यह आपके लिए पर्याप्त नहीं है, तो आप अन्य उत्तरों में उल्लिखित अधिक जटिल सुधारों का पालन कर सकते हैं, जैसे बेहतर शक्ति, बेहतर सर्वो सेंसर आदि।


हां, मेरे SG90 के लिए ये मूल्य 18 से 162 हैं। यह वास्तव में 32 डिग्री को अप्राप्य नहीं बना सकता है, शायद यह केवल आधा है।
मैक्सिम काचुरोवस्की

5

मैंने इसे स्थानांतरित करने के बाद अपनी समस्या "सर्वो स्विच ऑफ" करके तय की है। उदाहरण:

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

PINPWM पिन आपके इमदादी से जुड़ा है। इसे इनपुट मोड पर स्विच करके मैं कंपन को बंद करने में सक्षम था। यह इष्टतम समाधान नहीं है और मैं पहले अन्य समाधानों को आज़माने का सुझाव दूंगा।


मैंने अन्य समाधानों की कोशिश की, यह काम करने वाला एकमात्र था, +1। महान विचार जब बाकी सब विफल हो जाता है!
स्नप्पवापा

3

मुझे MG90S सर्वो (घबराना) के साथ एक ही समस्या थी, मेरी सिग्नल लाइनें अपेक्षाकृत लंबी (60 ~ 70 सेमी) हैं, सिग्नल और ग्राउंड लाइनों पर 103 (10nF) कैपेसिटर रखकर मेरे लिए समस्या तय की गई (मैंने कैपेसिटर को कहीं और रखा। मध्य, उस बिंदु पर जहां मूल सर्वो केबल मेरी आंतरिक केबल से जुड़ती है)।

इसके अलावा, मैं मानक सर्वो पुस्तकालय का उपयोग नहीं कर सका क्योंकि अरुडिनो मेगा पर पहला टाइमर यह टाइमर -5 है और मुझे आवृत्ति माप के लिए इसकी आवश्यकता है। जैसा कि मैंने केवल 10 सर्वो का उपयोग किया है मैंने सर्वो लाइब्रेरी से मुख्य कोड निकाला और इसे टाइमर -1 (प्रत्येक टाइमर मेगा पर अधिकतम 12 सर्वो का समर्थन करता है) का उपयोग करके बदल दिया।

स्टैंड-अलोन कोड संदर्भ के लिए नीचे है, यदि आप इसे अपनी परियोजना में शामिल करना चाहते हैं तो आप केवल शीर्ष भाग का उपयोग कर सकते हैं, निचला भाग शीर्ष भाग का परीक्षण करने के लिए है (यह सीरियल पोर्ट पर सुनता है, आप एसएक्स दे सकते हैं और vX कमांड्स, जहां sX एक सर्वो का चयन करता है, s0 पहले सर्वो का चयन करेगा, vX हम में सर्वो स्थिति सेट करता है, इसलिए v1500 सर्वो स्थिति को मध्य स्थिति में सेट करेगा, यह मानते हुए कि आपने पहले एक s0 कमांड दिया था)।

//----------------------------------------------------------------
// 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

जबकि अन्य ने इस सर्वो चर्चा के विभिन्न समाधानों का सुझाव दिया है, इस धागे और अन्य Arduino मंचों में, अर्थात्:

  • खुद की नब्ज पैदा करो
  • 5V बिजली की आपूर्ति अलग से करें
  • इसकी सीमा पर जाने से बचें (उदाहरण के लिए 0-180 के बजाय 10-170 का उपयोग करें)
  • एक संधारित्र चलाएँ
  • ले जाने के बाद अलग करना

मेरे मामले में, मैंने पाया कि 9V / 2A बिजली की आपूर्ति Arduino बोर्ड में प्लग किए जाने पर बंद हो जाती है। लेकिन सबसे आसान अंतिम उपाय यह था कि आप धीरे-धीरे सर्वो को स्थानांतरित करें:

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

मेरे लिए, यह फीडबैक लूप की त्रुटियों या गलत ट्यूनिंग की तरह है। हाई-एंड सर्वो कंट्रोल सिस्टम को मोटर विशेषताओं (इंडक्शन, टॉर्क, पीक करंट, पोल काउंट), लोड (जड़ता का क्षण) और तात्कालिक परिस्थितियों (स्थिति, आरपीएम, बैक-ईएमएफ, करंट) का कुछ ज्ञान होता है। इस जानकारी के साथ, मोटर नियंत्रण कार्यक्रम नियंत्रक (यानी वर्तमान / वोल्टेज इनपुट) से दिए गए इनपुट के जवाब में क्या करेगा के बारे में भविष्यवाणियां कर सकता है और उस आधार पर वांछित आउटपुट प्राप्त करने के लिए इष्टतम इनपुट उत्पन्न करता है।

जैसा कि आप कल्पना कर सकते हैं, यह कुछ जटिल सामग्री है, लेकिन सर्वो फीडबैक पर एक इंटरनेट खोज आपको शुरू कर देगा।

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