আমি একটি অপেক্ষাকৃত "সহজ" প্রকল্পে কাজ করছি যেখানে প্রশস্ততা এবং ফ্রিকোয়েন্সিতে পরিবর্তিত একটি সাইন ওয়েভের ফ্রিকোয়েন্সি পরিমাপ করা দরকার। জিনিসগুলিকে সরল করার জন্য, আপাতত, আমি কেবলমাত্র একটি স্থির ফ্রিকোয়েন্সি পেয়েছি (27Hz) সাইন ওয়েভ ইনপুট (তুলনাকারীর নেতিবাচক ইনপুট) যা কেবল প্রশস্ততা (পেন্টিওমিটার ব্যবহার করে) বিভিন্ন হতে পারে। তুলনাকারীর ইতিবাচক ইনপুটটি ভিসি / 2 তে সেট করা আছে। কম্পেটারের আউটপুটটি তখন ফ্রিকোয়েন্সি পরিমাপ করতে atmega2560 মাইক্রোকন্ট্রোলারের ইনপুট ক্যাপচার রেজিস্টারে খাওয়ানো হয়।
সমস্যাটি হ'ল ইনপুট সিগন্যালের নির্দিষ্ট প্রশস্ততায় আমি আউটপুটে বেশ তীব্র টগলিং (বা কখনও কখনও ডেড ব্যান্ডগুলি) পাই যা দেখতে এটির মতো দেখায়:
যেখানে প্রত্যাশিত আউটপুটটিকে কিছু দেখতে হবে:
আমি এখন পর্যন্ত যে জিনিসগুলি চেষ্টা করেছি:
অভ্যন্তরীণ atmega2560 এর অভ্যন্তরীণ তুলনামূলক ব্যবহার করে। একটি বাহ্যিক তুলক ব্যবহার করে। সফ্টওয়্যার এবং স্মিট ট্রিগার সার্কিট ব্যবহার করে হিস্টেরেসিসের পরিচয় দেওয়া হচ্ছে। নির্দিষ্ট রেফারেন্স সেটআপ এবং ডেটা স্লিকার সেটআপ সহ বিভিন্ন ইনপুট সেটআপ চেষ্টা করে। বিভিন্ন এমেগা 2560 এর চেষ্টা করে। বিভিন্ন ঘড়ির গতি চেষ্টা করা।
কিছু সমাধান অন্যদের তুলনায় আরও স্থিতিশীল ছিল, তবে সেগুলির কোনওটিই গ্রহণযোগ্যতার কাছাকাছি ছিল না। আমি এখন পর্যন্ত সবচেয়ে স্থিতিশীল কনফিগারেশন নিয়ে স্থির হয়েছি:
এই সেটআপের সাহায্যে কিছু কিছু স্থিতিশীলতার উন্নতি / পরিবর্তন করে, তবুও নিখুঁত কাছাকাছি কোথাও নেই:
হিস্টেরেসিস বাড়ানোর জন্য আর 5 এর মান পরিবর্তন করা। সি 2 পুরোপুরি সরানো হচ্ছে (কেন জানি না)। ব্রেডবোর্ডে তারগুলি স্পর্শ করা (একে অপরের পাশে বেশ কয়েকটি)। বাহ্যিক থেকে ইউএসবিতে বিপরীতে বিদ্যুত সরবরাহ সরবরাহ করা হচ্ছে।
এই মুহুর্তে, এটি হয় শব্দ হয়, আমার ড্যাক যা দিয়ে আমি সাইন ওয়েভ তৈরি করছি বা আমি ভুলভাবে খুব মৌলিক কিছু করছি। এই সার্কিটটি কোনও সমস্যা ছাড়াই অন্য ব্যক্তির পক্ষে কাজ করেছে, তাই আমার কনফিগারেশন বা পরিবেশের সাথে অবশ্যই কিছু ভুল হতে হবে।
কারও কাছে যদি কোনও পরামর্শ থাকে তবে আমি আপনার সময়ের প্রশংসা করব।
এখানে আমার ন্যূনতম উত্স:
#include <avr/io.h>
void init(void);
void init(void) {
/* Setup comparator */
ACSR = (1 << ACIE) | (1 << ACIS1);
/* Initialize PORTD for PIND5 */
DDRD = 0x00;
PORTD = 0x00;
/* Enable global interrupts */
sei();
}
int main(void) {
init();
while (1) {}
}
ISR(ANALOG_COMP_vect) {
if (!(ACSR & (1<<ACIS0))) { //comparator falling edge
/* Set PIND5 to 0V */
PORTD &= ~(1 << PIND5);
ACSR |= (1<<ACIS0); //set next comparator detection on rising edge
}
else {
ACSR &= ~(1<<ACIS0); //set next comparator detection on falling edge
/* Set PIND5 to 5V */
PORTD |= (1 << PIND5);
}
}
এছাড়াও, এখানে সার্কিট চিত্র এবং লাইব্রেরির লিঙ্কটি রয়েছে:
http://interface.khm.de/index.php/lab/interfaces-advanced/frequency-measurement-library/
হালনাগাদ:
আমি আপনার সমস্ত পরামর্শ চেষ্টা করেছি, সেগুলির মধ্যে একটিও কাজ করে নি। বিঘ্নিত পতাকা সাফ করা বা আইএসআরের অভ্যন্তরে বা বাইরের বিঘ্নগুলি অক্ষম করা সত্যিই কোনও প্রভাব ফেলেনি। চিপের তুলনামূলক রেজিস্ট্রেশন আসলে কীভাবে কাজ করে তা আমি ভুল বুঝেছি বলে মনে হচ্ছে।
আমি প্রথমদিকে যেমন উল্লেখ করেছি, আমি সাইন ওয়েভ থেকে প্রাপ্ত বর্গাকার তরঙ্গের ফ্রিকোয়েন্সি পরিমাপ করতে ইনপুট ক্যাপচার ব্যবহার করতে যাচ্ছিলাম। তুলনাকারীর আউটপুট ইনপুট ক্যাপচার পিনে খাওয়ানো হয়, তারপরে পিরিয়ড পরিমাপ করতে টাইমারগুলি ব্যবহার করুন, সহজ।
এটিমেগা 2560 http://ww1.microchip.com/downloads/en/DiviceDoc/Atmel-2549-8-bit-AVR-Microcontroller-ATmega640-1280-1281-2560-2561_datasheet.pdf , পৃষ্ঠা 265 এর এনালগ তুলনামূলক চিত্রটি এখানে রয়েছে :
যেমন আপনি দেখতে পাচ্ছেন, তুলনাকারীর দুটি আউটপুট রয়েছে, এসিও এবং এসিআইএস 0 + এসিআইএস 1। + ইনপুট> - ইনপুট, + ইনপুট <- ইনপুট যখন সাফ করা হয় তখন এসিও সেট করা হয়। ACIS0 + ACIS1 হ'ল প্রান্ত নির্বাচন বিট।
আমি প্রথমে যা করছিলাম তা আমার আইএসআরের প্রান্তের ধরণটি যাচাই করছিলাম। আমি পরিবর্তে আইএসআর এ পরিবর্তন করেছি:
ISR(ANALOG_COMP_vect) {
if (!(ACSR & (1<<ACO))) { // + < -
/* Set PIND5 to 0V */
PORTD &= ~(1 << PIND5);
}
else {
/* Set PIND5 to 5V */
PORTD |= (1 << PIND5);
}
}
এবং আউটপুট নির্দোষভাবে নিজেকে আচরণ করে (ঠিক দ্বিতীয় চিত্রের মতো)। তারপরে আমি ডালের প্রস্থ পরিমাপ করতে এগিয়ে গেলাম তবে ফলাফল খুব ভাল হয়নি। আমার এলসিডি ডিসপ্লেতে তীব্র টগলিং, পরিচ্ছন্ন সংকেত থাকা সত্ত্বেও সংখ্যাগুলি এলোমেলো মানগুলিতে ঝাঁপিয়ে পড়ে বা 0 এ থাকে। আমি বিভিন্ন অবস্থার ব্যবহার করে আমার কোডটি বহুবার পুনরায় লিখেছি, আমি এখন পর্যন্ত প্রাপ্ত একমাত্র আধা-স্থিতিশীল সমাধানটি হ'ল:
#include <avr/io.h>
#include <util/delay.h>
#include "UART.h"
void init(void);
volatile uint16_t y = 0;
volatile uint16_t x = 0;
volatile uint16_t current_value = 0;
volatile uint16_t previous_value = 0;
volatile uint16_t total = 0;
void init(void) {
/* Normal mode, 64 prescaler, Rising Edge trigger, Input Capture */
TCCR1A = 0;
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << ICES1);
TIMSK1 = (1 << ICIE1);
ACSR = (1 << ACIC);
ADCSRB = 0x00;
/* This port is used for simulating comparator's output */
DDRC = 0xFF;
PORTC = 0xFF;
DDRD = 0x00;
PORTD = 0x00;
USART_Init(UBRR_VALUE);
sei();
}
int main(void) {
init();
while (1) {
if (TCNT1 == 60000) {
/* Display the values on the LCD */
USART_Transmit(0xFE);
USART_Transmit(0x01);
USART_Transmit_Double(x+y);
}
}
}
ISR(TIMER1_CAPT_vect) {
//ACSR &= ~(1<<ACIC);
if (!(ACSR & (1 << ACO))) {
if (!(TCCR1B & (1 << ICES1))) { // check for falling edge
PORTD |= (1 << PIND5);
PORTC &= ~(1 << PINC1);
TCCR1B |= (1 << ICES1);
current_value = ICR1;
x = current_value - previous_value;
previous_value = current_value;
}
}
else {
if (TCCR1B & (1 << ICES1)) { // check for rising edge
PORTD &= ~(1 << PIND5);
PORTC |= (1 << PINC1);
TCCR1B &= ~(1 << ICES1);
current_value = ICR1;
y = current_value - previous_value;
previous_value = current_value;
}
}
//ACSR |= (1<<ACIC);
}
অর্ধ-স্থিতিশীল দ্বারা আমি বোঝাতে চাইছি, আমি সময়ের সঠিক 1/3 অংশ পাই। অন্যান্য সময়গুলির 2/3 বার এটি সঠিক মানের অর্ধেক বা এলোমেলো মানের হয়। আমি শর্তাধীন বিবৃতি হিসাবে টাইমারের রেজিস্টার বিটগুলি পাশাপাশি আমার আইএসআরে তুলনাকারীর রেজিস্টার বিটগুলি ব্যবহার করার চেষ্টা করেছি, এটি একমাত্র কনফিগারেশন যা এই ধরণের কাজ করে।
দিনের পরে আমি যা করেছি তা হ'ল অভিন্ন সেটআপ এবং উত্স (তুলকের সাথে সম্পর্কিত সমস্ত লাইন বাদে) পরিবর্তে একটি বাহ্যিক তুলক ব্যবহার করা হয়েছিল। এর আউটপুট ইনপুট ক্যাপচার পিনে খাওয়ানো হয়েছিল এবং এটি যেমন ইচ্ছা তেমন কাজ করেছিল (এমনকি কোনও হিস্টেরিসিসের প্রয়োজনও হয়নি)।
এই মুহুর্তে আমি বলতে পারি যে আমি এটি একটি বহিরাগত তুলনামূলক ব্যবহার করে সমাধান করেছি তবে কেন অভ্যন্তরীণ কেন নিজে আচরণ করে না আমার কোনও ধারণা নেই। আমি এ সম্পর্কে অনেকগুলি পোস্ট এবং গাইড পড়েছি, বিভিন্ন গ্রন্থাগার পড়েছি, কোনও গ্রহণযোগ্য ফলাফল ছাড়াই তাদের অনুকরণ করার চেষ্টা করেছি। পুরো তুলনামূলক ইউনিটে ডেটাশিটে কেবল 5 টি পৃষ্ঠা রয়েছে, আমি এটি বহুবার পুনরায় পড়ি এবং আমি কী ভুল করছি তা আমি দেখতে পাই না।
আমি কীভাবে এটি সঠিকভাবে ব্যবহার করতে হয় তা সন্ধান করতে চাই তবে যদি এটি ব্যর্থ হয় তবে আমি একটি ব্যাকআপ পেয়েছি। আপনার যদি আরও কোনও ইনপুট থাকে তবে এটি প্রশংসিত।