Compensating TOUCH16 values due to supply voltage variance.

mortifyu

New Member
Hello. once more Guru's.

Having a good go effectively at moisture detection utilizing TOUCH16. It is appearing a little trickier than I had hoped.

I am looking at using TOUCH16 as a way in determining from DRY thru to SATURATED media, 100% non-contact through plastic. I 'think' I have the sensing component under control, however my current issue is operating my circuit from a battery. Varying the bench supply voltage changes my sensed values as one would expect.

With an 08M2, I am currently experimenting using a 100K pullup with a 1N4148 (cathode to GND) as a very low fixed external reference and then acquiring a value from this reference by a READADC10 (C.1) command and finally deducting this reference value from the TOUCH16 (C.4) value. As I am sure you would be aware, as the supply voltage drops, the ADC and TOUCH16 values go up and vice versa as the supply voltage increases.

I need to null out this varying factor as I would like to operate this particular sensing circuit from a CR2032 button cell.

This is a background project I have been working on/off since early May 2019. The test circuit has, since May, been and continues to run 24/7 on a CR2032. By using NAP 5 in my CODE loop, I can confirm at 12-12-2019, the CR2032 is still holding up quite well at 2.927VDC measured today at V+ (pin1) and GND (pin8) of the 08M2 with a FLUKE 79III whilst in it's ongoing operational state.

I am reasonably confident I am going the wrong way about trying to compensate the varying supply voltage in my CODE as it is bluntly not working as I had hoped. It has dramatically helped, but there is still variance when varying the supply voltage. To avoid confusion of what I have mentioned above, I have one circuit running on a CR2032 and another identical circuit I am working on with the bench supply. The circuit running on the battery does not currently have the 100K pullup & 1N4148 reference.

Further to note, I do know,understand and appreciate the 100K/1N4148 is NOT a precision reference and measurements do show this reference varying with supply variation. The question is, if I was to use a precision reference such as:


Will I null out this variance? And, am I going to the right way about compensation in my CODE?

For varying (pun intended :)) reasons I cannot disclose the ACTUAL program code, but here is some highly modified and extremely simplified code that expresses my dilemma.


Code:
init:
disablebod
setfreq m32

symbol onthreshold=24330
symbol offthreshold=24260



main:
readadc10 c.1,w4
touch16 [%00010001],c.4,w1

let w2=w1-w4

