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:
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?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




Bookmarks