Swordfish Tutorial - ADC (Output to LCD)

This Analogue to Digital (ADC) PIC micro example is not only great for learning how to use ADC with Swordfish, but also to learn how a  Function works. The  Function will perform the required task/commands and then return with a Word variable called Result. you don't need to declare the variable "Result", as its the sole purpose of using a Function.

In this case, the Function is called "ADInAsVolt". It gets the ADC value on channel 0, and converts it to volts, and stores it in the Functions Result register. Just because the Function is at the start of the program does not mean that it is executed at the start - the first line to be executed is "ADCON1 = $07", and the program follows on from there. The command ADVal = ADInAsVolt instructs the program to call the function, and store the result in ADVal. Handy!

Device = 18F452
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 "ADC.bas"
Include "convert.bas"
 
Dim ADVal As Word
// Read the AD port and scale for 0.00 - 5.00 volts...
Function ADInAsVolt() As Word
 result = (ADC.Read(0) + 1) * 500 / 1024
End Function
 
// Start Of Program...
ADCON1 = %10000000
ADCON0.7 = 1
ADCON0.6 = 1
 
DelayMS (150)
LCD.Cls
 
// main program loop...
While true
 ADVal = ADInAsVolt
 LCD.MoveCursor (1,1)
 LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
 DelayMS(250)
Wend

img2B1

Note the PIC's power supply/oscillator are not shown


Voltages over 5V


For voltages that exceed 5V that you wish to sample, simply use a voltage divider network like the following;

adc20voltage20divider1


For best ADC performance of the PIC micro, the input impedance should not exceed 2.5K as the PIC's internal capacitors will take too long too charge/discharge. This isn't really an issue for most projects though, as you can just change the sample time with a couple of settings - see the help file of your compiler for more information. I generally use 10K resistors without any issues.


Video Tutorials:


Using a PIC Datasheet to initialize ADC settings

  • Explores the different settings for the 18F452 that setup the ADC settings

 

18F452 ADC Example

  • Simulation of the code and circuit shown throughout the above example.

 


Posted: 7 years 11 months ago by MrDEB #9092
MrDEB's Avatar
I programmed a 18F452 as in the example but the LCD reads numerous different voltages. WHY
it jumps over a wide range. Using a 10k pot. perhaps a smaller pot??
Posted: 7 years 11 months ago by MrDEB #9086
MrDEB's Avatar
I think I found a fix
I replaced the pot with a 200k multi turn pot (first one I found)
contemplating a voltage divider using the thermistor in the Hakko soldering iron (50ohm(room temp) to 180 ohm (solder melts).
Would like to incorporate a UAA2016 zero voltage switch on an output of the 18F452.
Get lost on the math configuring the triac Ihold etc.
Posted: 7 years 11 months ago by MrDEB #9085
MrDEB's Avatar
am I to assume that by changing the math I can achieve a better resolution?
result = (ADC.Read(0) + 1) * 250 / 1024
see changes. By using moisten fingers across one of the 1k resistors in the voltage divider,the volts on the LCD change ever so slightly.. If left at 500 there is no change
Device = 18F452
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 "ADC.bas"
Include "convert.bas"
 
Dim ADVal As Word
// Read the AD port and scale for 0.00 - 5.00 volts...
Function ADInAsVolt() As Word
 result = (ADC.Read(0) + 1) * 250 / 1024  // [color=#FF0000]INSTEAD OF 500 change to 250[/color]
End Function
 
// Start Of Program...
ADCON1 = %10000000
ADCON0.7 = 1
ADCON0.6 = 1
 
DelayMS (150)
LCD.Cls
 
// main program loop...
While true
 ADVal = ADInAsVolt
 LCD.MoveCursor (1,1)
 LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")
 DelayMS(250)
Wend

Posted: 7 years 11 months ago by Jon Chandler #9052
Jon Chandler's Avatar
am I to assume that by changing the math I can achieve a better resolution?

Sigh. The ADC resolution on most PIC18F-series parts is 10 bits (although some 12-bit parts are available).

10 bits -->

2^10 = 1024 possible values from the ADC.

All the math in your code is to convert this reading to 5 volts, assuming Vref (which is Vcc) is 5 volts. Does 5 volts mean anything as a temperature? No. There's no reason to scale to 5 volts as it doesn't mean anything in this context.

Use the ADC values directly until/unless you can convert them to a relevant temperature.
Posted: 7 years 11 months ago by MrDEB #9053
MrDEB's Avatar
I found this over at Microchip
http://ww1.microchip.com/downloads/en/A ... 01152A.pdf
It suggests an instrument amp, oversampling etc???
LOST in Salmon but pecking away.
Close as I can come is 50 ohms or 2.56volts = 75F
180ohms = 2.70 volts at which temp solder melts (300F)
I simulated the amp on the microchip site and found a 1 volt input I can get an 15volt output.Weather this helps any?? Thinking increasing the resolution x 15?
Like I said, LOST but simulating different ideas.
Posted: 7 years 11 months ago by Jon Chandler #9054
Jon Chandler's Avatar
I simulated the amp on the microchip site and found a 1 volt input I can get an 15volt output.Weather this helps any?? Thinking increasing the resolution x 15?

15 volts into the ADC of a PIC will let out the magic smoke.
Posted: 7 years 11 months ago by MrDEB #9055
MrDEB's Avatar
I realize that. I was on the wrong track. Thinking that increasing the voltage then using a voltage divider to keep it below 5v but won't work. Going in the wrong direction.
going to look at your thermocouple project and see what computations to convert the ADC into degrees.
Using the posted code
LCD.Write("DC Volts = ", DecToStr(ADVal / 100), ".", DecToStr(ADVal, 2), " ")I think I need to figure out the conversion. Looking at .004mv per degree? as a ballpark.
Posted: 7 years 11 months ago by Jon Chandler #9056
Jon Chandler's Avatar
It would take some research (i.e., you need to figure it out yourself) but it is possible to use Vref+ and Vref- to expand the ADC range. The 1024 counts of the ADC could cover 2v - 4v instead of 0v - 5v for example. This puts all of the resolution in the needed range.

A better approach might be in how the resistance of the temperature sensor is read. Rather then using a voltage divider to convert to a voltage, use a constant current supply.

V = I*R, where I is a constant of a few mA.

The easy alternative is to order a solder station from someplace like Circuit Specialists. They have temperature-controlled stations starting at $30.
Posted: 7 years 11 months ago by jmessina #9057
jmessina's Avatar
Looking at .004mv per degree? as a ballpark
4 microvolts/degree is a very, very small number.

If you want to measure that with a pic, it needs to be about 10,000 times larger just to get out of the noise.
Posted: 7 years 11 months ago by be80be #9058
be80be's Avatar
Some of the best SOLDERING STATION are no where near as dead on temp as you would think
there +/- 2 degree at no load. But what makes them great is that when you solder they can heat up fast
rapid heat-up temperature and fast thermal recovery

Forum Activity

Member Access