Author Topic: Delay using ADC problem on PIC18F4550  (Read 4745 times)

0 Members and 1 Guest are viewing this topic.

Offline BibiricatTopic starter

  • Contributor
  • Posts: 43
Delay using ADC problem on PIC18F4550
« on: June 03, 2013, 07:33:25 pm »
Hello.
I am trying to make a pulse delay using a potentiometer (using a ADC). The ADC works, the delay function work, but it's not a linear delay.
What i want to say is that when the pot is at 0, i get no delay. When it's somewhere else, i get some delay, however, after a certain point, the delay begins to drop, until it almost get to 0 again, however the pot gets to full range.

This is the code. I hope someone can help me with this.

Code: [Select]
#include<p18f4550.h> // Always include the header file
#include <delays.h>

#define REMAPPED_RESET_VECTOR_ADDRESS      0x1000

/***************Bootloader************************************/
#pragma code REMAPPED_RESET_VECTOR = REMAPPED_RESET_VECTOR_ADDRESS
extern void _startup (void);
void _reset (void)
{
   _asm goto _startup _endasm
}
#pragma code

void Delay(int x)
{
int i; //Post:Delay for x*10ms.
for (i=0; i<x; i++){
                          Delay10TCYx (10); // gives a delay of 10 x 60 x 1/12 = 600/12 = 50 us
}
}

void ADCInit()
{
    ADCON1 = 0b00001110;//VSS,VDD ref. AN0 analog only
ADCON0 = 0x00;//clear ADCON0 to select channel 0 (AN0)
ADCON2 = 0b10001000;//ADCON2 setup: Right justified, Tacq=2Tad, Tad=2*Tosc (or Fosc/2)
ADCON0bits.ADON = 0x01;//Enable A/D module
}

void main(void)
{
unsigned int delay;
int ad_val;
TRISB=0b00000001;
PORTB=0b00000000;
PORTBbits.RB2=1;
ADCInit();

while(1)
{
if(PORTBbits.RB2 == 0)PORTBbits.RB2 = 1;
if(PORTBbits.RB0 == 0) //test button press
{
ADCON0bits.GO_DONE = 1; //Start A/D Conversion
while(ADCON0bits.GO_DONE != 0);               //Loop here until A/D conversion completes
ad_val=((ADRESH<<8)+ADRESL);                               //get value of 10 bit adc
Delay100TCYx (ad_val);                                              //insert number in delay function
PORTBbits.RB2 = 0;                                                     //change port status
Delay10TCYx (120);                                                    //delay for a bit
PORTBbits.RB2 = 1;                                                    //change back to initial port status
}

}
}


 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: Delay using ADC problem on PIC18F4550
« Reply #1 on: June 03, 2013, 07:58:00 pm »
When you turn the pot, what range of voltages are you getting? Could it be something daft like both ends of the pot's track being connected together, so the resistance between the wiper and the ends of the track reaches a maximum when the wiper is in the middle of the range, and zero when it's at either end?

In your code, try replacing:

ad_val=((ADRESH<<8)+ADRESL);

with the simpler:

ad_val=ADRES;

I've a feeling that, for some devices at least, ADRES is defined in the header file as a single 16 bit register that you can reference to get the whole 16 bit result in one hit. I also have a feeling I've tried to combine ADRESH and ADRESL as you've done and had problems, but I wouldn't like to be drawn on exactly what the problem was or why it happened.

Also, you have a line:
Delay100TCYx (ad_val);

Is it possible that ad_val can take values that are out of range for this function?

Can you list your delays.h header file?

Offline BibiricatTopic starter

  • Contributor
  • Posts: 43
Re: Delay using ADC problem on PIC18F4550
« Reply #2 on: June 04, 2013, 08:47:22 am »
The pot is working good (i get 0v at one end, and +4.88v at the other).
based on youre commnets i have modified the code:

ad_val=ADRES;
ad_val=ad_val>>3;
Delay100TCYx (ad_val);

so now i shift the adc value so i get a max of 256.
I haven't tested it , but will do soon.
 

Offline PA0PBZ

  • Super Contributor
  • ***
  • Posts: 5129
  • Country: nl
Re: Delay using ADC problem on PIC18F4550
« Reply #3 on: June 04, 2013, 10:52:01 am »
Could be you have a logaritmic pot, they are almost more common than linear ones (audio equipment and such). Did you measure the voltage at regular intervals?
Keyboard error: Press F1 to continue.
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: Delay using ADC problem on PIC18F4550
« Reply #4 on: June 04, 2013, 11:11:22 am »
The pot is working good (i get 0v at one end, and +4.88v at the other).
based on youre commnets i have modified the code:

ad_val=ADRES;
ad_val=ad_val>>3;
Delay100TCYx (ad_val);

so now i shift the adc value so i get a max of 256.
I haven't tested it , but will do soon.

It might be simpler to set the ADC to give a left justified result, then just use ADRESH. That gives you a range of 0-255 without the need for a 16 bit read followed by a shift.

If you keep the same code structure, I think you need ad_val>>2, not 3.

Offline BibiricatTopic starter

  • Contributor
  • Posts: 43
Re: Delay using ADC problem on PIC18F4550
« Reply #5 on: June 04, 2013, 07:36:46 pm »
I managed to get it working, using left justified, but i encountered another problem with the interrupt. When i use a button, i get everything to work just fine, but the i use a AC trigger source, i can't get the interrupt to work, bit i am checking with the pickit 2 logic tool to see if the trigger is working, and the micro is registering a change, however, the interrupt doesn't trigger....
Any idea on what else can i try ?
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4228
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: Delay using ADC problem on PIC18F4550
« Reply #6 on: June 04, 2013, 07:57:49 pm »
With most (all?) PIC18 devices, there are several interrupt enable bits to set - there's probably a PIE bit, an interrupt priority bit for that particular interrupt source, the bit which selects between legacy vs prioritised interrupts, then GIEH and GIEL to set. One trap that's caught me out on one or two occasions is that if you disable high priority interrupts, then low priority interrupts get disabled as well.

Could you post your code again? What was wrong with it before?

Offline Dennis

  • Contributor
  • Posts: 10
  • Country: us
    • Discovering Electronics
Re: Delay using ADC problem on PIC18F4550
« Reply #7 on: June 12, 2013, 01:14:29 am »
It may make the response from the delay pot a bit smoother if you use a slope function. This will allow you to span the delay to whatever degree you wish; from Fine to Course.

int map(int x, int in_min, int in_max, int out_min, int out_max)
{
// 10 bit ADC  ans 256 step delay
                             0                  256           0                1024         0              0
       return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

or simply (for a 256 step delay):

ad_val=ADRES;  // always store register value, don't use raw

Delay100TCYx (  (ad_val * 256) / 1024 );

Stress: The overwhelming urge to choke the crap out of someone who desperately needs it!
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf