PWM बिट संकल्प बढ़ाएँ


10

मैं Arduino Uno के PWM बिट रिज़ॉल्यूशन को बढ़ाना चाहूंगा। इस समय यह 8-बिट है जिसे मैं बहुत कम मानता हूं। क्या यह रुकावटों और देरी की क्षमता को खोए बिना संभव है?

कोएन

EDIT यह सेटअप 16-बिट परिणाम प्रदान करता है

void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS11);                    /* prescaler: clock / 8 */
    ICR1 = 0xffff;                      /* TOP counter value (freeing OCR1A*/
}
/* Comments about the setup
Changing ICR1 will effect the amount of bits of resolution.
ICR1 = 0xffff; (65535) 16-bit resolution
ICR1 = 0x7FFF; (32767) 15-bit resolution
ICR1 = 0x3FFF; (16383) 14-bit resolution etc....

Changing the prescaler will effect the frequency of the PWM signal.
Frequency[Hz}=CPU/(ICR1+1) where in this case CPU=16 MHz
16-bit PWM will be>>> (16000000/8)/(65535+1)=30.5175Hz
*/

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}

जवाबों:


16

Arduino Uno एक ATmega382P माइक्रोकंट्रोलर पर आधारित है। इस चिप में दो 8-बिट टाइमर हैं, प्रत्येक दो पीडब्लूएम चैनल चला रहे हैं, और एक 16-बिट टाइमर, पिछले दो चैनलों को चला रहे हैं।

आप 8-बिट टाइमर का रिज़ॉल्यूशन नहीं बढ़ा सकते हैं। हालाँकि, आप Arduino कोर लाइब्रेरी द्वारा उपयोग किए जाने वाले 8-बिट मोड के बजाय 16-बिट टाइमर को 16-बिट मोड में रख सकते हैं। यह आपको 244 हर्ट्ज (अधिकतम) की कम आवृत्ति के साथ, दो 16-बिट पीडब्लूएम चैनल देगा। आपको संभवतः टाइमर को स्वयं कॉन्फ़िगर करना होगा, और analogWrite()फ़ंक्शन का उपयोग करने के लिए आसान से लाभ नहीं होगा । विवरण के लिए, ATmega328P डेटाशीट में टाइमर 1 पर अनुभाग देखें ।

अपडेट : यहां 16-बिट का कार्यान्वयन है analogWrite()। यह केवल 9 और 10 पिन पर काम करता है, क्योंकि ये 16-बिट टाइमर से जुड़े एकमात्र पिन हैं।

/* Configure digital pins 9 and 10 as 16-bit PWM outputs. */
void setupPWM16() {
    DDRB |= _BV(PB1) | _BV(PB2);        /* set pins as outputs */
    TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                   /* mode 14: fast PWM, TOP=ICR1 */
    TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS10);                    /* no prescaling */
    ICR1 = 0xffff;                      /* TOP counter value */
}

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
    switch (pin) {
        case  9: OCR1A = val; break;
        case 10: OCR1B = val; break;
    }
}

आप देख सकते हैं कि काउंटर अनुक्रम का शीर्ष स्पष्ट रूप से कॉन्फ़िगर किया गया है। घटी हुई रिज़ॉल्यूशन की कीमत पर, PWM को तेज़ बनाने के लिए आप इसे छोटे मूल्य में बदल सकते हैं।

और यहाँ एक उदाहरण स्केच है जो इसके उपयोग को दर्शाता है:

void setup() {
    setupPWM16();
}

/* Test: send very slow sawtooth waves. */
void loop() {
    static uint16_t i;
    analogWrite16(9, i);
    analogWrite16(10, 0xffff - i);
    i++;
    delay(1);
}

वाह बहुत बहुत धन्यवाद, यह वही है जो मुझे चाहिए। मैं चाहता हूं कि मेरा PWM परिणाम मेरे सेंसर रिज़ॉल्यूशन के समान हो। अगर मैं आपका कोड बदलकर <संपादित करें> देखूं तो क्या यह 13-बिट परिणाम होगा? यदि हां, तो आवृत्ति क्या होगी? मैं इसके साथ एक डीसी मोटर चला रहा हूँ, इसलिए 244Hz थोड़ा कम होगा मुझे लगता है
KoenR

@ नोनी: नहीं, रिज़ॉल्यूशन का रिज़ॉल्यूशन पर कोई प्रभाव नहीं पड़ता है, इसका उद्देश्य गिनती को धीमा करना है। 8 को प्रीस्कूलर सेट करना आपको 30.5 हर्ट्ज की पीडब्लूएम आवृत्ति प्रदान करेगा। यदि आप 13 बिट रिज़ॉल्यूशन चाहते हैं, पर सेट ICR1है 0x1fff, तो आपकी आवृत्ति 1953 हर्ट्ज (F_CPU / (TOP + 1) होगी, जिसमें 1 पर प्रीस्कूलर होगा।
Edgar Bonet

विवरण के लिए आपका धन्यवाद। मेरे प्रश्न का संपादन किया ताकि यह इन गलतियों को कवर करे। तो अन्य लोग इसे सीधे देख सकते हैं। धन्यवाद!
कोएनआरआर

1
@Edgar Bonet यह बहुत अच्छा है, हालाँकि मैं एक एलईडी को पूरी तरह से बंद नहीं कर सकता। मैं का उपयोग कर रहा हूँ ICR1 = 0x03FFऔर 0 पर मैं गुंजाइश को हल्का करने के लिए पर्याप्त पर एक छोटी सी नाड़ी देख रहा हूँ। कोई विचार?
डेविविड

1
@davivid: हां, आपके पास शून्य शुल्क चक्र नहीं हो सकता है। analogWrite16(pin, val)(val + 1) / ICR1 का एक कर्तव्य चक्र देता है। वर्कअराउंड के रूप में, अर्डुइनो analogWrite()करता है if (val == 0) digitalWrite(pin, LOW); else if (val == 255) digitalWrite(pin, HIGH);। लेकिन तब आपको 1 / ICR1 का शुल्क चक्र नहीं मिल सकता है ...
एडगर बोनट

3

कुछ अंशांकन के साथ आप दो PWM चैनलों के आउटपुट को अलग-अलग भार प्रतिरोधों के साथ जोड़ सकते हैं। चरम पर आप 8 आउटपुट प्रदान करने के लिए एक आउटपुट का उपयोग नहीं कर सकते हैं और दूसरे को 1/256 के स्तर पर स्केल कर सकते हैं और उन्हें जोड़ सकते हैं इसलिए 2 चैनल एक बिट रेंज को कवर करता है और आपको (फिर से उल्लेखनीय रूप से) 16 बिट्स रिज़ॉल्यूशन मिलता है। अपार देखभाल और समायोजन के बिना आपको मिलने वाला सब गड़बड़ हो जाएगा।
हालाँकि, 2 चैनल को 16 या 32 से विभाजित करके आप PWM रिज़ॉल्यूशन के कई अतिरिक्त बिट्स जोड़ सकते हैं। बस 2 पीडब्लूएम चैनल एनालॉग फ़िल्टर किए गए आउटपुट को जोड़कर आप एक अतिरिक्त बिट जोड़ते हैं (जैसा कि अपरिवर्तित एमवी / बिट के लिए संभावित सीमा दोगुनी है)।
2 से प्रत्येक अतिरिक्त विभाजन के लिए विशेष रूप से (फिर से) आपको रिज़ॉल्यूशन का एक अतिरिक्त बिट मिलता है, लेकिन यह केवल 4 या 5 या 6 अतिरिक्त बिट्स के लिए किया जा सकता है, प्रतिरोधों को स्केल करने की सटीकता आवश्यकताओं और अधिक कठिन अंशांकन और त्रुटियों के लिए स्पष्टता के साथ। ।

संक्षिप्त उदाहरण।
यदि एक PWM को 1 mV चरण में 0 - 255 mV कहने के लिए छोटा किया जाता है, तो समान आयाम वाले दो PWM को 1 mV चरणों में 0 - 510 mV श्रेणी दें।
यदि एक पीडब्लूएम को 32 के कारक से घटाया जाता है, तो प्रारंभिक पीडब्लूएम श्रेणी में 255 एमवी जोड़ने के बजाय यह शीर्ष अंत में केवल 8 एमवी जोड़ देगा (0.256.32 = 8 एमवी, लेकिन रिज़ॉल्यूशन 0.03125 (1/32 वें) में होगा ) एमवी कदम।

हालांकि यह संभवत: प्रतिरोधक योग और आरसी फ़िल्टरिंग के साथ पूरी तरह से प्राप्त किया जा सकता है, लेकिन एक सेशन amp गर्मियों के उपयोग से परिणामों में बहुत सुधार होगा।

PWM तरंग को एक साधारण RC फ़िल्टर के साथ फ़िल्टर किया जा सकता है, लेकिन बफर के रूप में एक opamp का उपयोग (या यहां तक ​​कि एक एमिटर अनुयायी के रूप में एक एकल ट्रांजिस्टर) आपको कम पास फ़िल्टरिंग के 3 या 5 डंडे देगा और अतिरिक्त PWM प्राप्त करने का बेहतर मौका मिलेगा। संकल्प। मैंने PWM आउटपुट के "चरण सुसंगतता" का निरीक्षण नहीं किया है, लेकिन उम्मीद है कि वे सापेक्ष लॉकस्टेप में चलते हैं ताकि आपको दो असंबंधित तरंगों को जोड़ने का सहज लाभ न मिले।

जरूरत पड़ने पर और भी कमेंट किए जा सकते हैं। रुचि हो तो पूछें।


यह चतुर है! ऐसा लगता है कि Mozzi ध्वनि संश्लेषण पुस्तकालय इस चाल का उपयोग करता है इसलिए इसे "HIFI" मोड कहा जाता है।
एडगर बोनट

यह पीडब्लूएम का एक बेहतरीन उदाहरण है। लेकिन इस तरंग को सुचारू नहीं करेगा? मैं आपसे यह पूछ रहा हूँ क्योंकि आप RC फ़िल्टर का उपयोग कर रहे हैं। यह मेरे सवाल में उल्लेख नहीं किया है, लेकिन मैं इसके साथ एक डीसी मोटर चला रहा हूं <शर्म आ रही है>। इनपुट के लिए धन्यवाद!
KoenR

@Koenr (fwiw: मुझे कुछ भी शर्म नहीं आती।) मुझे नहीं पता कि आपके ADC आउटपुट में परिवर्तन की आवृत्ति / दर क्या चाहते हैं। या आप एन बिट्स क्यों चाहते हैं या कितना बड़ा है। मोटर्स को आमतौर पर 8 से अधिक बिट्स द्वारा उपयोगी रूप से नियंत्रित नहीं किया जाएगा - यह निर्भर करता है कि आपके पास कितना सटीक अनुप्रयोग है। मोटर अधिष्ठापन के कारण एक चौरसाई फिल्टर के हिस्से के रूप में कार्य करता है। आपको यह कहने की ज़रूरत है कि किस प्रकार की मोटर और कैसे संचालित होती है। और एक सर्किट आरेख आवश्यक है। जब तक मोटर छोटी न हो, आपके पास ड्राइवर हो। पीडब्लूएम बंद होने पर मोटर चालू करने के लिए ब्रश किए गए मोटर पीडब्लूएम को आ कैच डायोड होना चाहिए। दो जोड़ना ...
रसेल मैकमोहन

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

सावधान रहें! कुछ मामलों में, कम पास आरसी के साथ पीडब्लूएम को चौरसाई करना वांछनीय नहीं है। उदाहरण के लिए, यदि आप Arduino आउटपुट को MOSFET के गेट में प्लग करते हैं, तो MOSFET तब तक ठंडा रहेगा जब तक कि यह साफ PWM द्वारा संचालित होता है। लेकिन अगर आप इसे सुचारू करते हैं, तो MOSFET बहुत अधिक गर्मी को नष्ट करना शुरू कर देगा। कभी-कभी यह अच्छी बात नहीं है।
फ्लोरिन आंद्रेई
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.