View previous topic :: View next topic |
Author |
Message |
tonkostz
Joined: 07 May 2011 Posts: 40 Location: Bulgaria
|
How to read the previous ADC value? |
Posted: Sat May 07, 2011 12:39 am |
|
|
I'm still learning in ccs programming. My experience is little. I searched the forum and i couldn't manage to find an exact answer for my issue.
I'm reading the signal from a 4.7k pot and applying it to AN0 analog input. I want to compare previous reading with the present and see whether the input signal is increasing or decreasing and then make a decision what to do in the program.
Maybe i should use interrupts after adc done and the read the two result registers and then start conversion again for the next value. The problem is i don't know how to do it.
Please help me!
The whole program purpose is to control a DC motor with two complementary PWM outputs and regeneration. PWM1 controls the motor and PWM0 is for freewheeling and braking.
The MCU I'm using is PIC18F2431.
Compiler version is 4.110
Supply voltage is 5V.
Oscillator speed is 10MHz HS.
And here is the whole program.
Code: |
#include <18f2431.h>
#include <PIC18F2431_registers.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=10000000)
static long int adc_accel,pwm_duty_1,pwm_duty,period=78; //16kHz
static int acc_stop=5;
#int_TIMER0
void TIMER0_isr(void)
{
if(input(pin_c3)!=0 && adc_accel<=15)
{
setup_power_pwm_pins(PWM_OFF,PWM_OFF,PWM_OFF,PWM_OFF);
output_low(pin_b1);
output_low(pin_b0);
pwm_duty_1=0;
pwm_duty=0;
}
if (input(pin_c3)==0 && adc_accel<=15) //this is the brake
{
setup_power_pwm_pins(PWM_BOTH_ON,PWM_OFF,PWM_OFF,PWM_OFF);
output_low(pin_b1);
MCU_OVDCOND=0b00000001;
if (pwm_duty_1<=350)
{
pwm_duty_1=pwm_duty_1+acc_stop;
}
else pwm_duty_1=350;
pwm_duty=pwm_duty_1;
}
else if (input(pin_c3)!=0 && adc_accel>=15)
{
MCU_OVDCOND=0b00000011;
setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_OFF,PWM_OFF,PWM_OFF);
pwm_duty=adc_accel;
}
}
void main()
{
MCU_FLTCONFIG = 0b00000011;
setup_power_pwm_pins(PWM_COMPLEMENTARY,PWM_OFF,PWM_OFF,PWM_OFF);
setup_power_pwm(PWM_CLOCK_DIV_4|PWM_UP_DOWN|PWM_DEAD_CLOCK_DIV_2,1,0,period,0,1,10);
setup_adc_ports(sAN0);
setup_adc(ADC_CLOCK_DIV_4 | ADC_TAD_MUL_8 | ADC_WHEN_PPWM);
setup_timer_0(RTCC_INTERNAL);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
while(true)
{
set_adc_channel(0);
delay_us(20);
adc_accel=read_adc();
set_power_pwm0_duty((pwm_duty/3));
delay_ms(100);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
tonkostz
Joined: 07 May 2011 Posts: 40 Location: Bulgaria
|
|
Posted: Sat May 07, 2011 3:10 am |
|
|
I saw this topic yesterday but i still don't understand how to do it.
This line lowest = 0xFF; means that lowest=255; or FF is an address of register?
This :
if(current < lowest)
lowest = current;
Isn't it:
if(current<255)
255=current;
Or i'm wrong?What's the point here?
Thank you! |
|
|
SherpaDoug
Joined: 07 Sep 2003 Posts: 1640 Location: Cape Cod Mass USA
|
|
Posted: Sat May 07, 2011 6:07 am |
|
|
The purpose is to track the lowest value seen. 255 is a value that is definitely NOT the lowest, so the first time we check it will be overwritten with the REAL lowest.
if(current < lowest)
This line checks to see if the value just read is lower then the lowest on record.
lowest = current;
This line sets the lowest reading on record to the value just read. It overwrites (destroys) the old value. _________________ The search for better is endless. Instead simply find very good and get the job done. |
|
|
tonkostz
Joined: 07 May 2011 Posts: 40 Location: Bulgaria
|
|
Posted: Sat May 07, 2011 12:25 pm |
|
|
I understand now everything you said. I tested it but it seems like this is not what I actually need.
I need some kind of direction indicator:
1. Every time the voltage applied to the adc input increases (no matter what the actual value is) - some kind of indication to see this.
2. Every time the voltage applied to the adc input decreases (no matter what the actual value is) - some kind of indication to see this.
Thank you! |
|
|
vinniewryan
Joined: 29 Jul 2009 Posts: 154 Location: at work
|
|
Posted: Sat May 07, 2011 12:45 pm |
|
|
Like this?
Code: | if(current > previous_current)
{
//current has increased
//set increase variable;
}
else
{
reset increase variable
}
if(current < previous_current)
{
//current has decreased
//set decrease variable;
}
else
{
reset decrease variable
} |
_________________ Vinnie Ryan |
|
|
tonkostz
Joined: 07 May 2011 Posts: 40 Location: Bulgaria
|
|
Posted: Sat May 07, 2011 10:43 pm |
|
|
Like that?
Code: |
while(true)
{
set_adc_channel(0);
delay_us(20);
a=read_adc();
if(a > p)
{
//current has increased
p=a;
delay_us(300);
i=a;//set increase variable;
}
else
{
delay_us(300);
i=0;//reset increase variable
}
if(a < p)
{
//current has decreased
p=a;
delay_us(300);
d=a;//set decrease variable;
}
else
{
delay_us(300);
d=0;//reset decrease variable
}
printf(lcd_putc,"\f i=%2.3w,d=%2.3w",i*5,d*5);
printf(lcd_putc,"\n a=%2.3w,p=%2.3w",a*5,p*5);
delay_ms(500);
}
}
|
a is the input signal or the current variable
i is the increase variable
d is the decrease variable
p is temporary variable
Results are:
1.When a increases:
a==i==p; or i>0;
2.When a standing still:
i=d=0;
3.When a decreases:
a==d==p; or d>0;
It seems like it is working. I watch the results on lcd 16x2.
I put delays for safety but I'm not sure I'll need them.
vinniewryan, is that what you mean?
Do you have any other suggestions? |
|
|
|