Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] How to use ADC module of PIC18f4680 with more channels?

Status
Not open for further replies.

Pallavi Burje

Junior Member level 1
Joined
Oct 29, 2013
Messages
18
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
121
hi

I m doing project on PIC18f4680 microcontroller. In that i want to interface 3 different sensors to pic18f4680 microcontroller's ADC module using its channels. so i want to know, is this possible?? if yes, how to write a code... please help..
 

the pic 18f4680 has 11 differents adc channels with 10 bits resolution already built in !
you dont need anything more !
http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010305

all the pins names ANxx are the analog inputs you can read with the adc.

381944216_920.jpg
 

hi

I m doing project on PIC18f4680 microcontroller. In that i want to interface 3 different sensors to pic18f4680 microcontroller's ADC module using its channels. so i want to know, is this possible?? if yes, how to write a code... please help..

Hi,

Always better if you mention which compiler you intend to use.

As mentioned you have 11 ADC channels on that chip.

There are system registers, ADCON 0,1 & 2 , that allow you to select which of the 11 channels to use for ADC and then to further select which one of those is next to be read in by the ADC module.
 
Mention details about your project like what you want to measure and what are the ranges of adc inputs you are giving to the different adc channels. Are you going to use Vref +/-? Post a circuit and mention the Compiler you are using and also Fosc.
 

Mention details about your project like what you want to measure and what are the ranges of adc inputs you are giving to the different adc channels. Are you going to use Vref +/-? Post a circuit and mention the Compiler you are using and also Fosc.

Thank you for reply... i m using 3 sensors like temp. sensor(LM35), gas sensor (MQ 6) and pressure sensor.. I want to take continues readings of each sensor after particular time interval.. yes i will use Vref +/-... I want to use C18 compiler and want to write code in embedded C in MPLAB IDE.. i m not getting which value of fosc is beneficial so please suggest... and about circuit... i hv done one small project of temp sensor interfaced to pic16f877a and as potiometer is used as temp sensor in simulation so i want to do like wise in this project but more sensors .. plz help
 

Proteus has LM35 and pressure sensor. You can use them. For Gas Sensor you can use pot for simulation. LM35 max output for 150 deg C is 1.5V. If you set Vref+ to 1.6V say then it applies to all the channels. See if you can set Vref+ to 1.6V only when measuring LM35 sensor o/p and then disabling Vref+ when measuring o/ps of gas sensor and pressure sensor. You have to use ADCON0 to select ADC channels and ADCON1 to enable or disable Vref+. You can use Fosc of 4MHz. Mention pressure sensor you are going to use. I guess gas sensor modules analog o/p varies from 0 to 5V.
 
Proteus has LM35 and pressure sensor. You can use them. For Gas Sensor you can use pot for simulation. LM35 max output for 150 deg C is 1.5V. If you set Vref+ to 1.6V say then it applies to all the channels. See if you can set Vref+ to 1.6V only when measuring LM35 sensor o/p and then disabling Vref+ when measuring o/ps of gas sensor and pressure sensor. You have to use ADCON0 to select ADC channels and ADCON1 to enable or disable Vref+. You can use Fosc of 4MHz. Mention pressure sensor you are going to use. I guess gas sensor modules analog o/p varies from 0 to 5V.

Thank you for all this information.. i will use load cells as pressure sensor.. and also tried gas sensor interfacing with pic18 microcontroller... but at this time i want to interface all sensors to same microcontroller i.e. to pic18f4680.. Can i write only one code for interfacing all 3 sensors? in separate subcodes i hv to configure ADCON1, ADCON2 and ADCON3 what to do???
 

Yes you can interface all three sensors to your PIC. Your PIC should have 3 adc channels plus Vref+. Read datasheet and configure ADCONx registers. I use mikroC PRO PIC. Load cell might also need an amplifier. What is the output range of Load cell you are using? I can help you with mikroC code.


mikroC code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// LCD module connections
sbit LCD_RS at LATD0_bit;
sbit LCD_EN at LATD1_bit;
sbit LCD_D4 at LATD4_bit;
sbit LCD_D5 at LATD5_bit;
sbit LCD_D6 at LATD6_bit;
sbit LCD_D7 at LATD7_bit;
 
sbit LCD_RS_Direction at TRISD0_bit;
sbit LCD_EN_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
 
float adcVal;
unsigned char lcdData[23];
 
void readADC() {
     ADCON0.GO = 1;            //Start conversion
     while(ADCON0.GO);         //Wait till conversion finishes
     adcVal = (ADRESH << 8) | ADRESL;   //Read ADC result into adcVal
}
 
void main() {
 
    TRISA = 0xFF;
    TRISB = 0x00;
    TRISC = 0x00;
    TRISD = 0x00;
    
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    PORTD = 0x00;
    
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    LATD = 0x00;
    CMCON = 0x07;
    CVRCON = 0x00;
    
    LCD_Init();
    LCD_Cmd(_LCD_CURSOR_OFF);
    LCD_Cmd(_LCD_CLEAR);
    LCD_Out(1,1,"Multiple ADC");
    
    while(1){
    
            ADCON0 = 0b00000001;                //Select AN0, LM35
            ADCON1 = 0b00011010;                //Vref+ used
            ADCON2 = 0b10101101;                //12 TAD, 16 TOSC
            Delay_ms(10);                       //Delay for ADC stabilization
            readADC();                          //Read ADC
            adcVal = adcVal / 6.413332;         //Convert ADC value
            FloatToStr(adcVal, lcdData);        //Convert to string
            LCD_Out(2,1,lcdData);               //Display adc value on LCD
            
            ADCON0 = 0b00000101;                 //Select AN1, Load Cell
            ADCON1 = 0b00001010;                 //Vref disabled, AVdd and AVss are used
            ADCON2 = 0b10101101;                 //12 TAD, 16 TOSC
            Delay_ms(10);                        //Delay for ADC stabilization
            readADC();                           //Read ADC
            adcVal = adcVal * 5.0 / 1023.0;      //Convert ADC value
            FloatToStr(adcVal, lcdData);         //Convert to string
            LCD_Out(3,1,lcdData);                //Display adc value on LCD
 
            ADCON0 = 0b00001001;                 //Select AN2, MQ-6
            ADCON1 = 0b00001010;                 //Vref disabled, AVDD and AVSS are used
            ADCON2 = 0b10101101;                 //12 TAD, 16 TOSC
            Delay_ms(10);                        //Delay for ADC stabilization
            readADC();                           //Read ADC
            adcVal = adcVal * 5.0 / 1023.0;      //Convert ADC value
            FloatToStr(adcVal, lcdData);         //Convert to string
            LCD_Out(4,1,lcdData);                //Display adc value on LCD
    }
}
 
 
/*
//ADCON0 = 0b00000001;
ADCON1 = 0b00011010;
ADCON2 = 0b10101101;
Delay_ms(10);
adcVal = ADC_Read(0);
adcVal = adcVal / 6.413332;
FloatToStr(adcVal, lcdData);
LCD_Out(2,1,lcdData);
 
//ADCON0 = 0b00000101;
ADCON1 = 0b00001010;
ADCON2 = 0b10101101;
Delay_ms(10);
adcVal = ADC_Read(1);
adcVal = adcVal * 5.0 / 1023.0;
FloatToStr(adcVal, lcdData);
LCD_Out(3,1,lcdData);
 
//ADCON0 = 0b00001001;
ADCON1 = 0b00001010;
ADCON2 = 0b10101101;
Delay_ms(10);
adcVal = ADC_Read(2);
adcVal = adcVal * 5.0 / 1023.0;
FloatToStr(adcVal, lcdData);
LCD_Out(4,1,lcdData);
*/

 

Attachments

  • Pallavi Bhurje.rar
    101 KB · Views: 61
Last edited:
Thank you thank you so much... actually i studied only temp. and gas sensor and trying to interface pressure sensor so not much i m knowing about load cell as pressure sensor..
i will study this code and will write in mplab ide.. Can i use Vdd and GND voltages instead of Vref+/-??
 

If you don't use Vref+ then ADC ref will be 5V and for 5V you will get 1023 raw adc value. LM35 max o/p is 1.5V. So, adc value will be max 307. So, your adc will only vary from 0 to 307 instead of 0 to 1023. Resolution will be less. Use the code I have given. I have used Vref+ for LM35 so that for 1.5V you get 1023 raw adc value.


1.5V / 307 = 0.004885993485342

1.5V / 1023 = 0.001466275659824
 
Last edited:

Can you please tell me, how adcVal = adcVal / 6.413332 for lm35 and adcVal = adcVal * 5.0 / 1023.0; for load cell and gas sensor... for load cell and gas sensor there only hex conversion and 1023.0 is taken as our adc is 10 bit and voltage used is 5v so value 5.0 ... correct? but i m not getting calculation for lm35 ?? and also i read datasheet but i m not clear with the concept of CMCON and CVRCON reg.s?? and their values are 0x07 and 0x00; resp. in this code.???
 

I am using Vref+ of 1.6V so

1.6V = 1023

1.5V (max LM35 value) = 959.0625

959.0625 has to be converted to 150 (150 deg C)

959.0625 * x = 150

x = 150 / 959.0625 = 0.1564027370478983


You can use adcVal = adcVal * 0.1564027370478983

or

adcVal = adcVal / 6.39375


6.39375 = 1 / 0.1564027370478983

You can also use

adcVal = adcVal * 160 / 1023 (160 = 1.6V)

160 / 1023 = 0.1564027370478983


Code C - [expand]
1
CMCON = 0x07

disables the Comparators and

Code C - [expand]
1
CVRCON = 0x00

disables the Comparator Voltage reference. It is done because Comparators are multiplexed with ADC input pins.


The actual data I was getting for 150 deg C was 961.9998. So,

150 / 961.9998 = 0.155925188342035

1 / 0.155925188342035 = 6.413332
 
Last edited:

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top