View previous topic :: View next topic |
Author |
Message |
capella
Joined: 07 Feb 2009 Posts: 38
|
pwm motor control via pc? |
Posted: Wed Jun 09, 2010 9:28 am |
|
|
hello
pwm motor control does not work correctly. I want to control motor with pwm via pc keyboard. When I press 1 ,2,3,4 or 5 . each number must be different motor speed value. So I search and try and I prepared a circuit and I try to write a code. But everytime motor speed same even I press different number 1 from 5. please help me. my circuit and code as below
Code: | #include <16F877.h>
#FUSES HS,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
void main()
{
byte duty;
char a ;
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16,124,1);
while(true)
{
if (kbhit())
{
a=getch();
if (a=='1')
{
delay_ms(100);
duty = 31;
set_pwm1_duty(duty);
}
if (a=='2')
{
delay_ms(100);
duty = 62;
set_pwm1_duty(duty);
}
if (a=='3')
{
delay_ms(100);
duty = 124;
set_pwm1_duty(duty);
}
if (a=='4')
{
delay_ms(100);
duty = 256;
set_pwm1_duty(duty);
}
if (a=='5')
{
delay_ms(100);
duty = 512;
set_pwm1_duty(duty);
}
}
}
} |
|
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Jun 09, 2010 9:31 am |
|
|
Does this seem right to you?
Code: |
byte duty;
//and later on
duty = 512;
|
|
|
|
capella
Joined: 07 Feb 2009 Posts: 38
|
|
Posted: Wed Jun 09, 2010 10:00 am |
|
|
I tried as int or long result is same |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Jun 09, 2010 10:18 am |
|
|
Let's assume you are using 8bit PWM for now.
You have this:
Code: |
setup_timer_2(T2_DIV_BY_16,124,1);
|
which means if duty = 124 you get 100% duty cycle already. So a lot of your code will not work. You need to make duty between zero and 124 to get 0 to 100% duty cycle.
IF you want more resolution you need 10 bit pwm. In this case you have to declare duty as type int16 equivalently long. The actual duty cycle would be DC = (duty/4) / 124. For example you can have:
Code: |
int16 duty = 62;
set_pwm1_duty(duty); //gives 12.5% duty cycle
|
or
Code: |
int16 duty = 248;
set_pwm1_duty(duty); //gives 50% duty cycle
|
|
|
|
capella
Joined: 07 Feb 2009 Posts: 38
|
|
Posted: Thu Jun 10, 2010 1:06 am |
|
|
I changed my code as your suggestion, but motor speed is same when I press 2 or 4, and cycle seems same, not change. so my problem continue. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Thu Jun 10, 2010 6:40 am |
|
|
Your PWM is at about 500 Hz. Is that what you want ? |
|
|
capella
Joined: 07 Feb 2009 Posts: 38
|
|
Posted: Thu Jun 10, 2010 8:53 am |
|
|
actually my problem is that:
I want to drive motor with pwm via pc. Only when we pressed buttons from 1 to 5. Motor speed must be change. In other cases dc motor must not work, only motor must work with pc keyboard. What is your code suggestion. It is not important 500 Hz. Important things motor speed control and motor speed must be from slowest to fastest. Yes I am waiting your suggestions. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Thu Jun 10, 2010 9:55 am |
|
|
You have to take it one step at a time.
Forget the PC for now. Try setting the PWM to 50% duty cycle, probe the output with a scope and see whether you get the right waveform. Then try setting the duty cycle to 12.5% for example and repeat the experiment. Once you verified that the PIC is giving the right output you can try to incorporate the PC.
Also, if it is a DC motor you probably have to RC filter the output of the PWM (something like a 10K and 1uF).
Also, shouldn't Vs- on the MAX232 go straight to GND? It looks like you have it going to C4 and the other side of C4 to GND. Vs+ should go to C3 AND go to the positive supply. The other side of C3 should go to GND. |
|
|
Abdulla M.A.
Joined: 28 Mar 2010 Posts: 30 Location: Baghdad, Iraq
|
|
Posted: Thu Jun 10, 2010 11:42 am |
|
|
mkuang wrote: | Let's assume you are using 8bit PWM for now.
You have this:
Code: |
setup_timer_2(T2_DIV_BY_16,124,1);
|
which means if duty = 124 you get 100% duty cycle already. So a lot of your code will not work. You need to make duty between zero and 124 to get 0 to 100% duty cycle.
|
Hi guys, there is no a direct relation between the duty and 124,
because the 124 represent the a value place in PR2 register, i.e.
determine the PWM period. CCPR1L is responsible about
the duty cycle. _________________ "A scientist can discover a new star, but he cannot make one. He would have to ask an engineer to do that."
"For an optimist the glass is half full, for a pessimist it's half empty, and for an engineer is twice bigger than necessary." |
|
|
Abdulla M.A.
Joined: 28 Mar 2010 Posts: 30 Location: Baghdad, Iraq
|
|
Posted: Thu Jun 10, 2010 11:49 am |
|
|
@capella
You connected C4 in reverse form, the negative terminal should connect
to Pin6 instead of the positive terminal.
You do not need to connect two transistors to drive the D.C motor, just
one FET will be ok, like VN66.
Now, correct your circuit and tell us about the results.
Abdulla _________________ "A scientist can discover a new star, but he cannot make one. He would have to ask an engineer to do that."
"For an optimist the glass is half full, for a pessimist it's half empty, and for an engineer is twice bigger than necessary." |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 10, 2010 11:56 am |
|
|
Quote: | Hi guys, there is no a direct relation between the duty and 124, |
This is wrong. There is a direct relationship between the duty cycle
and the middle value in the setup_timer_2() function.
See this post for the equation:
http://www.ccsinfo.com/forum/viewtopic.php?t=42417&start=3 |
|
|
capella
Joined: 07 Feb 2009 Posts: 38
|
|
Posted: Fri Jun 11, 2010 2:27 am |
|
|
I can see motor speed that:
Code: |
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main()
{
char a;
int pwm_duty;
output_low(pin_c2);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 127, 1);
pwm_duty =16;
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =32;
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =64;
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =127;
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =128;
set_pwm1_duty(pwm_duty);
while(1);
}
|
but when I tried that
Code: |
#include <16F877.h>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
void main()
{
char a;
int pwm_duty;
output_low(pin_c2);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_16, 127, 1);
while(true)
{
if (kbhit())
a=getch();
if (a=='1')
{
pwm_duty =16;
set_pwm1_duty(pwm_duty);
delay_ms(200);
}
if (a=='2')
{
pwm_duty =32;
set_pwm1_duty(pwm_duty);
delay_ms(200);
}
if (a=='3')
{
pwm_duty =64;
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =127;
}
if(a=='4')
{
set_pwm1_duty(pwm_duty);
delay_ms(200);
pwm_duty =128;
set_pwm1_duty(pwm_duty);
}
}
}
}
|
I could not control motor speed with pc keyboard. What is wrong? I just want to motor speed with keyboard. Only my problem is that I can not control motor speed via pc keyboard. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Fri Jun 11, 2010 7:21 am |
|
|
It has been pointed out that your RS232 chip is not connected properly. Therefore you cannot possibly be getting the correct input from your PC. You are never getting a kbhit() so none of your set_pwm_duty code ever gets executed. Please correct the power and ground connections on the RS232 chip. You will be surprised to see how well it works if you wired everything correctly. |
|
|
capella
Joined: 07 Feb 2009 Posts: 38
|
|
Posted: Fri Jun 11, 2010 9:22 am |
|
|
All of the connections are ok. And also in proteus and real circuit dont work correctly. Why? |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Fri Jun 11, 2010 9:28 am |
|
|
capella wrote: | All of the connections are ok. And also in proteus and real circuit dont work correctly. Why? |
Take a voltmeter and check to see whether you get -10V or so on V- and +10V on V+. |
|
|
|