CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help needed on using analog values.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

Help needed on using analog values.
PostPosted: Tue Oct 09, 2007 4:02 am     Reply with quote

I wrote the folowing code and it worked fine until i started using analog channel 3. I am using a small joystic that has an analog input for left and right and forward reverse. I need the forward reverse to stop working if the stick is pushed left and right. The pwm output rb1 and rb2 works fine but indication led RB3 stops working when the part that reeds an input from analog 3 is included in the program. What am i doing wrong?
Code:

setup_adc_ports(all_analog);
//setup_adc_ports(sAN2);
//setup_adc_ports(sAN3);
setup_adc( ADC_CLOCK_INTERNAL );

#define P1C PIN_B1
#define P1b PIN_B2
setup_timer_2(T2_DIV_BY_4, 124, 1);  // 1000 Hz
output_low(P1C);

//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
while(1){

set_adc_channel(1);
value = read_adc();
set_adc_channel(2);   
value1 = read_adc();
set_adc_channel(3);
weapon = read_adc();

if(weapon > 230){
output_high(pin_b4);
}
if(weapon > 30 && weapon <230){
output_low(pin_b4);
}
if(weapon <30){
output_high(pin_b4);
}
//////////////////////////////////////right//////////////////////////////////////////////
if(value1 > 245 ){
set_pwm1_duty(80);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_B);
output_high(pin_A4);
output_low(pin_b5);
output_low(pin_b3);
}
if(value1 > 210 && value1 < 245 ){
//set_pwm1_duty(0);
setup_ccp1(CCP_OFF);
output_low(pin_A4);
output_low(pin_b5);
output_low(pin_b3);
}
///////////////////////////////////////////left////////////////////////////////////////////
if(value1 > 10 && value1 < 90  ){
//set_pwm1_duty(0);
setup_ccp1(CCP_OFF);
output_low(pin_A5);
output_low(pin_b5);
output_low(pin_b3);
}
if(value1 < 10 ){
set_pwm1_duty(80);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_B);
output_high(pin_A5);
output_low(pin_b5);
output_low(pin_b3);
}
//////////////////////////////forwardreverse//////////////////////////////////////
if(value1 > 90 && value1 <210){
output_low(pin_A4);
output_low(pin_A5);

if(value > 110 && value < 115  ) {
set_pwm1_duty(25);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
output_high(pin_b3);
}

if(value > 115 && value < 160  ) {
set_pwm1_duty(0);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
output_low(pin_b5);
output_low(pin_b3);
}

if(value > 160 && value < 180  ) {
set_pwm1_duty(25);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
output_high(pin_b5);
}

}

}
}
Ttelmah
Guest







PostPosted: Tue Oct 09, 2007 7:50 am     Reply with quote

First thing. You must pause after selecting a channel, befoe reading it. The internal ADC, is electrically a capacitor, and there is significant resistance present in the input parts of the chip. It therefore takes time for the capacitor to charge to the input voltage. Typically at least 10uSec are needed, and almost certainly more, from a joystick, which will itself usually have a fairly high resistance. I'd suspect this is the actual problem. If the voltage on input 3, is significantly different from the other values, the capacitor will charge to this voltage, and never get 'back' to the right sort of levels fo the other channels.
A couple of other comments.
In general, don't use 'ADC_CLOCK_INTERNAL'. The problem with this, is that the sampling is then asynchronous to the other stuff going on in the chip. Hence there is a tendency to more noise variation between samples. Normally the data sheet will have a 'caveat', saying not to use this above perhaps 1MHz, unless the chip is put to sleep for the sample. However some latter chips are OK with this, provided you are running off the internal oscillator.
Then there is a 'weakness', in the logic of the 'weapon' test. What happens if the value _is_ 30, or '230'?.

Best Wishes
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue Oct 09, 2007 8:24 am     Reply with quote

Quote:
What happens if the value _is_ 30, or '230'?.

Ahhhh, I remember when this type of thing bit me in the rear. Embarassed

What Ttelmah is talking about is:

You are comparing values from your ADC. If the value is > 230 and if it is < 230. If the value is exactly 230 there is nothing that will be true in your evaluation. You'll need to change one of them so 230 (and 30 and 245 and so forth) will cause an evaluation to be true. Try:

Code:
if(weapon > 229){ // this will be true if value is 230
output_high(pin_b4);
}
if(weapon > 30 && weapon <230){ // this will be true if value is 229 or less
output_low(pin_b4);
}


It's the little things that can cause the most grief.

Ronald
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 09, 2007 8:37 am     Reply with quote