sertxd("Ref: ",#w4,", Sense: ",#w2,cr)

if w2>onthreshold then gosub wet

nap 5

goto main



wet:
high c.2

readadc10 c.1,w4
touch16 [%00010001],c.4,w1

let w2=w1-w4

sertxd("ON - Ref: ",#w4,", Sense: ",#w2,cr)

if w2<offthreshold then low c.2 return endif

goto wet
Another issue I have identified is that the values sensed are different from having the AXE027 programming cable plugged into the circuit or not. That too is a bit of an unhelpful bummer.

I am expecting you to talk of the FVR. I haven't really got my head around using the FVR. I had a play with it but found while varying the supply voltage, the FVR value always remained the same and that didn't make sense to me. Hence the 100K/1N4148 as reference.


Regards,
Mort.
 

lbenson

Senior Member
There are others with more expertise and experience who can perhaps explain it better, and give examples, but my understanding is the the fixed FVR value allows you to determine what percentage of your norm (say 3V for a CR2032) your actual voltage is, so you can then apply that percentage to reading you get from TOUCH16.
 

hippy

Technical Support
Staff member
I think you probably know more about the field than anyone in Rev-Ed and anyone here so I am not sure if there's much useful help to give on touch and compensation.

Touch was provided as a means of supporting low resolution 'finger present or not' projects without the expectation of it being used in higher resolution situations. Same too for FVR where changes with voltage often make little difference and any compensation or self-calibration can be rough and ready.

Reading the FVR with CALIBADC10 should have shown variation with supply voltage, and can be used to determine supply voltage from the reading. How absolutely accurate it is I'm not sure. It seemed 'pretty close' and 'good enough' when I tested it, varying a bench PSU and seeing what numbers it showed, but that doesn't mean it will be good enough for all situations.

I do recall there was some situation where two consecutive CALBADC10 reads proved more accurate than one. It was surmised that switching to the FVR was being affected by what was last read, the FVR not pulling the sample and hold cap fully to what it should have been with a single read.

I would guess a precision reference ought to give better results than the FVR or external diode circuit but have never tried that. A big challenge for anything requiring high resolution is retaining the desired resolution with the constraints of PICAXE 16-bit maths.

I would suggest the best way of handling things is in two parts, as you are probably doing; determining the voltage from the reference - or some representation of that - then determining the touch compensation from that value.
 

AllyCat

Senior Member
Hi,

Hmm, a touch of Deja Vue here. I've read all of #1 before and even drafted a reply, but it all seems to have "vanished" ?

Firstly, why use an external diode and resistor as a voltage "reference", when the CALIBADC10 command will do the same thing using the FVR1024, giving almost twice the resolution, more than 10 times better tempco, and no additional power drain ? Just an issue to beware of, if using the FVR for other purposes, is that CALIBADC doesn't always fully initialise and/or restore the FVR/ADC hardware when used repeatedly.

Secondly, I have to take issue with (at least) the first few lines of your program: Why disable the BOD , it risks major problems and consumes less current than that 100k resistor which you added? Also, "hard coding" the capacitive thresholds is never going to work reliably, and I believe running at 32 MHz may compromise the performance of the ADC.

Have you read section 27 (CaPacitive Sensing module) of the relevant base PIC data sheet (and perhaps sections 14/16 for the FVRs/ADC) ? The CPS oscillator has numerous operating modes for various frequency/current drains, but only some are "voltage insensitive". You may need to get your hands dirty with some PEEK/POKESFR commands to set up a suitable mode, or at least to determine which mode(s) Rev. Ed. are using.

Finally, water as a dielectric has highly complex characteristics (not the least that it's also a conductor) which may produce all kinds of unpredictable results. Reliable "Soil Wetness" sensors (for example) are an active market where the manufacturers appear to be very protective of the technology they use.

EDIT: Oh, and a 3v lithium cell should be quite a stable voltage anyway. Of course such a small cell will have a significant series resistance, so you may need to watch your current drain.

Cheers, Alan.
 
Last edited:

mortifyu

New Member
Hi,

Hmm, a touch of Deja Vue here. I've read all of #1 before and even drafted a reply, but it all seems to have "vanished" ?

Firstly, why use an external diode and resistor as a voltage "reference", when the CALIBADC10 command will do the same thing using the FVR1024, giving almost twice the resolution, more than 10 times better tempco, and no additional power drain ? Just an issue to beware of, if using the FVR for other purposes, is that CALIBADC doesn't always fully initialise and/or restore the FVR/ADC hardware when used repeatedly.

Secondly, I have to take issue with (at least) the first few lines of your program: Why disable the BOD , it risks major problems and consumes less current than that 100k resistor which you added? Also, "hard coding" the capacitive thresholds is never going to work reliably, and I believe running at 32 MHz may compromise the performance of the ADC.

Have you read section 27 (CaPacitive Sensing module) of the relevant base PIC data sheet (and perhaps sections 14/16 for the FVRs/ADC) ? The CPS oscillator has numerous operating modes for various frequency/current drains, but only some are "voltage insensitive". You may need to get your hands dirty with some PEEK/POKESFR commands to set up a suitable mode, or at least to determine which mode(s) Rev. Ed. are using.

Finally, water as a dielectric has highly complex characteristics (not the least that it's also a conductor) which may produce all kinds of unpredictable results. Reliable "Soil Wetness" sensors (for example) are an active market where the manufacturers appear to be very protective of the technology they use.

EDIT: Oh, and a 3v lithium cell should be quite a stable voltage anyway. Of course such a small cell will have a significant series resistance, so you may need to watch your current drain.

Cheers, Alan.
Hi Alan,

The calibadc10 sounds like what I may be looking for. I have used it in past times and will have a further play and see where I end up.

I don’t actually WANT to use an external reference if I can avoid it. Using a 100K and a dirty old 1N4148 was simply a view to seeing if this idea would be beneficial. If I have to go the way of external reference, the precision reference I provided a link to the Datasheet states it has a current draw of less than 6 micro-amps and would be what I’d use if needed. However if I can precisely benefit from calibadc10 it will be a great energy saver not to mention the precision reference is more expensive than the 08M2 itself.

May I ask, could you please possibly post some code utilising CALIBADC10 in this situation?

CALIBADC not fully initialising reliably... I would imagine this could resolved by continuously doing a RESET command.

Also, can anyone answer if I am doing the math right? ie TOUCH value - REF ADC value = supply voltage compensated TOUCH value.

From what I have read this far TOUCH is effectively working similarly to ADC.

I’ve not read section 27 etc. but will most certainly do so.

Thank you for you insights.

You too Hippy. ( Always a benefit you hear your views)


Also worth noting, with the hardware I have custom created (the capacitive sense component) it does appear to be quite stable and reliable. It is just that the stability goes right out the window without going to the trouble of compensating for the change in supply voltage.



Regards,
Mort.
 

mortifyu

New Member
Hmm, a touch of Deja Vue here. I've read all of #1 before and even drafted a reply, but it all seems to have "vanished" ?
Not vanished, I posted almost the same on the end of a 2011 thread recently, but didn’t get much response so thought it best to start a fresh thread around this dilemma.


Regards,
Mort.
 

AllyCat

Senior Member
Hi,

Basically CALIBADC10 works in the same way as your external reference (but without any extra hardware or configuration). It "measures" the value of a "reference" voltage (the 1.024 volt FVR) relative to the supply rail (which is currently "unknown"). You can then calculate the supply voltage by "inversion", i.e. dividing the reference voltage by the calibadc result (as a fraction of full-scale). I (and others) have posted several examples of this and alternative methods in the Code Snippets section of the forum. Yes, resetting the PICaxe before each measurement would be one way to ensure that calibadc is correctly initialised, but it's not difficult just to ensure that the FVR and/or ADC reference voltages are correctly set.

The "Capacitive Sensing Oscillator" is not intended to be a "precision" oscillator and you can't make a silk purse out of a pigs ear. ;) So you might do better to add a higher quality external oscillator (probably L-C type) rather than a reference voltage. Note that the CPS Module has a "noise" mode which basically disables the on-chip oscillator and could receive the signal from an external oscillator. The CPS module is basically just a (gated) counter, whilst the ADC performs a "binary search" to balance fractional voltages, so I wouldn't really consider them as "similar".

However, I've taken another look at section 27 of the data sheet to "remind" me of how it works. To me, the operational description seems quite confusing, apparently exchanging the meanings of "fixed" and "variable". As far as I can see, the "fixed" mode uses the supply rail as a reference (so the frequency varies with the supply rail) whilst the "variable" mode uses the FVR (Fixed Voltage Reference) so the frequency is independent of the supply rail !

Basically, the oscillator switches between a source and a sink "constant current generator" to alternately charge and discharge the capacitor. The currents are exchanged each time the capacitor voltage reaches the upper or lower threshold levels. If these currents are "constant" (i.e. independent of the supply voltage), then the threshold voltages would need to be "constant" (i.e. of fixed spacing) to give a constant frequency. If the levels change (i.e. separate when the supply increases) then it will take longer for the voltage to travel between the thresholds, and the frequency will fall.

IMHO, it's nearly always better to start with a "stable" configuration, rather than use "compensation" methods (that pigs ear again), but if you did want/need to compensate for changes in frequency due to voltage (or temperature, etc.) changing, then you should nearly always MULTIPLY (or divide) the intermediate results to give a "compensated" result..

Cheers, Alan.
 

johnlong

Senior Member
Hi
How are you determining the diffrence brtween saturated and dry of the medium
I would sugest that you take a dry sample of say 100g and fully saturate it to the point where it can not hold anymore water take a reading
weigh it then place the sample into the oven and bake it until all the moisture is removed weigh it and take a reading this will give you a baises
as to the ranges that you should expect to obtain and take it from there.
regards john
 

hippy

Technical Support
Staff member
Also, can anyone answer if I am doing the math right? ie TOUCH value - REF ADC value = supply voltage compensated TOUCH value.
I am not sure. "'compensated = ƒ(touch, voltage)" is probably a good stating point, and it might be possible to simplify that to "'compensated = touch - ƒ(voltage)" if it can be shown that the compensation required is purely a function of voltage across the entire range of touch values. There might then be a ƒ(voltage) == ƒ'(Vref) equivalence.

One would really need a whole array of touch values across a range of voltages and what result they should give to be able to determine how the compensation function should be.
 

rq3

Senior Member
Here is a some "auto-cal touch" code stripped from a much longer effort I wrote years ago. I'm not even sure what the intent was anymore, but the circuit had four touch switches fabricated from a printed circuit board, under a 1/16 inch thick cover glass.

There was a bunch of other stuff in the code, but I think this is the salient feature. When the code starts, it immediately reads the touch switches, and stores their value. Any finger on a switch forces a comparison of the result with the stored result, and a new storage of a new calibration. I'm sure I screwed up the "max" and "min" statements, but the main point is that the entire circuit could go from freezer to oven, and work reliably, even covered with ice or hot condensed water.

The T-sense and Test: pause items were critical. Tweaking these adjusted the repeatable sensitivity from a hand wave 6 inches from the sensors all the way to requiring a firm, wet thumb to get a response. And it was stable and repeatable. Hope this helps, at least as food for thought.

Code:
#PICAXE 20M2                                                                                    ;Picaxe type directive
#no_data                                                                                            ;no EEPROM
#no_end                                                                                            ;do not auto-append "End"
;disconnect                                                                                        ;no download scan - requires hard reset
disabletime                                                                                        ;turn off timer (s_w7)
setfreq M32                                                                                        ;clock 32 MHz
dirsC=%11111101                                                                                ;make C.1 glideslope input
pullup %0100000000000000                                                                    ;pullup spare input C.6
bptr=40                                                                                            ;OLED display brightness register
@bptr=16                                                                                            ;pre-load OLED display brightness (1-16)
sertxd ("REV:9.0-DATE:090917",13,10)                                                    ;display revision and date to terminal


symbol T_Sense=30                                                                   ;touch switch sensitivity (higher=more sensitive)


touch_cal:                                                                                        ;initialize touch switch calibration
    gosub cal    
                                                                                    
test:                                                                                                ;detect switch condition                        
    outpinsC=%00001000                                                                 ;disable stepper driver
        do                                                                                         ;menu select and calibration loop
            gosub finger
                gosub cal
                    pause 800                                                                    ;modify for response time 
                    if Touch_Flag=6 then glideslope                                                                    
        loop until Touch_Flag=5
        

finger:                                                                                            ;touch_switch detection
    touch16 [%11110001],B.0,Switch_1
        peek 28,word w1
    touch16 [%11110001],B.1,Switch_2
        peek 30,word w2
    touch16 [%11110001],B.2,Switch_3
        peek 32,word w3
    touch16 [%11110001],B.3,Switch_4
        peek 34,word w13
    
    if Switch_1<w1 and Switch_2<w2 and Switch_3<w3 and Switch_4<w13 then return
        endif    
        
cal:
    touch16 [%11110001],B.0,w1                                                                ;read touch switch
        w2=w1/T_Sense                                                                            ;divide value by sensitivity constant
            w3 = 65535 - w1 max w2+w1 min 1                                                ;sum the results and prevent over,underflow
                poke 28,word w3                                                                ;store baseline touch value

    touch16 [%11110001],B.1,w1
        w2=w1/T_Sense
            w3 = 65535 - w1 max w2+w1 min 1
                poke 30,word w3

    touch16 [%11110001],B.2,w1
        w2=w1/T_Sense
            w3 = 65535 - w1 max w2+w1 min 1
                poke 32,word w3

    touch16 [%11110001],B.3,w1
        w2=w1/T_Sense
            w3 = 65535 - w1 max w2+w1 min 1
                poke 34,word w3
                    return
 
Top