#### MrDEB

##### Well-Known Member
have a resistor ladder for 10 switches but getting the ADC port set up right.
The LCD only displays 5v regardless of which switch is pressed.
The ACON regestors?
Code:
Device = 18F43k22
Clock = 20

// some LCD options...
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3

// uses LCD and AD libraries...
Include "LCD.bas"
Include "convert.bas"

// read the AD port and scale for 0 - 5 volts...
End Function

Dim led As PORTA.0
// initialise and clear LCD...
ADCON1 = $07 // PORTE as digital (LCD) TRISA.1 = 1 // configure AN0 as an input /// ADCON1.7 = 1 // set analogue input on PORTA.0 /// DelayMS (500) LCD.Cls Input(PORTA.1) // ADC IN on portA.1 ADCON1 = %10000000 //set up ADC regesters ADCON0.7 = 1 ADCON0.6 = 1 ADCON1 =$07
TRISA = %111111
TRISB = %11111111
TRISC = %00000000
TRISD = %00000000
TRISE = %000

// main program loop...
While true
led=1
DelayMS(1000)
led=0
DelayMS(1000)
LCD.MoveCursor (1,1)
LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
DelayMS(250)
Wend

#### Visitor

##### Active Member
I don't think the comments line up with which input you're trying to use, which makes deciphering your code virtually impossible.

You set ADCON1 in 3 different places. Best to figure out what you need and do it once.

Binary numbers are 8 bits. While TRISE may only use the last 3 bits, the first 5 are "don't care", so it's less confusing to specify 8 bits.

Here is code I used to read AN0 in a recent project. Unless you have updated Swordfish to the most recent version – which updated most of the include files to handle recent variants – you might be best off to not include ADC.bas and use this code.

Please note: after you go to all the trouble to set up the ADC, don't undo it all with SETALLDIGITAL.

Code:
  'ADC setup
TRISA=%00000001
ANSELA=%00000001

DelayUS(10)
Wend

ADCout.byte0=  ADRESL

#### Pommie

##### Well-Known Member
ADCON1.7 = 1 // set analogue input on PORTA.0 ///

How is 7 equal to 0?

Mike.

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
Isn't ADCON1.7 supposed to be the old ADCON1 = 7 ie.. all digital!!

It really doesn't matter as the special trigger isn't used... However ADCON1 = 7 does matter as it is setting Avss and Avdd to something other than you need.
Mike.. Don't read the comments as these are copied and pasted from example codes, these have no bearing here..

ADC input appears to be on RA1...

#### MrDEB

##### Well-Known Member
YES I am using the sample code. Going to rewire and use portA.0 as ADC input.
I did an update couple weeks ago but?
Will use "visitors" code

#### MrDEB

##### Well-Known Member
Yes in the code I posted I have , or supposed to have ADC input on portA.1
curious how to make it portA.1
??? I think I posted the code tags correctly?

#### Visitor

##### Active Member
??? I think I posted the code tags correctly?
I strongly suggest you proofread your posts after you click post. Then you will be able to see if what you did worked and see if the post makes sense. If not, edit your post and try again.

#### MrDEB

##### Well-Known Member
the code I posted looks ok.

#### MrDEB

##### Well-Known Member
checked my SF version= 2.2.3.0

#### Ian Rogers

##### User Extraordinaire
Forum Supporter
the code I posted looks ok.
Yep!! Looks good, but it's wrong... The ADC on that chip is about as different to the old pic18f4520 as you can get!

ADCON2 = 173 or binary ( 10101101) I always use FOSC/16 on 20Mhz... I hardly ever use the internal RC
ANSELA = 2
TRISA should be 255 by default, so input anyway..

#### MrDEB

##### Well-Known Member
just got back from church, rewired the ADC input to port A.0
BUT lets throw a fly into the works!
After looking at my schematic and planning on using an 8 x 8 led matrix into the mess got to thinking that maybe using all 8 bits of portA and all of portB or portC for the matrix. using the entire port for the Cathodes and Anodes should make it easier to program (readability of code) (only one port for each) so looking at using PortE.0 for the ADC input?
First to try out code using portA.0 as per suggestion then ??

#### MrDEB

##### Well-Known Member
HOUSTON we have touchdown
this code works well for all 10 "switches(have a clip for testing instead of actual switches.
.74, 1.16, 1.56, 1.97, 2.38, 2.79, 3.22, 3.53, 4.08, 4.54
pretty even differential between test points on the resistor ladder IMO.
Code:
Device = 18F43k22
Clock = 20

// some LCD options...
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3

