Searching \ for 'Resistance Measurement (AN512)' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=resistance+measurement
Search entire site for: 'Resistance Measurement (AN512)'.

Truncated match.
PICList Thread
'Resistance Measurement (AN512)'
1998\07\16@025736 by

flavicon
face
I have been trying to implement a PI temperature controller (No Differential
term, it wasn't considered necesary) using a 16C62.  Temperature measurment
is (supposed) to be performed via a thermistor using the single slope
integration method outlined in Microchips AN512 application note.
Temperature control is via the PWM output driving a peltier device.  The
conversion process is carried out under interupt driven from Timer1.

Now, the application note sets up TMR0 as a counter, using the RA4/T0CKI
input and charges a capacitor whilst looking for a change in the TMR0
register. Why?  The Schmitt trigger input on this pin seems to be just as
valid when used as a normal input pin.  It seems to be a lot of extra
complication if just configuring RA4 as an input would do the trick.  But,
this extra complexity is there for a reason I suspect.

I have had no end of problems with the counter not incrementing and the
software getting stuck in an endless loop, untill the watchdog kicks in.
This seems to happen very regularly, after a set number of sucessfull
conversions, usually about 3.  By varying the time constant of the ADC
components, this number could be made as small as 1 or as large as 10 or so.
Generally the larger the time contant, the more reliable the conversion was,
but it was never 100% reliable.

Well, I spent far too many erase/program cycles trying to find a way around
this, so I decided to just use RA4 as a normal input.  And it nearly works.
The conversion technique uses a "set point" resistor (actually part of a
Xicor e2pot) and thermistor driven from RA0 and RA1 respectively.  These
pins have the output latch set to 1 during initialisation, and the TRIS
registers are set or cleared to enable or disable charging, as per AN512.
This bit of the code worked fine while I was using TMR0, but now I'm reading
RA4 directly, RA0 refuses to go high when the TRIS register is set to 0 for
that pin.  RA1 still works correctly.  Could this be the infamous
read-modify-write problem?  If so how do I cure it?  The code is written
using Hitech C.

Thanks for any suggestions, comments, or just general abuse you could heap
in my direction :)

Mike Rigby-Jones
spam_OUTmrjonesTakeThisOuTspamnortel.co.uk

1998\07\16@095513 by lilel

flavicon
face
Michael wrote:


