PDA

View Full Version : DT averaging of interrupt driven cap sensor



Max Power
- 12th September 2011, 05:31
Hey DT,

I've used your averaging routine on some of my non-interrupting (start timer, pause for 50mS, stop timer), relaxation oscillator, cap sensors, and it's worked great. Now I've graduated on to using the CSM module driven by an interupt. And I'm having trouble getting the same great results.

The average value does not eventually reach the present value after it drops, and sometimes it just mirrors it, and sometimes the average value spikes up.

If you could take a look at what I'm doing, I'd really appreciate it.



'MPLAB 8.70, PICBASIC PRO Compiler 2.60C, Darrel Taylor Instant Interrupts-14_V110 (http://darreltaylor.com/DT_INTS-14/intro.html)
'PIC16F1823 14 PIN dip package


@ __CONFIG _CONFIG1, _FCMEN_OFF & _FOSC_INTOSC & _WDTE_SWDTEN & _MCLRE_OFF & _CP_OFF & _IESO_OFF & _BOREN_OFF & _PWRTE_OFF
@ __CONFIG _CONFIG2, _LVP_OFF

DEFINE OSC 8 'tell picbasic what speed the oscillator is

DEFINE DEBUG_REG PORTA ' asyncronous bit-banged RS-232 output on PORTA...
DEFINE DEBUG_BIT 0 ' bit 0, which can be seen with the PICKIT2 UART tool, but you can't program this chip with the PICKIT2?!?!
DEFINE DEBUG_BAUD 9600 ' 9600 Baud,
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true,like for using max232, or pickit2
DEFINE DEBUG_PACING 1000 ' 1mS delay

INCLUDE "DT_INTS-14.bas" '
INCLUDE "ReEnterPBP.bas" ' Include if using PBP interrupts

OSCCON = %01110010
'0 = 4x PLL is disabled
'1110 = 8 MHz
'0 = unused
'1X = Internal oscillator


ANSELA = %00000000 'make port A pins digital
TRISA = %00000000 'make port A pins outputs

ANSELC = %00000010 'make pin 9 (RC1) (CPS5) analog
TRISC = %00000010 'make pin 9 (RC1) (CPS5) input


OPTION_REG = %10000111
'1 = All weak pull-ups are disabled (except MCLR, if it is enabled)
'0 = Interrupt on falling edge of RB0/INT pin
'(TMR0CS) 0 = Transition on RA4/T0CKI pin
'0 = Increment on low-to-high transition on RA4/T0CKI pin
'0 = Prescaler is assigned to the Timer0 module
'111 = 1:256 Timer0 prescaler rate

T1CON = %11000001 'enable timer 1 (bit 0) & source the clock from the CPS module (bit 6 & 7 =11

CPSCON0 = %10001100 'set the CPS module highest frequency availabe (for vcc mode) + timer0 clock sourced from CPS module. (BIT 1)
'1 = CPS module is enabled
'0 = CPS module is in the low range. Internal oscillator voltage references are used.
'00 = unused
'11 = Oscillator is in High Range. Charge/Discharge Current is nominally 18 ľA
'0 = Capacitive Sensing Oscillator Status bit (only readable)
'0 = Timer0 clock source is controlled by the core/Timer0 module and is FOSC/4

CPSCON1 = %00000101 '0101 = channel 5, (CPS5)

CM1CON0 = 0 ' COMPARATOR OFF
CM1CON1 = 0 ' COMPARATOR OFF

PAUSE 3000

DEBUG "Starting Up",13,10


VALUE var WORD
AVE var WORD


AvgCount CON 50 ' Number of samples to average
FAspread CON 8000 ' Fast Average threshold +/-


ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _Timer0_Int, pbp, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM

TMR0 = 0 'clear TIMER0
@ INT_ENABLE TMR0_INT 'enable timer0 interrupts

main:
pause 100
@ INT_DISABLE TMR0_INT ' stop timer0 interrupts
DEBUG DEC VALUE, ", ", DEC AVE, 13,10
@ INT_ENABLE TMR0_INT ' re-enable timer0 interrupt

goto main

'************************************************* *************************************************
Timer0_Int:
@ INT_DISABLE TMR0_INT ' stop timer0 interrupts
Value = TMR1

IF Value = AVE Then NoChange
IF ABS (Value - AVE) > FAspread OR Value < AvgCount Then FastAvg
IF ABS (Value - AVE) < AvgCount Then RealClose
AVE = AVE - (AVE/AvgCount)
AVE = AVE + (Value/AvgCount)
GoTo AVGok
FastAvg:
AVE = Value
GoTo AVGok
RealClose:
AVE = AVE - (AVE/(AvgCount/4))
AVE = AVE + (Value/(AvgCount/4))
AVGok:
' Value = AVE ' Put Average back into Value
NoChange:

