ADC Averaging problem

Status
Not open for further replies.
Hi Eric,
Thanks for the code, however I'm not sure that does what I want.

I want to be able to detect and signal when I have not received a data string via interrupts for 10secs.

But, maybe I am wrong and it does that...

Cheers
Stewart
 
Hi Eric,
Thanks for the code, however I'm not sure that does what I want.

I want to be able to detect and signal when I have not received a data string via interrupts for 10secs.

But, maybe I am wrong and it does that...

Cheers
Stewart

hi,
What you would do is to have the TMR1 loaded with the maximum count, such that when it rolls over at 0xffff to 0x0000 it would generate an interrupt or an action.
While you are receiving data OK, you would reset the TMR1 count back to zero, so f data is being received continuously then TMR1 would never roll over.
When it rolls over you bump a counter, if after 10secs then you do the LCD reset msg.

Instead of letting the TMR1 initiate an interrupt you could test the PIR1.TMR1IF flag.

OK.?

EDIT:
I you wish, post your ISR code and I will attempt to insert the extra code for the TMR1
Whats the crystal freq.?
 
Last edited:

That's it exactly... The crystal frequency is 20MHz

Code:
' Interrupts - Disabled/Enabled in int routine by compiler
'
On High Interrupt				'different syntax to 16F877A
Save System				'save system vars

If PIR1.RCIF = 1 Then			'it was a serial interrupt
   Hserin RxChar 		            	'get one character from UART
   RxBuf (RxCount)  = RxChar		'write to array
   RxCount = RxCount+1           	'prepare for next char
'
	If RxCount  > 38 Then		'we are expecting 38 chars
   	RxCount  = 0  			'reset array on overflow of > 38 Chars
		DataFlag = False		'bad freq data
		Goto TooLong		'string too long, bail out
	Endif
'
	If RxChar = ";" Then		'string terminator ?
		If RxCount = 38 Then	'and 38 chars ?
      	RxCount = 0   			'reset array 
         For i=5 To 8    			'save 4 wanted freq chars in RxBufCopy
         	RxBufCopy (i) = RxBuf (i)
         Next i
	 DataFlag = True	'good freq data
			'
	' Read L ADC and calculate an average reading
	ADCTemp = 0
			'
	For i=0 to 7			'take 8 ADC readings
		Adcin 2,RawADCL	'get ADC value for L from 2nd channel
		ADCTemp = ADCTemp + RawADCL
	Next i
			'
	AvgADCL = ShiftRight(ADCTemp,3)	'shift right 3 places to div by 8
									'and store  avg L ADC value
			'												
	' Read C ADC and calculate an average reading
	ADCTemp = 0
	'
	For i=0 to 7			'take 8 ADC readings
		Adcin 3,RawADCC	'get ADC value for C from 3nd channel
		ADCTemp = ADCTemp + RawADCC
	Next i
			'
	AvgADCC = ShiftRight(ADCTemp,3)	'shift right 3 places to div by 8
									'and store the avg C ADC value
	Else
                Rxcount = 0					'reset array
	        DataFlag = False 				'bad freq data
	Endif
	Endif
Else                         	 		                           'not our interrupt, ignore it.
Endif
'
TooLong:
'
PIR1.RCIF = 0								'reset interrupt flag
'	
Resume

Cheers
Stewart
 
hi Stewart,
Look at this option, marked additions with ++++++++++++++++++++

Code:
'18F4620  Intr Demo 1

''' +++++++++++++++++++++++++
Dim i As Byte
Dim intrcnt As Byte
T1CON = %01001001  ''' prescaler set for 1:8 so 20MHz/4 = 5MHZ internal, div by 8
'' =625KHz TMR1 clock, divided by 65536 gives a TMR1 int every 104,857uSec
'' say 0.1sec, so have your intr counter max set to approx 100

TMR1H = 0x00
TMR1L = 0x00
INTCON.GIE = 1
INTCON.PEIE = 1
PIE1.TMR1IE = 1
PIR1.TMR1IF = 0
IPR1.TMR1IP = 0
''++++++++++++++++++++++++++++


