MrDEB

Well-Known Member
I tested the LCD and it works. Eventually want to read the ADC on portA.0 and portA.1
using Swordfish
Code:
Device=18f43k22
Clock = 8            '8MHz
'Config FOSC = INTIO7   'internal oscillator
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
// import LCD library...
Include "SetDigitalIO.bas"
'Include "IntOSC.bas"
'Include "LCD.bas"
Include "utils.bas"
Include "LCD.bas"
Include "convert.bas"
// read the AD port and scale for 0 - 5 volts...
End Function

Dim led As PORTC.7
// initialise and clear LCD...
ADCON1 = $07 // PORTE as digital (LCD) TRISA.0 = 1 // configure AN0 as an input ADCON1.7 = 1 // set analogue input on PORTA.0 DelayMS (500) LCD.Cls Output(led) SetAllDigital // main program loop... While true led=1 DelayMS(500) led=0 DelayMS(500) ADVal = ADInAsVolt LCD.MoveCursor (1,1) LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ") DelayMS(2500) Wend Visitor Active Member The words all have meanings, and this has been explained to you before. What does the first circled area do? What does the second circled area do? MrDEB Well-Known Member got it working with two ports Code: Device=18f43k22 Clock = 8 '8MHz Config FOSC = INTIO7 'internal oscillator #option LCD_DATA = PORTD.4 #option LCD_RS = PORTD.2 #option LCD_EN = PORTD.3 // import LCD library... Include "utils.bas" Include "LCD.bas" Include "ADC.bas" Include "convert.bas" // read the AD port and scale for 0 - 5 volts... Function ADInAsVolt() As Word result = (ADC.Read(0) + 1) * 500 / 1024 End Function Function ADInAsVolt2() As Word result = (ADC.Read(1) + 1) * 500 / 1024 End Function // sampled AD value... Dim ADVal As Word dim adval2 as word // set this option true if building with the SE compiler Dim led As PORTC.7 Output(led) led=0 // program start... SetAllDigital While true 'led=1 'DelayMS(500) 'led=0 'DelayMS(500) Cls ADVal = ADInAsVolt adval2= ADInAsVolt2 LCD.MoveCursor (1,1) LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ") writeat(2,1,"dc volts = " ,DecToStr(ADVal2 / 100), ".", DecToStr(ADVal2, 2), " ") DelayMS(50) 'WriteAt(1,1,"Hello World") 'DelayMS(2000) Wend the circled area got put in by mistake from SAMPLE ADC CODE my working code doesn't have porte it was an oversite the circled area sets the ports up for adc input. I think the ADC.bas sets all the registers. Visitor Active Member Actually learning what the words mean rather than copy&pasting an example from somewhere else might help you understand programming. Visitor Active Member MrDEB, you may have noticed the number of people willing to help you is pretty close to ZERO. If you haven't, you should take notice of that fact. You, with an inordinate amount of help, usually manage to make something work with a lot of trial and error, but it takes a lot out of those few folks willing to try to help you. It's time you actually learn to code, rather than copy&pasting random bits of code together. I tried to get you to actually think with my post with the circles, but your reply was you pasted the wrong thing. You will not learn anything that way. So, start with the simple stuff. ¤ What does SETALLDIGITAL do and why is this necessary? This is a simple question, yet essential for programming. ¤ What do the TRIS and ADCON statements in the first circle do? Again, simple question and the answer is in the remarks. ¤ What happens to whatever the TRIS and ADCON accomplish when followed by SETALLDIGITAL? If you can answer the first two questions, this will be easy to figure out. Your problem is an extremely simple troubleshooting exercise that should have taken 30 seconds to spot. This isn't a complex problem; it's something that should be easy to recognize and fix. gophert Well-Known Member Most Helpful Member If computer and microcontroller manufacturers knew anything about product design, they would design their products to do what users wanted them to do, rather than what the user literally tell them to do. Visitor Active Member If computer and microcontroller manufacturers knew anything about product design, they would design their products to do what users wanted them to do, rather than what the user literally tell them to do. "Do what I meant, not what I said"? gophert Well-Known Member Most Helpful Member And before anyone gets out of control, post 6 was a joke. Visitor Active Member And before anyone gets out of control, post 6 was a joke. One could argue that that post isn't the only joke on this thread. gophert Well-Known Member Most Helpful Member One could argue that that post isn't the only joke on this thread. Every time I read new posts in this thread or the in famous (infamous) Christmas tree star thread, I think to myself, either Visistor has the patience of Job or he loves to be tormented. Then I looked up he current spelling of Job's name and discovered that Job was not patient at all. The word "patience" was a mistranslation in the King James Version of the Bible. It should have been Endurance. And, the quotes of Job are pretty in line with the quotes of Visitor as as he complains about his toils situation. The only difference between Job and Visitor, Job couldn't walk away from his source of torment. MrDEB Well-Known Member SETALLDIGITAL sets all the IO pins to analog/ digital Trisx configures the port adcon1.7 =1 sets analog input to porta Visitor Active Member SETALLDIGITAL sets all the IO pins to analog/ digital Trisx configures the port adcon1.7 =1 sets analog input to porta Ha ha ha. This "understanding" explains so much. Try again and answer the questions as asked. You might actually learn something. tumbleweed Active Member Here's where copy-paste has gotten you into trouble all over again. All pic's aren't the same, so what you did/copied for one device may not work for another. You need to actually read the datasheet for the part you're using, or at least check that the register settings you have in your code match up to the chip. For example, here are some comments for what you had: Code: Device=18F43K22 // THIS DOES NOT SET "PORTE as digital (LCD)" // ADCON1 selects the positive and negative reference for the ADC ADCON1 =$07       // PORTE as digital (LCD)