'TMR0 = 0 'clear Timer0, interrupt occurs every 32.77mS
TMR0 = 61 'preload Timer0 with 61 so the interrupt occurs every 24.96mS
TMR1 = 0 ' clear TIMER1
@ INT_ENABLE TMR0_INT ' re-enable timer0 interrupt
@ INT_RETURN
end




here is some data that I get out


14459, 14459
14457, 14456
14455, 14457
14457, 14458
14461, 14457
14458, 14462
14446, 14458
14452, 14456
14452, 14456
14453, 14456
14403, 14425
14326, 14349
14271, 14304
9743, 14028
8262, 13834
7988, 13576
7764, 13434
7694, 13180
7683, 12942
7680, 12723
7678, 12520
7677, 12333
7679, 12253
7668, 12086
7658, 11933
7649, 11790
7647, 11656
7636, 11612
7632, 11491
7634, 11379
7615, 11275
7620, 11178
7616, 11089
7624, 11078
7624, 10998
7616, 10925
7598, 10855
7596, 10788
7576, 10726
7594, 10732
7592, 10674
7583, 10621
7572, 10572
7552, 10526
7559, 10541
7555, 10495
7558, 10455
7557, 10418
7561, 10384
7547, 10349
7539, 10374
7560, 10341
7561, 10312
7567, 10286
7558, 10262
7558, 10237
7541, 10269
7549, 10243
7564, 10222
7543, 10199
7537, 10179
7522, 10213
7518, 10190
7531, 10170
7605, 10153
14074, 10402
14327, 14304
14326, 14324
14310, 14310
14295, 14302
14293, 14295
14295, 14288
14281, 14285
14262, 14273
14206, 14230
14161, 14160
14138, 14167
8625, 9013
8380, 8378
8243, 8266
8194, 8212
8159, 8163
8086, 8098
8086, 8092
8083, 8072
11679, 8448
14212, 14174
14273, 14281
14258, 14271
14237, 14243
14228, 14232
14224, 14225
14220, 14229
8940, 13727
8594, 13548
8489, 13468
8444, 13289
8424, 13120
8397, 12962
8350, 12813
8342, 12759
8333, 12621
8293, 12490
8284, 12369
8293, 12255
8247, 12149
8277, 12130
8260, 12035
8292, 11947
8285, 11868
12607, 11914
14165, 14096
14254, 14233
14248, 14253
14236, 14238
14228, 14230
14234, 14230
14211, 14227
8535, 10886
8261, 8295
8175, 8201
8101, 8119
8117, 8080
8070, 8096
8059, 8066
8015, 8041
7989, 8015
8006, 8016
8038, 8022
8064, 8042
8312, 8164
14011, 20100
14170, 14152
14204, 14199
14202, 14202
14192, 14199
14189, 14195
14183, 14186
13750, 14147
8305, 13929
8155, 13687
8021, 13450
7947, 13329
7931, 13106
7887, 12895
7880, 12701
7859, 12519
7853, 12444
7835, 12280
7833, 12129
7842, 11989
7812, 11859
7790, 11735
7772, 11698
7772, 11586
7764, 11482
7756, 11386
7753, 11297
7742, 11212
7736, 11202
7733, 11123
7741, 11050
7733, 10983
7738, 10921
7728, 10928
7726, 10870
7726, 10817
7722, 10768
7719, 10722
7713, 10679
7707, 10699
7715, 10659
7720, 10622
7716, 10587
7709, 10555
7717, 10525
7713, 10554
7719, 10525
7714, 10497
7708, 10473
7714, 10449
7707, 10484
7718, 10460
7714, 10438
7719, 10418
7724, 10398
7709, 10382
7702, 10420
7701, 10400
7715, 10383
7717, 10367
7710, 10351
7717, 10390
7711, 10374
7706, 10358
7717, 10343
7726, 10331
8966, 10350
14198, 14116
14409, 14369
14439, 14436
14437, 14432
14435, 14434
14432, 14434
14423, 14423
14433, 14428
14440, 14431
14432, 14434
14432, 14430
14426, 14431
14435, 14431
14434, 14431
14430, 14430
14429, 14425
14431, 14429
14429, 14431
14437, 14432

