Help 3. Using a A/D in a PIC18F2550

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
First of all I would like to say thank you to everybody who helped me in my previous questions, "how to wire a Potentiometer" and "how to wire a solenoid valve". Your help has proved really valuable to me.

This time my question is about using a PIC 18F2550 that I have with me. Particularly the A/D function. The value I am going to be entering is the voltage from the potentiometer. (0-5V)

so the questions I have so far are:

1) Is there a place you can recommend to find examples or tutorials on this theme?
2) Does the PIC 18F2550 needs any particular wiring (apart from putting I suppose the wiper of the pot to a port (any resistor needed? maybe not)

I know the questions seems too general so far but I am just starting to read the docs about this. I suppose I will have more concrete questions later.

Thank you in advance for all the help you can give me.

Kansai
 

SgtWookie

Joined Jul 17, 2007
22,230
My question is about using a PIC 18F2550 that I have with me. Particularly the A/D function. The value I am going to be entering is the voltage from the potentiometer. (0-5V)

1) Is there a place you can recommend to find examples or tutorials on this theme?
Have you tried the Microchip website? They have quite a bit of documentation and "How To" examples along with the Application Notes. The datasheet for your particular PIC will have quite a bit of information in the ADC documentation already.
2) Does the PIC 18F2550 needs any particular wiring (apart from putting I suppose the wiper of the pot to a port (any resistor needed? maybe not)
The ADC needs a pretty low-impedance source to sample. A small capacitor, say 10nF to 100nF, at one of the ADC-accessible inputs will help to assure that it gets a low impedance source.
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Have you tried the Microchip website? They have quite a bit of documentation and "How To" examples along with the Application Notes. The datasheet for your particular PIC will have quite a bit of information in the ADC documentation already.
Yes, I am checking that right now. The information is enourmous, say the datasheet is 438 pages!
I found a place with examples too. So far the ones I ve looked are in assembler and although I would go there if it is needed, my first language is C, so I was hoping for examples in C.
Anyway if I can find some more focused info (examples in C for A/D) it would save me time.


The ADC needs a pretty low-impedance source to sample. A small capacitor, say 10nF to 100nF, at one of the ADC-accessible inputs will help to assure that it gets a low impedance source.
Yes, thanks. I ve already applied a 10 nF cap so I am hoping that would be alright.
I am wondering more in the sense of setting the RESET pin or something of that sort. I still have to read about this...

thanks for the support :)

Kansai (back to the books)
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thank you for the help.

QUick question. Which C compilers are there for programming the PICs?

I have heard of some already:

  • MPLAB C for PIC18 V3.34 in LITE mode
  • HI-TECH PICC-Lite
  • CCS PCB
Any comment or recommendation on those?

Due to the availability of libraries it seems that the codes in one and another can be quite different!
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thank you very much for your useful suggestions :)

I have a question regarding initial settings of the microcontroller. I am using a board in which the PIC18F2550 is already connected to a crystal oscillator (pins 9 and 10).

Now when in the program we put "clock to be derived from the internal oscillator (as in #pragma config FOSC=INTOSCIO_EC
or CONFIG FOSC=INTOSCIO_EC)
what are we refering to???
Does the microcontroller have an oscillator "inside"???

Does the oscilator I see in the circuit of my board is an "external oscillator"??

if yes, which should I use??

the crystal oscillator I have in the board is 20MHz (X110) connected to ground with two caps of 22pF.

Thank you for any help about this. The project is going fine!!:)
 

spinnaker

Joined Oct 29, 2009
7,830
Thank you very much for your useful suggestions :)

I have a question regarding initial settings of the microcontroller. I am using a board in which the PIC18F2550 is already connected to a crystal oscillator (pins 9 and 10).

Now when in the program we put "clock to be derived from the internal oscillator (as in #pragma config FOSC=INTOSCIO_EC
or CONFIG FOSC=INTOSCIO_EC)
what are we refering to???
Does the microcontroller have an oscillator "inside"???

Does the oscilator I see in the circuit of my board is an "external oscillator"??

if yes, which should I use??

the crystal oscillator I have in the board is 20MHz (X110) connected to ground with two caps of 22pF.

Thank you for any help about this. The project is going fine!!:)
Yes, many MCUs have internal oscillators. Tou don't really need to use the external crystal osc unless you have something that is timing critical. For example a real time clock. There are also methods for measuring voltage by measuring the amount of time it takes to charge a capacitor that would require precise timing.

I think the internals are pretty limited on speed too, but probably plenty fast enough for most hobby purposes.
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thank you very much for all your responses.
Here is the state of things so far.

I have managed to write a ADC program for my pic, compile it and write it in the PIC18F2550.
I am just not sure if the ADC is working or not.