// THIS IS TRUE
TRISA.0 = 1        // configure AN0 as an input

// THIS DOES NOT "set analogue input on PORTA.0"
// IT SELECTS THE SPECIAL TRIGGER FROM CTMU
ADCON1.7 = 1       // set analogue input on PORTA.0

DelayMS (500)
LCD.Cls
Output(led)

// IF THE ABOVE HAD DONE WHAT YOU WANTED, IT WAS TO NO AVAIL
// SINCE CALLING "SetAllDigital" NOW WILL WIPE OUT MOST/ALL THE ABOVE SETTINGS
SetAllDigital
And here's the real mind-blower... you don't have to set a pin's analog/digital mode to use the ADC.

As long as the pin is an input (use the INPUT statement) you can convert it.
You really only need to set a pin to analog mode to disable the digital input buffer which will not be happy with analog voltages at its input.
You DO, however have to set the "digital" pins to "digital mode" since they all power up as analog by default, and a pin in analog mode will always read as a '0' to the digital input.

Since all of that is probably gibberish, here are some tips

- use SetAllDigital at the beginning or your program, before you start doing anything else.
there is a subroutine called SetAnalogPort in the file SetDigitalIO.bas that you can use after that to set the one or two pins you want to use
with the ADC back to analog mode. That way you won't have to figure out the difference between how this works for all the different chips.

- use 'output' and 'input' statements and skip using the TRISx registers

- don't set a register when you have no idea what it does

Here's an example which sets all pins to digital except for RA0
Code:
device =18F43K22
include "setdigitalio.bas"

SetAllDigital

input(PORTA.0)
SetAnalogPort(AN0, ANA)

// rest of your code...

Last edited:

MrDEB

Well-Known Member
Yes a different code was pasted in wrong. I am not using the original posted code that failed to work.
Only using the Include "setdigitalio.bas" and placing it just before the WHILE TRUE statement
will search for the SetAnalogPort sub route.
presently attempting to get two leds controlled using a pot and the ADC function.
Led1 on then led2 on turning the pot slightly more turns off led1 but led2 stays on.
just need to refine the turn on/turn off points

tumbleweed

Active Member
Only using the Include "setdigitalio.bas" and placing it just before the WHILE TRUE statement
What part of
- use SetAllDigital at the beginning or your program, before you start doing anything else.
was ambiguous?

You really want it to be the FIRST statement, not later on after you've done other things.
Otherwise it could trash other changes you might have made.

Better yet, change the line where to have
Code:
include "setdigitalio.bas"
to the following and you'll never have to call SetAllDigital again, it will be done automatically for you.
Code:
#option DIGITALIO_INIT = true
include "setdigitalio.bas"
You want to add this at the very top of your program, not after a big long list of 'include' statements.
If you use those two lines, in that order, you can then remove all the SetAllDigital calls

MrDEB

Well-Known Member
will give it a go
thanks
never heard of doing this in an include statement

tumbleweed

Active Member
If the setdigitalio.bas module sees that '#option DIGITALIO_INIT = true' then it'll automatically call the code for SetAllDigitial for you when the program starts up.

That's why the order of the two statements matters. The '#option' has to be set BEFORE you 'include', otherwise it won't be seen true and the compiler will skip generating the code.

The reason why you want those two lines before all the other 'includes' is that the compiler will process the include files in the order you list them.
If you have a bunch of other files before setdigitalio.bas then they will get processed first and a lot of other code could get
inserted before the code for SetAllDigital gets added.

This works the same way for all '#options'.

You want the program to set the digital/analog mode of the pins before you do anything else, otherwise pins might read as a '0' since the chip powers up with them in analog mode. That could cause your code to not work as intended.

Last edited:

Ian Rogers

User Extraordinaire
Forum Supporter
MrDEB !!!! Before Jon pops a gasket..

SETALLDIGITAL .... SET ALL pins to DIGITAL..... Thus turns off the ADC to every pin.... To turn on individual ADC pins either use the ADCON reg's , or the newer chips, the ANSEL reg's

tumbleweed

Active Member
Actually, just to clarify, all of this analog/digital mode stuff never disables the ADC inputs...
it just enables or disables the digital input buffer, which is disabled by default for any pins that have analog capability.

It doesn't prevent you from reading an input pin with the ADC, even of the pin is set for "digital mode".
What it DOES screw with is the ability to read the pin normally.

When a pin is set for analog mode (which remember, is the default) its digital input buffer is disabled and it will ALWAYS read as a logic '0'.
That's why it's important to set the pin mode early in the startup sequence.

If a pin is going to be used for analog voltages (ie ADC, comparators, etc) it's a good idea to set it to analog mode.
That way the digital input buffer won't see invalid digital levels. For example, if a digital input sees 1.5V it's neither a valid high or a low.
This can cause the input buffer to oscillate and increase current consumption, which is never a good idea.

That's why they have the chip default to analog mode (which causes everyone to cuss and b*tch).