// uses LCD and AD libraries...
Include "LCD.bas"
Include "convert.bas"

// read the AD port and scale for 0 - 5 volts...
End Function

Dim led As PORTA.0
dim led1 as portc.0
// initialise and clear LCD...
ADCON1 = $07 // PORTE as digital (LCD) TRISA.1 = 1 // configure AN0 as an input /// ADCON1.6 = 1 // set analogue input on PORTA.0 /// DelayMS (500) LCD.Cls Input(PORTA.0) // ADC IN on portA.1 // ADCON1 = %10000000 //set up ADC regesters //ADCON0.7 = 1 //ADCON0.6 = 1 ADCON1 =$07
TRISA = %11111111
TRISB = %11111111
TRISC = %00000000
TRISD = %00000000
TRISE = %000

/////////////////////////////
TRISA=%00000001
ANSELA=%00000001
///////////////////////////////////

DelayUS(10)
Wend

// main program loop...
While true
led1=1
DelayMS(1000)
led1=0
DelayMS(1000)
LCD.MoveCursor (1,1)
LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
DelayMS(250)
Wend

#### Visitor

##### Active Member
Glad it works for you. But why are you converting the ADC reading to volts? Better to leave it as 10 bit data, save some extraneous math, and have higher resolution.

What's the idle state value? I've lost track of how you have the matrix arranged. It should either be pulled high (~1023) or low (~0) when no switch is pressed. Then a simple Case/Select will give you what button is pressed. Start with the idle case. Let's suppose the idle case is high.

Code:
Dim ADCOut as Word

Case > 1000 'value over 1000
'no button pressed

Case > 900  'value between 901 – 1000
'Button 10 pressed

Case > 800 'value between 801 – 900
'Button 9 pressed

Case > 700 'value between 701 – 800
'Button 8 pressed

'And so on.

End Select
Of course you have to adjust the ranges for the values you are reading.

Remember, the Case/Select is exited when one of the conditions is met – the following tests are ignored. Say the value is 750. The first three tests fail. The 4th test, for value > 700 is met, indicating button 8 was pressed.

#### MrDEB

##### Well-Known Member
that's where I was headed visitor. Just wanted to get the ADC example working first.\
I used similar several years ago for a beer cooler thermostat.
looking at data sheet, page 301 and 151 for clues to use porte instead of porta. No good results yet.

#### tumbleweed

##### Active Member
try this...
Code:
Device = 18F43K22
Clock = 20

// some LCD options...
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3

// uses LCD and AD libraries...
Include "LCD.bas"
Include "convert.bas"

// ****** change this to select between  0 (AN0, PORTA.0) or 5 (AN5, PORTE.0) ******

// read the AD port and scale for 0 - 5 volts...
End Function

Dim led As PORTA.0
dim led1 as portc.0

// setup IO pins
TRISA = %11111111
TRISB = %11111111
TRISC = %00000000
'TRISD = %00000000      // PORTD is set by LCD.BAS
TRISE = %001

// initialise and clear LCD...
DelayMS (500)
LCD.Cls

Input(PORTA.0)                  // ADC IN on portA.0
ANSELA=%00000001                // ANSA0
Input(PORTE.0)                  // ADC IN on portE.0
ANSELE=%00000001                // ANSE0
endif

/////////////////////////////
ADCON0.bits(1) = 1                       // GO (start convert)
///////////////////////////////////

// main program loop...
While true
led1=1
DelayMS(1000)
led1=0
DelayMS(1000)

LCD.MoveCursor (1,1)
LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
Wend
You have to be careful... ADC.BAS hasn't been updated in eons, but I think Adc.Read() should still work for what you're doing.

#### MrDEB

##### Well-Known Member
attempting to chop the bits into 1023 pieces but just getting volts. My math is wrong?
want to go w/ case select as suggested in post 14
then attempt to go from portA over to portE as Tumble weed suggested.

#### Visitor

##### Active Member
attempting to chop the bits into 1023 pieces but just getting volts. My math is wrong?
The value read from the ADC is 10 bits = 0 to 1023. There is no need to chop anything. No math required. Use the value read out, but it must go into a variable dimensioned as a WORD to handle 10 bits.

#### Visitor

##### Active Member
You have to be careful... ADC.BAS hasn't been updated in eons, but I think Adc.Read() should still work for what you're doing.
Are you aware that there is a recent update (last few months)? I believe that ADC.BAS and most of the other include files have been updated to support new chip variants.

#### MrDEB

##### Well-Known Member
Does it need to be an integer?
will check the ADC.bas. I think I have the latest as I refreshed with version 2.2.3.0
will keep grinding away.