|
|
View previous topic :: View next topic |
Author |
Message |
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
Help me take a look on my code what error in it |
Posted: Fri Jul 15, 2011 3:15 am |
|
|
Code: | #include<18F4520.h>
#DEVICE ADC=8
#fuses HS,NOWDT,NOPROTECT,NOLVP, BROWNOUT, PUT
#use delay(clock=4000000)
#include "C:\Program Files (x86)\PICC\Drivers\flex_lcd.c"
#define data_width 3
int8 AccData[data_width];
void main(void)
{
int i;
//long value;
output_high(LCD_POWER); // Turn on power to LCD
output_low(LCD_RW);
lcd_init();
setup_adc(ADC_CLOCK_INTERNAL);//enables the a/d module
//and sets the clock to internal adc clock
setup_adc_ports(AN0_TO_AN2); //set the adc pins to analog
output_low(PIN_C1); // Set CCP2 output low
output_low(PIN_C2); // Set CCP1 output low
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
setup_ccp2(CCP_PWM); // Configure CCP2 as a PWM
enable_interrupts(int_timer2);
enable_interrupts(GLOBAL);
setup_timer_2(T2_DIV_BY_16, 250, 5);
while(1)
{
disable_interrupts(int_timer2);
disable_interrupts(GLOBAL);
for(i = 0; i < data_width; i++)
{
delay_us(10); //a small delay is required after setting the channel
set_adc_channel(i);
AccData[i] = read_adc(); //starts the conversion
}
lcd_gotoxy(1,1);
printf(lcd_putc, "x = %u y = %u ", AccData[0], AccData[1]);
lcd_gotoxy(1,2);
printf(lcd_putc, "z = %u ", AccData[2]);
delay_ms(10);
enable_interrupts(int_timer2);
enable_interrupts(GLOBAL);
output_low(PIN_D0);
output_low(PIN_D1);
// set_pwm1_duty(125); // 50% duty cycle on pin C2
// set_pwm2_duty(63); // 25% duty cycle on pin C1
}
}
#int_timer2
void ISR_Timer2()
{
output_high(PIN_D0);
delay_us(2000);
output_high(PIN_D1);
delay_us(500);
}
|
When I program it into the PIC board, the LCD show the x,y,z of the accelerometer. When I connect the SERVO MOTOR to pin D1/D0, the LCD will show black screen, all value gone. |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Fri Jul 15, 2011 6:38 am |
|
|
Tell us more about this servo motor. What type is it? Can you give us a link to a datasheet? How does it connect to the PIC?
Also why do you have long delays inside your timer interrupt? This is usually a bad idea. Interrupts want to do something quick and get out as fast as possible. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
Posted: Fri Jul 15, 2011 7:04 am |
|
|
Why you said that is a bad idea? Please teach me, i'm newbie, learning the CCS in this forum, no people teach =.=
Code: | setup_timer_2(T2_DIV_BY_16, 250, 5); //4ms, postscale 5 = 5*4ms=20ms(see in the occilloscope) |
Code: | #int_timer2
void ISR_Timer2()
{
output_high(PIN_D0);
delay_us(2000);
output_high(PIN_D1);
delay_us(500);
} |
output is 20ms period, D0 is 2ms high, 18ms low, D1 is 0.5ms high 19.5ms low |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Fri Jul 15, 2011 9:52 am |
|
|
Think of it by analogy.
Interrupts are designed to give rapid responses to something happening (like perhaps you returning a tennis ball, when a serving machine fires it at you).
Imagine what would happen, if when you received the first ball, you stopped and had a cup of tea (equivalent to delays in the interrupt). The subsequent balls would always be missed, and you'd probably end up spilling the tea as well.....
Key with interrupts, is always to do the _minimum_ to react to the event, and get out fast. If you want a long delay (cup of tea), in the court, you'd probably turn off the serving machine. The same is the way to approach interrupts. doing the slow things in the main code outside.
As a separate comment, look at your own remarks. Note the one that says
"//a small delay is required after setting the channel ". Then why is the delay _before_ setting the channel?.
Best Wishes |
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
Posted: Fri Jul 15, 2011 12:15 pm |
|
|
Quote: |
As a separate comment, look at your own remarks. Note the one that says
"//a small delay is required after setting the channel ". Then why is the delay _before_ setting the channel?.
|
Code: |
for(i = 0; i < data_width; i++)
{
delay_us(10); //a small delay is required after setting the channel
set_adc_channel(i);
AccData[i] = read_adc(); //starts the conversion
}
|
hmm? if i put the delay below the
set_adc_channel(i);
then the problem set?
Code: | for(i = 0; i < data_width; i++)
{
set_adc_channel(i);
delay_us(10);
AccData[i] = read_adc();
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Fri Jul 15, 2011 2:35 pm |
|
|
_One_ problem that will prevent the ADC returning a correct reading is fixed. Not the main ones.
Best Wishes |
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
Posted: Fri Jul 15, 2011 8:35 pm |
|
|
Ttelmah wrote: | _One_ problem that will prevent the ADC returning a correct reading is fixed. Not the main ones.
Best Wishes |
then what is the main 1=.= |
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
Posted: Sat Jul 16, 2011 7:00 am |
|
|
o...the main problem is serve the timer interrupt used too long time? then have any idea i can set the 20ms for motor? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Jul 16, 2011 8:15 am |
|
|
There are two or more separate issues:
First, the code will not cause the display to blank when the servo is attached. That this is happening, implies something in hardware - faulty servo, wrong connection, etc. etc.. Triple check the actual servo wiring - colour codes mean nothing. Normally the pin 'order' across the plug, is 0v, 5v, PWM. The manual you refer to, gives a different colour code to the one you are referring to (black red, white, not black red orange), so if the servo is not exactly the model listed check what pin order the manufacturer uses. Some have the supply and PWM signal reversed (Fujitsu typically). You have a hardware problem first.
Second, are the code issues. Use the PWM, or CTC, to generate the pulses from the main code. Don't actually 'worry' about the 20mSec. This is not important to the servo. It is the on pulse that matters, within reasonable limits (perhaps 10 to 50mSec!), servo's don't care about the duration of the off period.
Best Wishes |
|
|
pacman91
Joined: 17 Jun 2011 Posts: 28 Location: Malaysia
|
|
Posted: Sat Jul 16, 2011 10:09 am |
|
|
Quote: | Triple check the actual servo wiring - colour codes mean nothing. Normally the pin 'order' across the plug, is 0v, 5v, PWM. The manual you refer to, gives a different colour code to the one you are referring to (black red, white, not black red orange), so if the servo is not exactly the model listed check what pin order the manufacturer uses. Some have the supply and PWM signal reversed (Fujitsu typically). You have a hardware problem first. |
I connect the wire with its RC motor manual(weblink at top(C36R)), as below,
Wiring (Black/Brown Wire) Ground
Wiring (Red Wire) 4.8-6.0
Wiring (Orange/Other Wire) PWM signal
I was tried the accelerometer and servo motor 1 by 1 with different program (similiar as this program, I just combine those 2 code to this 1), there have no any error.
But i curious my servo motor, when my period is 2.35ms (PWM at max angle) turning anticlockwise, and min angle at 0.5ms, it turn clockwise, totally reverse with my manual, it that any error or just normal? |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|