Drifting resistances

Steve2381

Senior Member
Hey all
I have an 8x key keypad that is connected to a 40x2. Because I don't have enough pins, its been set up with button 1 as a short to 5v, and then varying resistances over the other 7 buttons to give me a reading on an ADC input (0-1024).
I worked out the values, set a slight 'window' either side of the target value and all was well.

However, I switched it on tonight and its all gone sideways, none of the readings are correct. Could the temperature of my workshop affect the resistances that much?
It was snowing when I did the programming over the weekend (and very cold in the garage), but the only difference I can think of is that its warmed up now.

I have written a short 'calibration' routine to store the returned button values in EEPROM, but I don't want to constantly re-calibrate as the weather changes.

If it is that, maybe I could add a reference resistor? I am surprised its drifted that much (if that is what it is).

Don't have the code to hand, so can't post it.... but its not a code problem anyway.
 

pxgator

Senior Member
I have written a short 'calibration' routine to store the returned button values in EEPROM, but I don't want to constantly re-calibrate as the weather changes.

If it is that, maybe I could add a reference resistor? I am surprised its drifted that much (if that is what it is).

Don't have the code to hand, so can't post it.... but its not a code problem anyway.

Not a code problem?? Well maybe and maybe not. Sometimes seemingly solid code can bite you back.
Perhaps you're calibration routine needs a bit wider windows? It will be very difficult for folks on this forum to
help you if you do not post a schematic with code. If you can do this I'll be anxious to hear what Hippy, AllyCat,
Premelec, Phil Hornby, etc., etc. has to say...:)

Cheers to All

P.S. If you want some answers much more information is needed.
 
Last edited:

hippy

Technical Support
Staff member
In my experience consistency is the biggest problem for ADC keypads. As you have "set a slight 'window' either side of the target value" you may need to change that so your detection routine uses a value mid-point between consecutive buttons to maximise detection.

Selecting resistor values to maximise the gaps between buttons can be quite difficult. Minimising the number of resistors in the chain will help. The ADC keypad matrix technique is probably a good guide to follow.

Perhaps post your button input part of your circuit and people will be able to assess that.
 

BESQUEUT

Senior Member
Could the temperature of my workshop affect the resistances that much?
Don't have the code to hand, so can't post it.... but its not a code problem anyway.
From that blog :
Cermetic: 0 ±100 PPM/°C
Metal film: 0±50PPM/°C, 0±25PPM/°C, 0±10PPM/°C orlower
Precision wire wound: 0±20PPM/°C, 0±10°C, 0±5PPM/°C or lower
Power resistors: +350PPM/°C

These are just a few examples, resistors can be found with TCRs of up to 6,000PPM/°C depending on the alloy.

I you want some help, we need your code, your schematic and values readed for each touch.
 

oracacle

Senior Member
Don't have the code to hand, so can't post it.... but its not a code problem anyway.
I bet there are number of use that have spent hours looking at hardware trying to figure out the problem because it wasn't a code problem only to find that is was actually a code problem that for some reason had been over looked for whatever reason.
 

techElder

Well-known member
That was me just the other day. My project developed a standing high bit that just had to be a small cheap Chinese switch. Turned out (after spending too much time) to be the difference between four bytes counted with FOR/NEXT 0 to 4 versus 0 to 3.
 

PhilHornby

Senior Member
I just spent two days wondering why several DS18B20's had suddenly started reading 'high' - which turned out to be an accidentally deleted line of code. Leaving a HC-12 permanently powered-on was slowly raising the internal temperature, which the DS18B20 successfully measured :rolleyes:
 

Steve2381

Senior Member
OK. I will have to lift the code off my workshop laptop tomorrow.
But... it does drift. Only by a slight amount, but its enough. I tried warming the pcb with a heat gun on low and watched the results.
I have got around the issue at the moment by using the spare contacts on a relay I have that operates briefly during the boot sequence. I wired it to short the middle resistance push button and then the Picaxe stores that result.
Then I can work out the slight drift from that figure. Seems to have cured it for now.
Ideally, I would not be using a single ADC input for a keypad, but I am out of inputs.
 

AllyCat

Senior Member
Hi,

varying resistances over the other 7 buttons to give me a reading on an ADC input (0-1024).
I worked out the values, set a slight 'window' either side of the target value
1024 possible ADC input levels and 8 buttons would permit a "guard band" (window) of 63 levels each side of the nominal values, which should be more than enough.

To me, it seems like a design error in the software or hardware (my guess is the hardware) but you've not given us any details of the circuit configuration or resistor values. :confused:

Cheers, Alan.
 

premelec

Senior Member
often it's the contact resistance of the keypad that's trouble - the resistances should be way higher than this expected maximum contact resistance... Also are you using the SAME voltage on the keypad resistors as the PICAXE? It's ratiometric unless you are changing to other configurations and accurate voltages...
 

Steve2381

Senior Member
Its using the same supply that feeds the Picaxe. I can't remember the resistor values off the top of my head.... but I did set them to be a decent distance apart and tested them with a simply read routine.
I am also suspecting my power supply now... I am wondering if its suffering noise that I am not seeing on my multimeter.
Just got in after 8 hour drive.... too tired to fire up the workshop tonight. Will investigate tomorrow I think. Thanks all
 

bfgstew

Senior Member
1 wire keypads are notoriously difficult to get the resistance between each button press in a good linear spread, therefore difficult to interpret in ADC.
I have done some work on the resistance values and have come up with the following. It works perfectly in simulation, not had time to put it into a hardware unit but you are more than welcome to use the info. In simulation it gives a perfect 0.3v step between each key. You must use 1% value resistors to maintain the 0.3v.
Screenshot_20180309-191149.png
 

PhilHornby

Senior Member
One thing you haven't mentioned, is if the actual voltage presented to the Picaxe is changing with temperature. (Your Picaxe Basic code says it has ... but does a multimeter confirm it?).

I was wondering if it was the Picaxe's ADC function that was varying with temperature, rather than the output from the keypad's resistors...
 

Steve2381

Senior Member
OK. Finally got time tonight for a fiddle with this circuit. Resistors certainly are drifting with temp, but I also believe its a PSU issue (see my other thread). I think the 5v supply is less than clean and that is also contributing to the problem.
Having said that, its self calibration routine I added has cured the problem.
Multimeter is showing an 0.2v variation on the supply at any one time.
 

premelec

Senior Member
Glad you've got it fixed... note that with digital multimeter variation in voltage is not necessarily accurately portrayed other than to show it's existence... sometimes more information can be had by switching to AC and see what the AC voltage [i.e. variation in DC] component reads... Metal film resistors should not drift much. I'd be interested in your "self calibration routine" code it you care to publish here... I've always either used a spread sheet or straight empiricism and manual value insert for real world redings...
 

bfgstew

Senior Member
I have finally gotten round to hacking my 4 x 3 keypad. And the initial results are better than expected. Key 1 gives 1.02v and key # gives 4.5v. Measuring the rest of the keys give a good linear spread of 0.3v to 0.4v between each key. ADC values average out at 16 between each key.
Now to write some nifty coding, which, to me, is the hard part. Would be nice to be able to write alpha/numerically to an OLED/LED. Maybe even add an 08M2+ to the keypad so it has its own driver and not 'clog up' the main controller, like the OLED driver?
As I said coding is not my strong point, so any help would be appreciated.

Cheers guys.

Stewart
 

hippy

Technical Support
Staff member
Would be nice to be able to write alpha/numerically to an OLED/LED.
Using SERTXD and viewing the data on the Terminal is the best way to debug things. We've seen a number of people try and use LCD displays, get something wrong, and then get bogged down in why the numbers are wrong or the hardware is faulty when the numbers and everything are perfectly fine but the displaying routines aren't.

Develop your code as if the PICAXE used were just a keyboard driver. Get that working reliably before anything else with it.
 

inglewoodpete

Senior Member
I have finally gotten round to hacking my 4 x 3 keypad. And the initial results are better than expected. Key 1 gives 1.02v and key # gives 4.5v. Measuring the rest of the keys give a good linear spread of 0.3v to 0.4v between each key. ADC values average out at 16 between each key.
Now to write some nifty coding, which, to me, is the hard part. Would be nice to be able to write alpha/numerically to an OLED/LED. Maybe even add an 08M2+ to the keypad so it has its own driver and not 'clog up' the main controller, like the OLED driver?
As I said coding is not my strong point, so any help would be appreciated.

Cheers guys.