''interrupts - disabled / enabled in int routine by compiler

On High Interrupt  'different syntax to 16F877A
Save System  'save system vars


If PIR1.RCIF = 1 Then  'it was a serial interrupt
Hserin rxchar  'get one character from UART
rxbuf(rxcount) = rxchar  'write to array
rxcount = rxcount + 1  'prepare for next char

    If rxcount > 38 Then  'we are expecting 38 chars
    rxcount = 0  'reset array on overflow of > 38 Chars
        dataflag = False  'bad freq data
        Goto toolong  'string too long, bail out
    Endif

    If rxchar = ";" Then  'string terminator ?
        If rxcount = 38 Then  'and 38 chars ?
    rxcount = 0  'reset array
For i = 5 To 8  'save 4 wanted freq chars in RxBufCopy
    rxbufcopy(i) = rxbuf(i)
Next i
    dataflag = True  'good freq data
            
    'Read L ADC and calculate an average reading
    adctemp = 0
            
    For i = 0 To 7  'take 8 ADC readings
        Adcin 2, rawadcl  'get ADC value for L from 2nd channel
        adctemp = adctemp + rawadcl
    Next i
            
    avgadcl = ShiftRight(adctemp, 3)  'shift right 3 places to div by 8
                                    'and store  avg L ADC value
            
    'Read C ADC and calculate an average reading
    adctemp = 0
    
    For i = 0 To 7  'take 8 ADC readings
        Adcin 3, rawadcc  'get ADC value for C from 3nd channel
        adctemp = adctemp + rawadcc
    Next i
            
    avgadcc = ShiftRight(adctemp, 3)  'shift right 3 places to div by 8
                                    'and store the avg C ADC value
    Else
rxcount = 0  'reset array
    dataflag = False  'bad freq data
    Endif
    Endif

'+++++++++++++++++++++++++++++++++++++++++++++++
    TMR1H = 0x00  '######'  recv oK so restart TMR1 at 0000
    TMR1L = 0x00  '######
'++++++++++++++++++++++++++++++++++++++++++++++
    
Else  'not our interrupt, ignore it, test for TMR1 intr'++++

'+++++++++++++++++++++++++++++++++++++++++++
    If PIR1.TMR1IF = 1 Then  'its a TMR1 intr
    PIR1.TMR1IF = 0  'clr intr flag
    intrcnt = intrcnt + 1  'bump intr cnt
    TMR1H = 0x00  'reload TMR1 with 0000
    TMR1L = 0x00
    Endif

    If intrcnt > 100 Then  'if max time elapsed then do msg
    '''do reset msg
    ''' intr=0
    PIR1.TMR1IF = 0  'clr intr flag
    Endif
'+++++++++++++++++++++++++++++++++++++++++++++++
Endif

toolong:


PIR1.RCIF = 0  'reset interrupt flag

Resume
 
Last edited:
Thank you very much Eric. That gives me a good platform to build on. I will let you know how I get on.

Cheers
Stewart
 
Last edited by a moderator:
Thank you very much Eric. That gives me a good platform to build on. I will let you know how I get on.

Cheers
Stewart

Hi,
I slight correction is that the intrcnt has to be zeroed at this point.

Code:
'+++++++++++++++++++++++++++++++++++++++++++++++     
TMR1H = 0x00  '######'  recv oK so restart TMR1 at 0000     
TMR1L = 0x00  '######
  intrcnt= 0'+++++++++++
 '++++++++++++++++++++++++++++++++++++++++++++++
 

Thanks Eric,
With your help I have now got it sussed. However rather than use TMR1 with interrupts I have used TMR0 16 bit with a 1:256 prescaler which gives 3.2 secs straight.
I have not used timer interrupts, but instead check the overflow flag in the main code. It is accurate enough, and the delay long enough for my needs.

Again thank you and others for your help.

Stewart
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…