Darrel Taylor
- 13th September 2011, 02:17
Well, I think the purpose of averaging with the CSM module is a little different than the Running average routine was written for. But maybe with a couple changes ...

But first, a few other changes are in order.


Use the USART with HSEROUT for serial comms. It is unaffected by interrupts.
If you do disable Timer0 to do something else, make sure the Timers get reset, because they will still be counting during that period which could give bad values.
Stop Timer1 before trying to read the value so the lowbyte can't overflow in-between reading the 2-bytes.
There is no need to disable Timer0 interrupts in the interrupt handler. Hardware interrupts on 16F1's cannot be interrupted since the GIE bit is cleared by hardware.
Now back to the CSM.
The purpose of averaging the readings is to maintain a baseline of the frequency when it's not being touched. The reading will vary over time due to humidity and temperature.

When you "press" a button, your finger adds capacitance which lowers the frequency. So you can use the FASpread to detect that change, but you don't want to keep averaging or it will change the "baseline" reading.

If you set the FASpread much lower than you have it, I'd guess around 2000 (but try different values). Then change the FastAvg section to ...


; ...
Pressed = 0
GoTo AVGok
FastAvg:
IF Value < AVE THEN
Pressed = 1
ELSE
AVE = Value
ENDIF
GoTo AVGok
RealClose:
Pressed = 0
; ...

HankMcSpank
- 13th September 2011, 09:08
If you look at what I think will be you your proper baseline readings (i.e. once you've addressed a couple of those issues mentioned by Darrel)...



14409
14439
14437
14435
14432
14423
14433
14440
14432
14432
14426
14435
14434
14430
14429
14431


they're only varying by about 0.00x% per sample period (interrupt)...and when your finger is pressed on the sensor, you should see the value drop by at least 20% (probably 50% or more if your sensor is decent enough), so there's really no need for averaging.

Max Power
- 15th September 2011, 04:09
thank you so much for the insight. that got rid of the erratic readings. I was able to set a threshold, and not update the average during a button press, and also count the amount of time that the button is pressed. I'm pleased.

but I'm having trouble with the HSEROUT command - I feel so silly, I've never used it before. I saw that the tx pin is the same one as I was using before, so I was encouraged, but all I got in the PICKIT2 UART tool was '????????????????????' and jiberish

I put these two defines up top, I tried 20h and 24h, 9600 baud and 19200
DEFINE HSER_TXSTA 24h ' high speed (BRGH = 1)
DEFINE HSER_BAUD 19200 ' 19200 BAUD rate

and then I had these in my code
Hserout ["Hello World", 13, 10]
HSEROUT [DEC VALUE, ", ", DEC AVE, 13,10]

HankMcSpank
- 15th September 2011, 13:12
This is what gets me there on an 16f1828 @115,200 baud (16Mhz Osc)...



Osccon = %01111010 'sets the internal oscillator to 16Mhz
DEFINE OSC 16
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 34 ' 115200 Baud @ 16MHz, -0.79%
SPBRGH = 0
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
RCSTA.7 = 1 ' Enable RB7 for TX USART (not sure if this is needed - needs removing one day to see!)
TrisB.7 = 0 ' set pin 10 RB7 to be an output



MrE's picmulticalc utility helps a lot wrt setting defines for your required serial speed...

http://www.picbasic.co.uk/forum/showthread.php?t=4994&p=65639#post65639

your command usage looks fine - have you tried scoping the hserout pin?

Max Power
- 19th September 2011, 04:11
yes! I got it working. Thanks for pointing me to the pic multi calc program, what a life saver. I used it for figuring out my interrupt timing, but I didn't see that it also did EUSART settings. It didn't start working until I set the appropriate bit in the APFCON register.

Ioannis
- 19th September 2011, 10:37
I am thinking of using the Cap sensor idea on a project to be battery powered in the middle of the sea.

Considering that there are no 50/60Hz power lines, will this work?

Ioannis

HankMcSpank
- 19th September 2011, 11:59
Considering that there are no 50/60Hz power lines, will this work?


I don't know what you mean wrt power lines bit (grounding?), but I see no reason why it wouldn't work - as far as I recall cap touch works with batteries too. (though now having a little bit of doubt in that all my exploits where on breadboard & mains sourced power!)

Ioannis
- 19th September 2011, 13:13
Sorry for that. I got a little carried away, because I was exprimenting with another touch sensor, working with power line interference.

The Cap sensor is what it say, capacitor sensor, so it has nothing to do with power lines, noise etc.... Reading your reply, a bell was ringing in my brain, making me a little embarrased...

Ioannis