> I have been trying to implement a PI temperature controller (No
> Differential term, it wasn't considered necesary) using a 16C62.
> Temperature measurment is (supposed) to be performed via a
> thermistor using the single slope integration method outlined in
> Microchips AN512 application note.

I've used this technique successfully, and found out that the app
note 512 doesn't tell the entire story.

1.  You can't really use high impedance signals with this technique.
If your thermistor is 100K or less you will probably have the most
luck.  1 meg impedances are hard to measure.

2.  You need error checking/correction in your code.  I wrote mine in
such a way that if the software timed out at a ridiculously long
value before the TMR0 tripped, it would recover from the error,
discharge the capacitors, and try again.  Same with timing out too
fast.  Either condition is probably noise.

3.  This circuit is not very noise immune.  I ended up learning a
lot about software noise immunity techniques.

4.  The schmidt trtigger input IS there for a reason.  The schmidt
trigger input will trip at a more precise level than the other
inputs, and will give a better level of noise immunity.  You'll find
higher variation in trip level from part to part in the standard port
inputs.

5.  Consider some kind of software noise immunity.  The technique I
used was a median filter.  I would clear out a section of RAM, take a
measurement, sort it into the RAM array, take another measurement,
sort it into the array, until I had an array of 10 or 12 measurements
all in sorted order.  The middle one is the median, and that is the
result.

6. I will give you a couple of samples of code for the median filter,
if you promise to get a SINGLE measurement working first.  It sounds
to me like some kind of simple but oh-so-maddening hard to find bug
in the code.  In a couple of days I should have this up on my web
page, URL below.


-- Lawrence Lile

    "An Engineer is simply a machine for
     turning coffee into assembler code."

Download AutoCad blocks for electrical drafting at:
http://home1.gte.net/llile/index.htm

1998\07\17@022205 by Dr. Imre Bartfai

flavicon
face
part 0 17734 bytes content-type:TEXT/PLAIN; charset=US-ASCII; name="ohm2.src"here is my working application for your convenience.

It measures and sends the result to a DMM software. R is 10 kohm, C is 47
nF. Part of code is copyright of Scott (the PicBasic Book).

Cheers,
Imre


On Thu, 16 Jul 1998, Rigby-Jones, Michael [PAI01:4837:EXCH] wrote:

{Quote hidden}

Content-Type: TEXT/PLAIN; charset=US-ASCII; name="ohm2.src"
Content-ID: <Pine.LNX.3.96.980717081134.224CspamKILLspamprof.pmmf.hu>> Content-Description:

       DEVICE        PIC16C84,WDT_OFF,PWRT_ON,PROTECT_OFF,XT_OSC

;

;

       ORG        0Ch                ; GPR terulet kezdete

ACCA        DS        2

ACCB        DS        2

ACCC        DS        2

ACCD        DS        2

ACCE        DS        2

TCAL        DS        2

TEMP        DS        1

       

temp2        ds        1        ; Temporary counter for delay.

dec_no        ds        1        ; Decade (1,10,100...) to work on.

flags        ds        1

rcvd        ds        1        ; The received byte



buffer        =        2Fh        ; String storage at end of memory.



ASC_0        =        '0'     ; ASCII numbers: 30h thru 39h.

ASC_dp        =        '.'     ; ASCII char for decimal point (period).

fix        =        2        ; Position for fixed decimal point.



; baud        =        31        ; 2400 baud at 4MHz.

baud        =        63        ; 1200 baud at 4MHz.

; baud        =        127        ; 600 baud at 4MHz.

; baud        =        255        ; 300 baud at 4MHz.

bits        =        7



zs        =        flags.0 ; Leading-zero suppression flag.

ovff        =        flags.1        ; overcount flag

;

RCALMS        EQU     10000<            ;RCAL MSB VALUE IN HEX

RCALLS        EQU     10000>            ;RCAL LSB VALUE IN HEX



DSCHR        EQU        RA.0

RCAL        EQU        RA.1

RMEAS        EQU        RA.3

OVF        EQU        RB.3

RDY        EQU        RB.2

ERR        EQU        RB.0

out_pin =        RB.4        ; Serial output through this pin.

serial_in =        RB.5



             ORG        0                ; belepesi pont

             B        OHMS                ; foprogram

             ORG        4                ; dummy IT rutin

             RETFIE

;-------------

; MADD: ACCB := ACCB + ACCA

MADD        MOVFW        ACCA+1

             ADDWF        ACCB+1                ;ADD LSB

             SKPNC                        ;ADD IN CARRY

             INCF        ACCB

             MOVFW        ACCA

             ADDWF        ACCB                ;ADD MSB

             RETURN

;-------------

; MPY:  (ACCB,ACCC) := ACCB * ACCA

MPY            CALL    SETUP           ;RESULTS IN B(16 MSB'S) AND C(16 LSB'S)

MLOOP          RRF     ACCD            ;ROTATE D RIGHT

             RRF     ACCD+1

             SKPNC                   ;NEED TO ADD?

             CALL    MADD

             RRF     ACCB

             RRF     ACCB+1

             RRF     ACCC

             RRF     ACCC+1

             DECFSZ  TEMP                ;LOOP UNTIL ALL BITS CHECKED

             B            MLOOP

             RETURN

;-------------

; SETUP: TEMP := 16

;        ACCD := ACCB; ACCB := 0

;        ACCE := ACCC

SETUP          MOVLW   16

             MOVWF   TEMP

             MOVFW   ACCB                  ;MOVE B TO D

             MOVWF   ACCD

             MOVFW   ACCB+1

             MOVWF   ACCD+1

             MOVFW   ACCC

             MOVWF   ACCE

             MOVFW   ACCC+1

             MOVWF        ACCE+1

             CLRF        ACCB

             CLRF        ACCB+1

             RETURN

;-------------

; DIV:  ACCB := ACCB DIV ACCA

;        ACCC := ACCB MOD ACCA

DIV            CALL    SETUP

             MOVLW        32

             MOVWF        TEMP

             CLRF    ACCC

             CLRF    ACCC+1

DLOOP          CLRC

             RLF        ACCE+1

             RLF        ACCE

             RLF        ACCD+1

             RLF        ACCD

             RLF        ACCC+1

             RLF        ACCC

       MOVFW        ACCA

       SUBWF        ACCC,W          ;CHECK IF A>C

       SKPZ

       B        NOCHK

       MOVFW        ACCA+1

       SUBWF        ACCC+1,W        ;IF MSB EQUAL THEN CHECK LSB

NOCHK        SKPC                        ;CARRY SET IF C>A

       B            NOGO

       MOVFW        ACCA+1                ;C-A INTO C

       SUBWF        ACCC+1

             SKPC

       DECF        ACCC

             MOVFW   ACCA

       SUBWF        ACCC

       SETC                    ;SHIFT A 1 INTO B (RESULT)

NOGO        RLF        ACCB+1

             RLF        ACCB

       DECFSZ        TEMP                ;LOOP UNTIL ALL BITS CHECKED

       B        DLOOP

       RETURN

;=============

DSCHRG        BSF        RP0

       BCF        DSCHR                ; kisuto lab kimenetkent

       BCF        RP0

             BCF        DSCHR                ; alacsonyba

       MOVLW        10                ; msecs

             MOVWF        TEMP2                ; varakozo ciklus

:LOOP0        CLRF        TEMP

:LOOP          DECFSZ  TEMP

             B        :LOOP

       DECFSZ        TEMP2

       B        :LOOP0

             BSF        RP0                ; vissza inputra

             BSF        DSCHR

             BCF        RP0

             RETURN

;=============

;M_TIME: ACCA := Time of Load

M_TIME        CLRF        TMR0                ;CLEAR RTCC

       CLRF        ACCA+1

       CLRF        ACCA

TLOOP        INCFSZ        ACCA+1

       B        ENDCHK

       INCFSZ  ACCA

       B        ENDCHK

       B        END_M

ENDCHK        BTFSS        TMR0.0                ; CHECK FOR RTCC TRIP

       B        TLOOP

       CLRF        TMR0

       BCF        OVFF

       RETLW        0                ; normal return

END_M        CLRF        TMR0

       BSF        OVFF

       RETLW        1                ; overflow

;=============

; Main program

OHMS        BSF        RCAL                ; legyen magas, ha majd aktiv

       BSF        RMEAS

       MOVLW        00101000b        ;SELECT POSITIVE EDGE FOR RTCC

       OPTION

       MOVLW        11100000b        ; lower 4 bits & out_pin

       TRIS        RB

       MOVLW        00010011b        ; clear all LEDs

       MOVWF        RB



       CALL        DSCHRG                ;DISCHARGE CAPACITOR

       BSF        RP0

       BCF        RCAL                ; calibrate on

       BCF        RP0

       BSF        RCAL

       CALL        M_TIME                ; MEASURE TIME

       BSF        RP0

       BSF        RCAL

       BCF        RP0

       IORLW        0                ; overflow?

       BNZ        ERROR

       MOVFW        ACCA+1

       MOVWF        TCAL+1                ;STORE LSB

       MOVFW        ACCA

       MOVWF        TCAL                ;STORE MSB

       

AGN        BSF        RDY                ; machine ready

       

       CALL        GETCHAR                ; read a character

;        XORLW        'Z'                ; this is the challenge

;        BNZ        AGN                ; not recognized - try again

       BCF        RDY                ; turn LED off - communicate

               

MEAS        CALL        DSCHRG                ; DISCHARGE CAPACITOR

       BSF        RP0

       BCF        RMEAS

       BCF        RP0

       BSF        RMEAS

       CALL        M_TIME                ; MEASURE TIME

       BSF        RP0

       BSF        RMEAS

       BCF        RP0

       IORLW        0                ; overflow?

       BZ        GO



       BSF        OVF                ;signal overflow

       MOVLW        5                ;fill buffer with 9's

       MOVWF        BUFFER

       MOVWF        TEMP

       MOVLW        BUFFER-1

       MOVWF        FSR

       MOVLW        '9'

:LOOP        MOVWF        INDF

       DECF        FSR

       DECFSZ        TEMP

       B        :LOOP

       B        DONE



GO        BCF        OVF

       MOVLW        RCALLS                ;CALIBRATION LSB VALUE

       MOVWF        ACCB+1

       MOVLW        RCALMS                ;CALIBRATION MSB VALUE

       MOVWF        ACCB



       CALL        MPY                ;MULTIPLY ACCA(MEAS) * ACCB(RCAL)

       MOVFW        TCAL+1

       MOVWF        ACCA+1

       MOVFW        TCAL

       MOVWF        ACCA



       CALL        DIV                ;DIVIDE ACCB(MEAS * R) BY ACCA(TCAL)

       

       CLRF        BUFFER                ; Clear char count (item 0 in buf).

       MOVLW        4                ; length of prefix

       MOVWF        TEMP                ; into loop var.

       MOVLW        BUFFER-1        ; 1st of buffer

       MOVWF        FSR                ; pointer

:LOOP        MOVFW        TEMP                ; fetch string pointer

       CALL        PREFIX                ; fetch current char

       MOVWF        INDF                ; store it

       DECF        FSR                ; next char in buffer

       INCF        BUFFER                ; count length

       DECFSZ        TEMP                ; loop

       B        :LOOP

       

       CALL        BIN_ASC

DONE        CALL        APPEND

       CALL        SEROUT



       B        AGN



ERROR        BCF        ERR                ; signal error LED

       B        ERROR                ; endless loop

;----

PREFIX        ADDLW        -1

       ADDWF        PCL

       RETW        ' ','S','E','R'

;----

APPEND        MOVLW        7                ; length of string

       MOVWF        TEMP                ; mark it

       MOVLW        BUFFER-1        ; first pos. of buffer

       MOVWF        FSR                ; to pointer

       MOVFW        BUFFER                ; actual length

       SUBWF        FSR                ; correct

:LOOP        MOVFW        TEMP                ; fetch string pointer

       CALL        GETSTR                ; fetch current char

       MOVWF        INDF                ; store it

       DECF        FSR                ; next char in buffer

       INCF        BUFFER                ; count length

       DECFSZ        TEMP                ; loop

       B        :LOOP

       RETURN



GETSTR        ADDLW        -1

       ADDWF        PCL

       RETW        13,' ','m','h','o','k',' '

;                0  1   2   3   4   5



; SEROUT_# data   (Serout_2 merged with bin_asc to transmit data as

;                   numeric text strings.)



; Transmits serial data with a fixed output pin, baud rate, and polarity.

; Data bytes to be transmitted must be arranged in memory starting at the

; address "buffer-1" and working downward (e.g., 30,29,28...). The number of

; bytes to transmit must be stored at the address labeled "buffer." A companion

; routine, BIN_ASC, converts 16-bit numbers to this form, optionally adding a

; decimal point. See the listing for Serout ...(format # data).

; Serout uses the common data format of no parity, 8 data

; bits, 1 stop bit (N81).



; This routine differs from the Serout presented in the text in that you

; must set the baud rate and input pin through the equates below. They

; cannot be changed once the program is assembled. (The larger version

; can change pins, baud rate, and data polarity on the fly.) Removing

; the code necessary for runtime changes saves about 30 instruction

; words of space. If you only need to send single bytes at a time,

; check out SEROUT_3 on this disk.



; To set the baud rate, just remove the comment symbol (;) in front of

; the desired baud rate in the list below. Make sure that all of the

; other "baud" definitions begin with (;) so that the assembler will

; ignore them.



; Note that the baud rates are all calculated at 4 MHz. At other clock

; rates, they will be proportional. For example, at 8 MHz, the fastest

; baud rate will be 4800. At 1 MHz, the fastest will be 600.



; To change the output pin, just change the line "out_pin = " to the

; desired pin. Make sure that the pin is set up as an output before

; calling serout.



; To change the signalling polarity of serout, you must make one

; change in the body of the program. There are comments next to

; the appropriate lines. Use a comment symbol (;) to deactivate the

; version you don't want, and remove comment symbols from in front of

; the desired line. The routine is currently set up for "inverted"

; polarity, meaning that it will transmit data properly to a PC

; serial port without the need for a serial line-driver IC. Just

; connect out_pin to the PC com port's data-in line, and the PIC

; circuit ground to the PC com port signal ground.



; Device data and reset vector

; Lookup table used by bin_asc routine.

DECADE        ADDWF        PCL

       RETW        10000>,10000<

       RETW        1000>,1000<

       RETW        100,0

       RETW        10,0

       RETW        1,0



; This routine accepts a 16-bit number in hiB, lowB and converts it into

; a counted ASCII text string located at the address "buffer." The buffer

; grows downward in memory. The first (0th) item in buffer is the number

; of characters in the string. The routine destroys the contents of

; hiB, lowB. If this value is required elsewhere, make a copy.



BIN_ASC CLRF        FLAGS                ; Clear zs flag.

       CLRF        DEC_NO                ; Clear decade no.

       CLRF        TEMP                ; Char counter

       MOVLW        BUFFER-1        ; elso karakter poz.

       MOVWF        FSR                ; index pointer

       MOVFW        BUFFER                ; length

       SUBWF        FSR                ; set pointer

:LOOP        MOVFW        DEC_NO                ; Get 1st hex digit of decade no.

       CALL        DECADE                ; from the lookup table.

       MOVWF        ACCA+1

       INC        DEC_NO                ; Get 2nd digit of decade no.

       MOVFW        DEC_NO                ; from the table.

       CALL        DECADE

       MOVWF        ACCA

       CALL        D_POINT        ; Insert decimal point.

       CALL        SUB_IT                ; Divide ACCB by ACCA

       BTFSC        ZS                ; If zs = 0 AND digit = 0 then

       B        :NO_ZS

       MOVFW        INDF                ; returning answer in indirect.

       BZ        :NO_ZED        ; digit is a leading zero to be

:NO_ZS                                ;  ignored. Otherwise, it's either

       MOVLW        ASC_0                ; an included zero (as in 7501)

       ADDWF        INDF                ; or a non-zero digit.

       INCF        BUFFER                

       INCF        TEMP        

       DECF        FSR                ; Point to next memory location.

       SETB        ZS                ; First non-zero digit sets zs bit.

       

:NO_ZED INCF        DEC_NO                ; Next decade.

       MOVLW        8                ; If dec_no = 8, we're down to ones.

       XORWF        DEC_NO,W

       SKPZ

       B        :LOOP                ; Otherwise, do next decade.

       INCF        DEC_NO                ; Update decade number for d_point.

       CALL        D_POINT        ; Decimal point here?

       MOVFW        ACCB+1                ; Whatever's left belongs in ones.

       MOVWF        INDF

       MOVLW        ASC_0

       ADDWF        INDF                ; Add offset for conversion to ASCII.

       INCF        BUFFER                ; Add 1 to character count.

       INCF        TEMP

       MOVLW        5                ; max. of string

       SUBWF        TEMP,W                ; W := TEMP - 5

       SKPC                        ; if less: return

       RETURN

       SKPNZ                        ; if equal: return

       RETURN

       SUBWF        BUFFER                ; recover char. count

       RETURN



; This routine performs division by iterated subtraction. It is efficient

; in this application because the dividend and divisor keep getting smaller

; as BIN_ASC runs, so the quotient is never larger than nine. A general-

; purpose division routine would be slower (and longer).



SUB_IT        CLRF        INDF                ; Clear to track no. of subtractions.

:LOOP        MOVFW        ACCA+1                ; Subtract LSB

       SUBWF        ACCB+1

       BC        :SKIP                ; If no borrow, continue w/MSB.

       MOVLW        1

       SUBWF        ACCB                ; Otherwise borrow from MSB.

       BC        :SKIP                ; If borrow causes a carry, then

       INCF        ACCB                ; add numbers back and return.

       MOVFW        ACCA+1

       ADDWF        ACCB+1

       RETURN

:SKIP        MOVFW        ACCA                ; Subtract MSB.

       SUBWF        ACCB

       BC        :SKIP2                ; If no borrow, subtract again.

       MOVFW        ACCA+1                ; Otherwise, undo the subtraction

       ADDWF        ACCB+1

       SKPNC                        ; by adding entire 16-bit no.

       INCF        ACCB                ; back together and return.

       MOVFW        ACCA

       ADDWF        ACCB                

       RETURN

:SKIP2        INCF        INDF                ; No borrow, so do it again.

       B        :LOOP



; This routine adds a decimal point in the location set by "fix" in the

; equates at the beginning of the program. The location of the decimal point

; is in front of the "fix"ed digit, numbered starting with 0. If you fix the

; point at 0, the first (0th) character in the string produced by BIN_ASC

; will be a decimal point. If you don't want a decimal point, either move

; it out of range (fix = 6), or delete this routine and the "call d_point"

; in the body of BIN_ASC above.



D_POINT        MOVLW        FIX*2+1

       XORWF        DEC_NO,W

       SKPZ

       RETURN

       BSF        ZS

       MOVLW        ASC_DP

       MOVWF        INDF

       INCF        BUFFER

       DECF        FSR

       INCF        TEMP

       RETURN



; Subroutine used by Serout to send a bit and generate time delays.

EmitBit

       SKPNC                        ; skip if Carry

       BCF        OUT_PIN                ; otherwise clear pin

       SKPC

       BSF        OUT_PIN

B_Wait        

       MOVLW        BAUD

       MOVWF        TEMP2

:loop        B        $+1                ; Two-cycle nops for time delay.

       B        $+1

       B        $+1

       B        $+1

       B        $+1

       DECFSZ        TEMP2                ; Number of trips through loop

       B        :loop                ; Set by baud rate in temp2.

       RETURN



; A data string consisting of the number of bytes, followed by the

; bytes arranged downward in memory, must be at the location "buffer."

; Upon return, the data in the buffer will be unchanged, but the 0th entry

; (representing the string length) will have been decremented to 0.



Serout        MOVLW        BUFFER-1        ; Point to first data byte.

       MOVWF        FSR

:XMIT        CLRC                        ; Set up start bit.

       CALL        EmitBit        ; Send start bit.

       MOVLW        Bits                ; Send data bits.

       MOVWF        TEMP

:BITS        RRF        INDF                ; Rotate bit into carry.

       CALL        EmitBit        ; Send the data bit.

       DECFSZ        TEMP                ; All 8 bits sent?

       B        :BITS                ; No: send more bits.

       RRF        INDF                ; Rotate data back into original position.

       SETC                        ; Set up stop bit.

       CALL        EmitBit        ; Send the stop bit.

       SETC                        ; Set up stop bit.

       CALL        EmitBit        ; Send the stop bit.

       DECF        FSR                ; Point to next data byte.

       DECFSZ        BUFFER                ; All bytes sent?

       B        :XMIT                ; No: send more bytes.

       RETURN                        ; Yes: return.



; Taken from Parallax PIC Application Note: Receiving RS-232 Serial Data



; July 15, 1993



; This program receives a byte of serial data and displays it on eight LEDs

; connected to port rb. The receiving baud rate is determined by the value of

; the constant bit_K and the clock speed of the PIC. See the table in the

; application note (above) for values of bit_K. For example, with the clock

; running at 4 MHz and a desired receiving rate of 4800 baud, make bit_K 50.

; For 1200 Baud, use bit_K = 206



bit_K        =        baud/21*68        ;Change this value for desired baudrate



;--------

; GetChar: fetch a char from RxD into rcvd

;



GetChar

; now program waits for mark bit (low if inverted)

;

:strtbt        nop                        ; wait for start bit (SPACE signs +)

       btfss   serial_in       ; skip if high (normal input)

       b        :strtbt                ; otherwise wait for



       movlw        bit_K/2                ; init half-bit loop

       movwf        TEMP2                ; dctr = W

:loop        nop

       decfsz        TEMP2

       b        :loop



       btfss        serial_in       ; skip if high (normal input)

       b        :strtbt                ; only glitch



       movlw        bits                ; # of bits

       movwf        TEMP

       clrf        rcvd



Rcvr    call        B_wait

       bcf     c               ; copy /serial_in into carry

       btfss   serial_in       ; skip if input high

       bsf     c               ; otherwise set carry



       rrf     rcvd            ; rotate bit into LSB

       decfsz  TEMP            ; bctr--;

       b        Rcvr



       call        B_wait                ; wait for stop_bit



       movfw        rcvd                ; the Read byte

       return

;

;--------



       END

1998\07\19@062543 by White Horse Design

flavicon
face
At 08:11 17/07/98 +0200, you wrote:
>  This message is in MIME format.  The first part should be readable text,
>
>
>
>WARNING: The remainder of this message has not been transferred.
>The estimated size of this message is 33767 bytes.

I don't believe PIClisters will appreciate you posting this.

Regards

Adrian

WWW    WWW   Adrian Gothard
WWW WW WWW   White Horse Design
WWWWWWWWWW   +44-385-970009 (Mobile/SMS), +44-118-962-8913/4 (voice/fax)
WWWW  WWWW   .....whdKILLspamspam.....zetnet.co.uk, http://www.users.zetnet.co.uk/whd
---
Developers of GPS satellite-based tracking systems for vehicles/helicopters

1998\07\23@045324 by

flavicon
face
Lile, thanks for the info you sent.

> 1.  You can't really use high impedance signals with this technique.
>
Should be OK here, thermistor is around 10K.

> 2.  You need error checking/correction in your code
>
Trouble seems to be that adding extra code into the loop for error checking
slows the loop down and effectively cuts the resolution of the converter.

> 3.  This circuit is not very noise immune.  I ended up learning a
> lot about software noise immunity techniques.
>
Yes, I have discovered this the hard way.  I pointed an acusuing finger at
the guy who did the layout for our development board, and he turned around
and said "fix it in software" !  The worst thing is trying to use an
emulator.  The long ribbon cable effectively couples edges from all the
other port pins into the RA4 input and worsens the noise problems
considerably.  However, it still works and seems tobe far the best way to
debug (if you can afford it).

> 4.  The schmidt trtigger input IS there for a reason.  The schmidt
> trigger input will trip at a more precise level than the other
> inputs, and will give a better level of noise immunity.  You'll find
> higher variation in trip level from part to part in the standard port
> inputs.
>
I understood this, what I didn;t understand it why the port wasn't read
directly.  I've since learned that it was because of hardware differences in
the lower end 16C5X chips that were used in the App note.

I have since made the thing work pretty well just by reading the RA4 line.
It seems very reliable, but of course, there is noise present that needs to
be filtered.

> 5.  Consider some kind of software noise immunity.  The technique I
> used was a median filter.  I would clear out a section of RAM, take a
> measurement, sort it into the RAM array, take another measurement,
> sort it into the array, until I had an array of 10 or 12 measurements
> all in sorted order.  The middle one is the median, and that is the
> result.
>
If this better than just using a circular buffer and calculating the
average?

> 6. I will give you a couple of samples of code for the median filter,
> if you promise to get a SINGLE measurement working first.  It sounds
> to me like some kind of simple but oh-so-maddening hard to find bug
> in the code
>
Very maddening.  But mostly, due to not having used PICs before and not
knowing about their habits, like the read-modify-write hassles.  I think it
didn't help writing the code in C, it kinda separates you from the hardware
that bit more, although it's nice when it comes to do 16 and 24 bit math.

The CCP module is still giving me grief, even with the duty cycle set to
about 75% (as shown by the emulator) the output seems to latch high
sometimes.  I just know that this is going to be so obvious when I find it,
but a phrase about woods and trees springs to mind at the minute.

Mike Rigby-Jones
EraseMEmrjonesspam_OUTspamTakeThisOuTnortel.co.uk

1998\07\23@101137 by lilel

flavicon
face
Michael sez:

> > 5.  Consider some kind of software noise immunity.  The technique I
> > used was a median filter.  I would clear out a section of RAM, take a
> > measurement, sort it into the RAM array, take another measurement,
> > sort it into the array, until I had an array of 10 or 12 measurements
> > all in sorted order.  The middle one is the median, and that is the
> > result.
> >
> If this better than just using a circular buffer and calculating the
> average?

YES.  Consider the following data points:

1000
5
5
5
5
2

The average is 170, the median is 5.  Which is more representative of
the data?   I also found BIG problems with errors due to the lack of
floating point math.  Calculating an average always results in a
division.  In a simple PIC, without floating point math you introduce
tiny rounding errors that add up after a while.  I don't want to
belabor this extensively, because it was all hashed out here about
six months ago.   Once you have the basics worked out, median filters
are easy to code and they are very noise immune.

Since I haven't gotten around to posting it I'll email you some code
for median filters privately.




-- Lawrence Lile

    "An Engineer is simply a machine for
     turning coffee into assembler code."

Download AutoCad blocks for electrical drafting at:
http://home1.gte.net/llile/index.htm

1998\07\24@024922 by Dr. Imre Bartfai

flavicon
face
Hi,

to the point #5:

statistically, the median filter is far better than moving average. Why?
because of median is completely immune against outliers, but averaging
not. If you calculate average (which is far more simpler, than median) it
is a good practice to remove outliers. Look the following example:

3, 5, 4, 2, 4, 98, 3, 4

The average is: 15
The median is: 4

Of course, you can use the x-sigma rule: calculate the average and the
standard deviation, and say that the probability of a particular value
exceeds x +/- n * stddev is 32 pct for n=1, about 5 pct for n=2, and 0.3
pct for n=3 (Gaussian distribution assumed). So one can set up a flexible
limit to detect the outliers.

This is my two cent.

Imre


On Wed, 22 Jul 1998, Rigby-Jones, Michael [PAI01:4837:EXCH] wrote:

{Quote hidden}

More... (looser matching)
- Last day of these posts
- In 1998 , 1999 only
- Today
- New search...