Thanks for the help.
Just one thing> If i do not use the "ADC_CLOCK_INTERNAL" what would be the better option as i am using an external oscilator of 4mhz?

I see those holes and will sort them out to see if that wil work.

Code:
#define ADC_CLOCK_DIV_2    0x100
#define ADC_CLOCK_DIV_8     0x40
#define ADC_CLOCK_DIV_32    0x80
#define ADC_CLOCK_INTERNAL  0xc0


Am i correct in saying that if i use one of the following the reading time would be connected to the external oscilator_div_x so it would have less interference?
Ttelmah
Guest







PostPosted: Tue Oct 09, 2007 9:47 am     Reply with quote

There is a table in the data sheet....

However you generally need more than 2uSec/cycle (some latter chips less). This represents 8 cycles of your clock.
Check the data sheet for your chip (you have not told us which chip it actually is...).

Best Wishes
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 09, 2007 11:36 am     Reply with quote

Thanks. Its a 16f886 and i see in the datasheet it should be div_8.
Seems like most of the hickups are sorted out i just need to sort the pwm switching on and off but shouldn't be a problem.

Thanks for the help.
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 09, 2007 11:58 am     Reply with quote

I thought i would be able to sort it out but i must be missing something??

In the code if i move the stick to the front and back the pwm on pin c switches correctly between the duty cycles but if i move it left and right as well as front and back the pwm on both B and C doesnt want to switch off when i return the stick to between the levels where i set ccp_off. Is there a software problem or can anyone see what i did wrong?

Code:
set_tris_a(TRISA | 0b00001110);
set_tris_a(TRISA & 0b11001111);
set_tris_b(trisb & 0b11000001);

output_low(PIN_A4);
output_low(PIN_A5);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
output_low(PIN_B4);
output_low(PIN_B4);

         
setup_adc_ports(sAN1);
setup_adc_ports(sAN2);
setup_adc_ports(sAN3);
setup_adc( ADC_CLOCK_DIV_8  );

#define P1C PIN_B1
#define P1b PIN_B2
setup_timer_2(T2_DIV_BY_4, 124, 1);  // 1000 Hz
output_low(P1C);

//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////
while(1){

///part were weapon is actvated
//xxxxxxxxxxxxxxxxxxxxxxxxxxx

//////////////////////////////////////Joystick pushed right ////////////////////////////////////////
set_adc_channel(2);   
delay_us(20);
value1 = read_adc();

if(value1 > 245 ){
setup_ccp1(CCP_OFF);
output_high(pin_A4);
output_low(pin_b5);
output_low(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x1A);
}
else if(value1 > 210 && value1 < 246 ){
set_pwm1_duty(0);
setup_ccp1(CCP_OFF);          ////switch off ccp1(pwm)
output_low(pin_A4);
output_low(pin_b5);
output_low(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x1B);
}
///////////////////////////////////////////Joystick pushed left////////////////////////////////////////////
if(value1 > 10 && value1 < 90  ){
//set_pwm1_duty(0);
setup_ccp1(CCP_OFF);                   ////switch off ccp1(pwm)
output_low(pin_A5);
output_low(pin_b5);
output_low(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x2A);
}
else if(value1 < 11 ){
set_pwm1_duty(80);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_B);
output_high(pin_A5);
output_low(pin_b5);
output_low(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x2B);
}
//////////////////////////////joystic pushed forward /////////////////////////////////////////////////
if(value1 > 90 && value1 <211){
output_low(pin_A4);
output_low(pin_A5);
set_adc_channel(1);
delay_us(20);
value = read_adc();

 if(value > 110 && value < 116  ) {
set_pwm1_duty(25);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
output_high(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x3E);
}
//////////////Joystic in the middle////////
else if(value > 115 && value < 161  ) {
setup_ccp1(CCP_OFF);                          ////switch off ccp1(pwm)
output_low(pin_b5);
output_low(pin_b3);
PutCC1000(PREAMBLE);
PutCC1000(0x4A);
}
/////////////////joystick pushed back////////////
else if(value > 160 && value < 181  ) {
set_pwm1_duty(25);
setup_ccp1(CCP_PWM_H_H | CCP_PULSE_STEERING_C);
output_high(pin_b5);
PutCC1000(PREAMBLE);
PutCC1000(0x5A);
}


}
}
Gerhard



Joined: 30 Aug 2007
Posts: 144
Location: South Africa

View user's profile Send private message Send e-mail

PostPosted: Tue Oct 09, 2007 2:12 pm     Reply with quote

If anyone has a better way of doing it also please your input would be apreciated. The reason i am not using the analog values directly is because the position of the joystick is sent via rf to another pic to actually control the car but if there is a better way please let me know.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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