Can someone please take a look and tell me what I am doing wrong??

  1. First, a program that reads the analog value from AN0 and display it as 4 leds in binary (somehow the leds are always on):(
Rich (BB code):
/***********************************************************************************
*  This is a ADC conversion program for the  MPLAB C18-Lite compiler
*  Continuosly sample analog input
*  copy value to 4 leds
*   this program is made for the PIC18F2550 ********************************************************************************
* PIN assignments:
*           AN0 :  voltage to be measured 
*           RB0-3:  output LEDs (RB3 is MSB)
*
**************************************************************************************/
 
// Includes
#include <p18f2550.h>
#include "adc.h"
unsigned int ADCResult=0;
/********************CONFIGURATION**************/
#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB 
#pragma config WDT = OFF //Disable watchdog timer
 
// Pin assignments
#define LEDS PORTB  // output LEDs in port B
/**********MAIN PROGRAM*************/
void main()
{
 unsigned char channel=0x00,config1=0x00,config2=0x00,config3=0x00,portconfig=0x00,i=0;
  // initialization
  TRISB=0b110000;    // configure RB0-RB3 as outputs
 
 
  // configure ADC
  config1 = ADC_FOSC_RC | ADC_RIGHT_JUST | ADC_2_TAD ;
  config2 = ADC_CH0 | ADC_INT_OFF | ADC_REF_VDD_VSS ;
  portconfig = ADC_1ANA ;  // Only A0 is analog. the rest are digital (so as to allow us digital output on B)
  OpenADC(config1,config2,portconfig);
 
  // main loop
  while(1)
    {
      ConvertADC();   // start conversion
 
      while(BusyADC()); // wait for result
 
      ADCResult=(unsigned int) ReadADC();
 
 
        LEDS=ADCResult>>6; // copy highes nybble (6 since this is a 10-bit ADC)
//  LEDS= ADRESL>>4; // copy high nybble of result to LEDs (this is for 8-bit ADC)
      }
 CloseADC();         //turn off ADC
}
2. A program that converts the value from ADC to angles (0 to 320 degrees and based on that turns on or off a led (somehow, the led is always on:()

Rich (BB code):
/***********************************************************************************
*  This is the LED-on/off based on ADC conversion from a potentiometer program
*  (compiled with MPLAB C18-Lite compiler)
*  Continuosly sampled analog input
*  based on the value from that input (after ADC) the LED is going to be 
*  turn ON/OFF, 
*   this program is made for the PIC18F2550 
*
*   The range of value of the 10-bit ADC is 0~1024 which correspond to a voltage 0~Vmax 
*
*   The range of motion of the potentiometer is 320 degrees
*
*   We have to make a conversion between degrees and values of the ADC
*
*     ZERO DEGREE  ---->  0
*     320 DEGREE   ---->  1024
*
*
*
********************************************************************************
* PIN assignments:
*           AN0 :  voltage to be measured 
*           RB3:  output 
**************************************************************************************/
/*********************Includes********************/
#include <p18f2550.h>
#include "adc.h"
unsigned int ADCResult=0;
double  angle=0;
/********************CONFIGURATION**************/
#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB 
#pragma config WDT = OFF //Disable watchdog timer
/**********PIN Assignment*************************/
#define LEDPin3   LATBbits.LATB3  // the only one we will be using
 
/***********Other Definitions************************/
#define  LOWANGLE   45
#define  HIGHANGLE  135
#define  TOTALANGLE 320
#define  TOTALADC   1024
#define  CONVADCTOANGLE  (TOTALANGLE/TOTALADC)
#define  CONVANGLETOADC  (TOTALADC/TOTALANGLE)
 
/**********MAIN PROGRAM*************/
void main()
{
 unsigned char channel=0x00,config1=0x00,config2=0x00,config3=0x00,portconfig=0x00,i=0;
  // initialization
  TRISB=0b110000;    // configure RB0-RB3 as outputs
 
   LEDPin3=0;  // turn off the pin
 
  // configure ADC
  config1 = ADC_FOSC_RC | ADC_RIGHT_JUST | ADC_2_TAD ;
  config2 = ADC_CH0 | ADC_INT_OFF | ADC_REF_VDD_VSS ;
  portconfig = ADC_1ANA ;  // Only A0 is analog. the rest are digital (so as to allow us digital output on B)
   OpenADC(config1,config2,portconfig);
 
  // main loop
  while(1)
    {
     ConvertADC();   // start conversion
     while(BusyADC()); // wait for result
     ADCResult=(unsigned int) ReadADC();
     angle=ADCResult*CONVADCTOANGLE;   // we get the angle here.
 
     if(angle>HIGHANGLE) // turn off the LED
        LEDPin3=0;   // turn off the LED
 
     if(angle<LOWANGLE)  // turn on the LED
        LEDPin3=1;
 
 
    }
 CloseADC();         //turn off ADC
}
Can someone please tell me what am I doing wrong?

Thanks a lot again :)

Kansai
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Yes thanks I have taken a look at it and studying it
I have modified my code to see if the AD is actually working or not. And yes it is working. I set a LED toogle everytime a AD operation is finished. At first it didnt work, but then I introduced a delay and it works.

So I am guessing my problem is in how I am configuring the Tad and the timings. But I am lost at this. Any advice will be appreciated. In the meantime I post the code and will keep thinking about this

Rich (BB code):
/*********************Includes********************/
#include <p18f2550.h>
#include <delays.h>
#include "adc.h"
unsigned int ADCResult=0;
double  angle=0;
/********************CONFIGURATION**************/
#pragma config FOSC = INTOSCIO_EC //Internal oscillator, port function on RA6, EC used by USB 
#pragma config WDT = OFF //Disable watchdog timer
/**********PIN Assignment*************************/
#define LEDPin3   LATBbits.LATB3  // the only one we will be using
/***********Other Definitions************************/
#define  LOWANGLE   45
#define  HIGHANGLE  135
#define  TOTALANGLE 320
#define  TOTALADC   1024
#define  CONVADCTOANGLE  (TOTALANGLE/TOTALADC)
#define  CONVANGLETOADC  (TOTALADC/TOTALANGLE)
 
/**********MAIN PROGRAM*************/
void main()
{
 unsigned char channel=0x00,config1=0x00,config2=0x00,config3=0x00,portconfig=0x00,i=0;
    // initialization
     TRISB=0b110000;    // configure RB0-RB3 as outputs
     TRISAbits.TRISA0=1;  // configure TRISA0 as input
     LEDPin3=0;  // turn off the pin
 
 // configure ADC
 config1 = ADC_FOSC_2 | ADC_RIGHT_JUST | ADC_20_TAD ;
 config2 = ADC_CH0 | ADC_INT_OFF | ADC_REF_VDD_VSS ;
 portconfig = ADC_1ANA ;  // Only A0 is analog. the rest are digital (so as to allow us digital output on B)
 OpenADC(config1,config2,portconfig);
 
 // main loop
 while(1)
    {
     ConvertADC();   // start conversion
     while(BusyADC()); // wait for result
 
         LEDPin3=~LEDPin3; // toggle LED when finished
// HERE, THIS ONLY WORKS WHEN THE NEXT DELAY IS INTRODUCED!!!
         Delay10KTCYx(25);//Delay 250K cycles (1 second at 1MHz since each instruction takes 4 cycles)
 
//     ADCResult=(unsigned int) ReadADC();
   //     angle=ADCResult*CONVADCTOANGLE;   // we get the angle here.
 
/*
     if(angle>HIGHANGLE) // turn off the valve
        LEDPin3=0;   // turn off the LED
 
     if(angle<LOWANGLE)  // turn on the valve
        LEDPin3=1;
*/            
    }
 CloseADC();         //turn off ADC
}
Thanks for all the help.

Kansai
 

eng1ne

Joined Dec 4, 2009
97
Make use of the MPLAB Simulator. It serves as a reasonable debugging tool, with a watch window for certain memory locations etc. Set up some stimuli on your ADC memory location, calculate what you expect to see and step through your code.

First watch this video: http://www.youtube.com/watch?v=S1QCZW92fU4

Then, watch this video: http://www.youtube.com/watch?v=pnkUOL0mmyA&feature=related

Pretty sure the second one I referred to explains stimulus etc. Let me know if it doesn't, and the only way you will be able to tell me if it does or doesn't is by watching it :)
 

Thread Starter

KansaiRobot

Joined Jan 15, 2010
324
Thanks
I watch the videos. the Stimulus seems like a great idea. Now I am reading the HELP but still can not figure how to infuse a voltage stimulus into my analog pin.....

my deadline is gettin near and I still dont know how to run this:(

I am pretty sure the problem must be in the timing. I have no idea how to select the correct values for oscilators Tads and I dont understand the table 21-1 in the datasheet and what Tosc or Fosc is....:(

-----

when you say "ADC memory location".... is this what? my PORTA??? but how can I say 3.5V on pin 0 of Port A???
I dont get it....
 
Last edited:

Tahmid

Joined Jul 2, 2008
343
Thank you for the help.

QUick question. Which C compilers are there for programming the PICs?

I have heard of some already:

  • MPLAB C for PIC18 V3.34 in LITE mode
  • HI-TECH PICC-Lite
  • CCS PCB
Any comment or recommendation on those?

Due to the availability of libraries it seems that the codes in one and another can be quite different!
Hi,
When it comes to library functions, I think you should take a look at mikroC. I found that the best C compiler while programming PICs, although I mainly use mikroBASIC.
I suggest you take a look at the compiler.
Tahmid.
 

Tahmid

Joined Jul 2, 2008
343
Hi KansaiRobot,
The TAD settings are very important.
1 TAD = 1 ADC conversion clock. It takes 12 TAD to complete a conversion.
Minimum TAD time = 1.6us
So, if you are using 4MHz clock,
(a) FOSC/2 = 2MHz
1/2MHz = 400ns.
Invalid since this is faster than 1.6us
(b) FOSC/8 = 500kHz
1/500kHz = 2us
Valid since slower than 1.6us
Hope you understood.
Tahmid.
 

spinnaker

Joined Oct 29, 2009
7,830
Hi KansaiRobot,
The TAD settings are very important.
1 TAD = 1 ADC conversion clock. It takes 12 TAD to complete a conversion.
Minimum TAD time = 1.6us
So, if you are using 4MHz clock,
(a) FOSC/2 = 2MHz
1/2MHz = 400ns.
Invalid since this is faster than 1.6us
Tahmid.
Doesn't 1/2 = 500? Or am I missing something?
 
Top