Stewart
The following code is from a keypad-based program I wrote a few years ago. My project used a smaller keypad of 5 keys (East/West/North/South/Select). The code reads the ADC value but does not make the value available for use until the key is released. This overcomes the problem of repeated detections of (and actions from) the same keypress.

The analogue values used in the Select Case code block to discriminate between the various keys were selected to be halfway between each actual keypress value. Of course, you will need to expand the Case structure and adjust the ADC lookup values to suit your keyboard and resistors. Note that the ADC values should be arranged as an increasing sequence in the Case statements.

I hope this code gives you something to build on.
Rich (BB code):
' **** Pins **** Prefix i: Input; o: output
'                             Leg
Symbol iKPad      = 0         ' 2 A.0 S.A0 ADC0
'
' **** Registers **** Prefix t: biT Pointer; b: Byte; w: Word
'
' Keystroke validation/usage status bits
Symbol tKeyDown      = bit4   'Key identified was still held at last read
'
Symbol bAlogKeyVal   = b52    'w26    Value from ADC (Used briefly in Interrupt routine)
Symbol bKeyVal       = b55    'w27    Used to resolve key press
'
' **** RAM Allocation - Note that bytes 0 to 55 are used for byte registers b0 to b55 *****
'               Prefix r: RAM Pointer
'
Symbol rPreviousKeyVal  = 60  '60 Stored value of ADC of last detected key press
'
' **** Constants **** Prefix c: Constant
'
'      Misc Constants
Symbol False            = 0
Symbol True             = 1
'      ADC cut off points for Key recognition
Symbol cKValR_U         = 16        ' Right<n;     Up>n
Symbol cKValU_D         = 55        '    Up<n;   Down>n
Symbol cKValD_L         = 100       '  Down<n;   Left>n
Symbol cKValL_S         = 150       '  Left<n; Select>n
Symbol cKValS_N         = 210       'Select<n;  NoKey>n
Symbol cLVNoKey         = 255       'Indicates no keypress is detected
'      Keypad Constants - Keystroke Values
Symbol cNoKey           = 0         'Identity of keys
Symbol cKeyRight        = 1
Symbol cKeyUp           = 2
Symbol cKeyLeft         = 3
Symbol cKeyDown         = 4
Symbol cKeySelect       = 5
'   
'... other code....
'
'**** Routine to read and resolve the keypress value.
'  The Key press's ADC is recorded but not resolved until the key is released.
'
   ReadADC iKPad, bAlogKeyVal             'Pin S.A0  ADC0
   If bAlogKeyVal > cKValS_N Then         'No key currently pressed
      tKeyDown = False
      Peek rPreviousKeyVal, bAlogKeyVal   'Check previous ADC value
      Select Case bAlogKeyVal             'Resolve key identity from previous ADC value
       Case < cKValR_U: bKeyVal = cKeyRight
       Case < cKValU_D: bKeyVal = cKeyUp
       Case < cKValD_L: bKeyVal = cKeyDown
       Case < cKValL_S: bKeyVal = cKeyLeft
       Case < cKValS_N: bKeyVal = cKeySelect
       Else: bKeyVal = cNoKey
      EndSelect
   Else
      tKeyDown = True
      Poke rPreviousKeyVal, bAlogKeyVal
   EndIf
'
'... other code....
   
 

Aries

New Member
For what it may be worth, I have had a couple of instances where ADC buttons seemed to be drifting off. Sometimes switching off and on solved the problem for a short time. It turned out in the end that there was a dodgy solder connection which meant that the effective resistance sometimes changed (could be temperature, or movement or vibration). Re-soldering and checking the joints with a meter seems to have cured the problem.
 

bfgstew

Senior Member
Further testing and tweaking has improved results giving a near perfect spread of 0.385v across each key press (need to modify keypad again before next physical trial). Coding has come to,

main:
serout C.0,N2400,(254,1)
pause 50

keypad:
do
readadc 4, b0 ; reads adc value into b0
let b1 = b0 × 10/196 ; converts adc to key no
loop until b0 > 15 ; loop until adc sees press

screen:
serout C.0,N2400,(254,128,#b1)
pause 1000

I will post a new thread to show how to modify 4 x 3 keypad to get a 1 wire output.
 

bfgstew

Senior Member
I would presume a number not wanted.
This is still in its infancy and the code posted above was just to see if the keypad worked, which it does. The code will need further work to iron glitches and bugs out, like multiple key presses.
 
Top