Switched to using a 16F1825 that was previously rock solid and it's still jumping around like crazy. Could it be this 5V switching voltage regulator? This code was what I used previously to test 10-bit ADC and is what I just loaded onto the 16F1825:
Code:
' ****************************************************************
' PIC16F1825
' ****************************************************************
#DEFINE USE_LCD_FOR_DEBUG ; comment out for non-debug use
' Vdd -> pin 1 -> +5V
' RC5/Rx -> pin 5 -> EUSART receive
' RC4/Tx -> pin 6 -> EUSART transmit (LCD)
' RA1 -> pin 12 -> trim pot input (1 uF electrolytic cap?)
' Vss -> pin 14 -> GND
DEFINE OSC 16 ; Set oscillator 16Mhz
' ***************************************************************
' EUSART Settings for Tx/Rc (e.g. LCD)
' ***************************************************************
' > use Mister E PIC Multi-Calc application to get register/DEFINE settings
' > as the values are dependent on the OSC and desired baud rate
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 160 ' 9600 Baud @ 16MHz, -0.08%
' ***************************************************************
' Device Fuses
' ***************************************************************
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _WDTE_ON & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _STVREN_ON & _BORV_LO & _LVP_OFF
#ENDCONFIG
' ***************************************************************
' Initialization
' ***************************************************************
OSCCON = %01111000 ; 16MHz internal osc
pause 100
APFCON0.2 = 0 ; Tx on RC4 for LCD display
APFCON0.7 = 0 ; Rx on RC5
' Some LCD serial modules need inverted data, some do not
' Enable the line below if needed, but for SparkFun SerLCD it should be
' commented out
'BAUDCON.4 = 1 ; Transmit inverted data to the Tx pin
' From Mister E's Multi-Calc (EUSART):
' *****************************************************************
SPBRGH = 1
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
' *****************************************************************
ANSELC = 0 ; Digital only for all PortC pins
TRISC = 0 ; Make all PORTC pins output
TRISA = %00000010 ; Make all pins output except for RA1 (trim pot input)
ANSELA = %00000010 ; Analog on PORTA.1 (AN1) only
FVRCON = 0 ; Fixed Voltage Reference is disabled
ADCON0 = %00000101 ; ADC enabled on AN1 (RA1) only; ADC conversion enabled
PAUSEUS 20 ; wait for the analog switch 'glitch' to die down
ADCON1 = %10010000 ; Right-justified results in 10-bits; Fosc/8 as timer
#IFDEF USE_LCD_FOR_DEBUG
' Display control codes for SerLCD serial LCD (SparkFun part #LCD-09395)
' (see 'Dropbox\PBP Projects\PIC Datasheets\SerLCD_V2_5 Datasheet.pdf'
' for list of control codes)
LCD_INST CON 254 ' instruction
LCD_CLR CON 1 ' Clear screen
LCD_L1 CON 128 ' LCD line 1
LCD_L2 CON 192 ' LCD line 2
LCD_BR_CMD CON 124 ' command character for adjusting backlight brightness
LCD_BR_LVL CON 140 ' 140==40%
#ENDIF
' Should only need to do this one time to adjust backlight brightness
'#IFDEF USE_LCD_FOR_DEBUG
' HSEROUT [LCD_BR_CMD, LCD_BR_LVL]
' PAUSE 5
'#ENDIF
#IFDEF USE_LCD_FOR_DEBUG
pause 1000
HSEROUT [LCD_INST, LCD_CLR, "LCD Init"]
pause 5
HSEROUT [LCD_INST, LCD_L2, "SerLCD_V2_5"]
pause 500
#ENDIF
ADCInVal VAR WORD ; stores ADCIN result read from trim pot
compVal VAR WORD ; stores last-changed ADC value
GOSUB Do_ADC
compVal = ADCInVal ; set initial compare value
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["ADCInVal=",DEC ADCInVal," "]
pause 500
#ENDIF
Main:
gosub Do_ADC
pause 100
If (compVal > (ADCInVal + 1)) or (compVal < (ADCInVal - 1)) THEn
' If this method of reading ADC is as rock-solid as it appears.
' then I can remove the +/- 1 before doing anything; it would be
' IF ADCInVal <> compVal
' DO SOMETHING HERE
compVal = ADCInVal
#IFDEF USE_LCD_FOR_DEBUG
HSEROUT [LCD_INST, LCD_CLR]
pause 5
HSEROUT ["new ADCInVal", LCD_INST, LCD_L2, DEC ADCInVal, " "]
#ENDIF
endif
GOTO Main
Do_ADC:
PAUSEUS 50 ' Wait for A/D channel acquisition time
ADCON0.1 = 1 ' Start conversion
WHILE ADCON0.1 = 1 ' Wait for it to complete
WEND
ADCInVal.HighBYTE = ADRESH
ADCInVal.LOWBYTE = ADRESL
return
EDIT: Tried the standard 7805 voltage reg approach and it's more stable but still jumps around by 3-4. Could it be the settings for my serial LCD on EUSART Tx?
Bookmarks