DT averaging of interrupt driven cap sensor


Closed Thread
Results 1 to 9 of 9
  1. #1
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37

    Default DT averaging of interrupt driven cap sensor

    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.

    Code:
    							'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
    Code:
    							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

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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 ...
    Code:
    ; ...
    Pressed = 0
    GoTo AVGok
    FastAvg:
    IF Value < AVE THEN 
     Pressed = 1
    ELSE
     AVE = Value
    ENDIF
    GoTo AVGok
    RealClose:
    Pressed = 0
    ; ...
    DT

  3. #3
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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)...

    Code:
    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.

  4. #4
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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]

  5. #5
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    This is what gets me there on an 16f1828 @115,200 baud (16Mhz Osc)...

    Code:
    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/show...5639#post65639

    your command usage looks fine - have you tried scoping the hserout pin?
    Last edited by HankMcSpank; - 15th September 2011 at 13:15.

  6. #6
    Join Date
    Jun 2008
    Location
    Milwaukee, WI
    Posts
    37


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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.

  7. #7
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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

  8. #8
    Join Date
    Mar 2009
    Posts
    653


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    Quote Originally Posted by Ioannis View Post
    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!)

  9. #9
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,807


    Did you find this post helpful? Yes | No

    Default Re: DT averaging of interrupt driven cap sensor

    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

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts