
به نام خدا
کنترل موتور دی سی با ریموت کنترل و آردوینو

در این آموزش کنترل سرعت و جهت گردش موتور DC را بوسیله ریموت کنترلر IR (اینفرارد) و آردوینو یاد خواهیم گرفت. در این آموزش از ریموت کنترل پخش کننده صوتی ماشین استفاده شده، این ریموت از پرتوکل NEC استفاده می کند.
در ابتدا باید کد های ریموت کنترلر را پیدا کنیم، ما قبلا کد های ریموت کنترلر مان را پیدا کرده ایم.اگر از ریموت دیگری استفاده میکنید ابتدا کد هایش را رمزگشایی کنید.

در این پروژه از ۳ دکمه ۱ ، ۲ و ۳ استفاده شده. کد های دکمه و کارکرد آنها را در زیر می بینید:(اندازه کد های ریموت کنترل NEC 32 بیتی است)
| Button Number | Function | Code |
|---|---|---|
| ۱ | Change direction | ۰x40BF30CF |
| ۲ | Speed down | ۰x40BFB04F |
| ۳ | Speed up | ۰x40BF708F |
قطعات مورد نیاز کنترل موتور دی سی با ریموت کنترل و آردوینو :
- آردوینو UNO
- درایور موتور L293D
- موتور ۱۲ ولت DC
- ریموت کنترل (IR (NEC protocol
- گیرنده IR
- خازن ۴۷ میکرو فاراد
- منبع تغذیه ۱۲ ولت
- برد بورد
- سیم برد بورد
شماتیک مدار کنترل موتور دی سی با ریموت کنترل و آردوینو :
شماتیک مدار پروژه را در زیر مشاهده می کنید.

گیرنده اینفرارد (IR) برای دریافت سیگنال های ریموت کنترلر استفاده می شود. این گیرنده ۳ پایه GNF , VCC , OUT دارد و به وسیله پایه ۵ ولت آردوینو تغذیه می شود. پایه OUT نیز به پین ۲ آردوینو متصل می شود.
درایور L293D از دو منبع متفاوت تغذیه می شود، اولی (VCC1) و از پایه ۵ ولت آردوینو گرفته می شود و دومی (VCC2) که از منبع تغذیه ۱۲ ولت می آید و ولتاژ نامی موتور است.
کد های کنترل موتور دی سی با ریموت کنترل و آردوینو:
برای کد های این پروژه از کتابخانه ای استفاده نکرده ایم ، تغییرات سرعت و جهت چرخش با وقفه ای که به پایه ۲ وارد میشود صورت میگیرد.
اندازه سیگنال که به آردوینو فرستاده می شود ۳۲ بیت است. در این پروژه از تایمر ۱ برای اندازه گیری پالس ها استفاده شده و به گونه ای تنظیم شده است که هر میکروثانیه دو واحد افزایش پیدا می کند.
دانلود کد کنترل موتور دی سی با ریموت کنترل و آردوینو :
دانلود فایل// Arduino remote controlled DC motor (speed and direction control)
// NEC IR remote control is used (Car MP3)
#define pwm1 5
#define pwm2 6
boolean nec_ok = 0, motor_dir = 0, repeated = 0;
byte i, nec_state = 0, duty_cycle = 0;
unsigned long nec_code;
void setup() {
pinMode(pwm1, OUTPUT);
pinMode(pwm2, OUTPUT);
// Timer1 module configuration
TCCR1A = 0;
TCCR1B = 0; // Disable Timer1 module
TCNT1 = 0; // Set Timer1 preload value to 0 (reset)
TIMSK1 = 1; // enable Timer1 overflow interrupt
attachInterrupt(0, remote_read, CHANGE); // Enable external interrupt (INT0)
}
void remote_read() {
unsigned int timer_value;
if(nec_state != 0){
timer_value = TCNT1; // Store Timer1 value
TCNT1 = 0; // Reset Timer1
}
switch(nec_state){
case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse)
TCNT1 = 0; // Reset Timer1
TCCR1B = 2; // Enable Timer1 module with 1/8 prescaler ( 2 ticks every 1 us)
nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space)
i = 0;
return;
case 1 : // End of 9ms pulse
if((timer_value > 19000) || (timer_value < 17000)){ // Invalid interval ==> stop decoding and reset
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else
nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse)
return;
case 2 : // End of 4.5ms space
if((timer_value > 10000) || (timer_value < 3000)){
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
else{
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
if(timer_value < 6000) // Check if previous code is repeated
repeated = 1;
}
return;
case 3 : // End of 562µs pulse
if((timer_value > 1400) || (timer_value < 800)){ // Invalid interval ==> stop decoding and reset
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
}
else {
// Check if the repeated code is for button 2 or 3
if(repeated && (nec_code == 0x40BFB04F || nec_code == 0x40BF708F)){
repeated = 0;
nec_ok = 1; // Decoding process is finished with success
detachInterrupt(0); // Disable external interrupt (INT0)
}
else
nec_state = 4; // Next state: end of 562µs or 1687µs space
}
return;
case 4 : // End of 562µs or 1687µs space
if((timer_value > 3600) || (timer_value < 800)){ // Time interval invalid ==> stop decoding
TCCR1B = 0; // Disable Timer1 module
nec_state = 0; // Reset decoding process
return;
}
if( timer_value > 2000) // If space width > 1ms (short space)
bitSet(nec_code, (31 - i)); // Write 1 to bit (31 - i)
else // If space width < 1ms (long space)
bitClear(nec_code, (31 - i)); // Write 0 to bit (31 - i)
i++;
if(i > 31){ // If all bits are received
nec_ok = 1; // Decoding process OK
detachInterrupt(0); // Disable external interrupt (INT0)
return;
}
nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space)
}
}
ISR(TIMER1_OVF_vect) { // Timer1 interrupt service routine (ISR)
nec_state = 0; // Reset decoding process
TCCR1B = 0; // Disable Timer1 module
}
void loop() {
if(nec_ok) {
nec_ok = 0; // Reset decoding process
nec_state = 0;
TCCR1B = 0; // Disable Timer1 module
if(nec_code == 0x40BF30CF){ // If button 1 is pressed (change motor direction of rotation)
motor_dir = !motor_dir; // Toggle direction variable
if(motor_dir)
digitalWrite(pwm2, 0);
else
digitalWrite(pwm1, 0);
}
if(nec_code == 0x40BF708F && duty_cycle < 255) // If button 3 is pressed (increase motor speed)
duty_cycle++;
if(nec_code == 0x40BFB04F && duty_cycle > 0) // If button 2 is pressed (decrease motor speed)
duty_cycle--;
if(motor_dir)
analogWrite(pwm1, duty_cycle);
else
analogWrite(pwm2, duty_cycle);
attachInterrupt(0, remote_read, CHANGE); // Enable external interrupt (INT0)
}
}
با سلام
چجوری کدهای ریموت رو پیدا کنیم
سلام
متوجه منظورتون نمیشم... کد ها که موجود هست توی صفحه سایت