M2 chips: Can Serial Out pin be overridden to become a DAC input?

kranenborg

Senior Member
M2 chips: Can Serial Out pin be overridden to become a DAC Vref- input?

Hello,

The M2 series has a large number of very useful modules (comparators, Data Signal Modulator, etc.) which, although not directly supported by Basic commands like on the X2 series (I presume because the M2 series have less memory than the X2 series to contain the Basic Interpreter and thus the supported set of Basic commands must be smaller), nevertheless can be made fully accessible through appropriate POKESFR commands (see for example my contribution regarding the use of the on-chip comparators: http://www.picaxeforum.co.uk/showthread.php?17654-Use-of-Comparators-in-the-PICAXE-18M2 ). Hippy has done something similar with the DSM.

One module that has my particular interest (and in principle supported by the DACSETUP command) is the DAC module. With reference to the corresponding Microchip datasheets it becomes clear that principally the on-chip DAC module should allow to have both the Vref- and Vref+ as external inputs (not for the 8-pin device, but indeed for the 14, 18 and 20 pin versions, and the 14M2 is exactly what I need). However the DACSETUP and ADCSETUP command descriptions in the Picaxe manual state that you cannot have both Vref+ and Vref- available at the same time for any of the M2 chips. Some further study of the mapping of the Picaxe functions on the PIC chips shows why: the Serial Out pin is always mapped on either Vref+ or Vref-. This means that this pin is always considered an output and the Programming Editor consequently blocks any INPUT command on these pins.

However I have not given up hope yet: a LET DIRSB = %00000000 command for a 14M2 application is accepted by the PE (implying the Serial Output pin B0 would be an input if executed accordingly). My questions then are: 1: would indeed this command override the Serial Output and make it an input pin (in casu an analog Vref- input) and 2: do I need to execute a DISCONNECT command as well?

Thanks, Jurjen
http://www.kranenborg.org/electronics
 
Last edited:

nick12ab

Senior Member
However I have not given up hope yet: a LET DIRSB = %00000000 command for a 14M2 application is accepted by the PE (implying the Serial Output pin B0 would be an input if executed accordingly). My questions then are: 1) would indeed this command override the Serial Output and make it an input pin - in casu an analog Vref- input
I've said on the forum before that I've previously used the Serial Out pin as an input but Hippy stated that the interpreter fixes the pin as an output so I was just forcing the pin high/low which is potentially damaging. I can't find the thread at the moment.
 

hippy

Senior Member
Using "Dirs=" won't set Serial Out as an input as the value used is OR'd and AND'd to ensure the fixed inputs and outputs remain as such.

When firmware forces an input or output the only way to override it is internal hardware which disconnects the pin - This is what happens when the DAC and DSM are enabled on an 08M2 and override Output 0.

Some internal hardware can override the normal I/O pin usage as above, other internal hardware simply connects additional modules to the pins and requires the user/firmware to set I/O as input, output or ADC as appropriate. The later is usually the case for Vref+/-, the pins become Vref inputs but the pins needs to be set as input ( ideally ADC ) and, if Serial Out, that can't be achieved with a PICAXE.

On the 14M2/20M2 there's an additional problem, if wanting to use the actual DAC analogue output rather than use DAC for ADC referencing, and that is the DACOUT signal is the same pin as Vref-.

My 14M2/20M2 PICmicro datasheet in the ADC section block diagram shows Vref+ as AN1, Vref- as AN2, but that does seem contradictory to other information elsewhere and appears to be wrong.
 

kranenborg

Senior Member
Hello Hippy,

Thanks for your answer, this seems to rule out the solution that I had in mind initially. Not a catastrophy though, for in my application I can alternatively use the comparator in a 08M2 (instead of a 14M2) and use a 6-pin Maxim FleaPot (I have an adapter board) instead, this would lead to almost the same footprint on the circuit board. A pity though that the full functionality of the DAC inputs (Vref+ and Vref-) somehow cannot be made available in the M2 series. At the same time I admit that this application is far beyond what one would consider to be relevant to the main educational audience that is targeted by the Picaxe architecture.

I also recognize the many documentation issues and contradictions in the Microchip PIC datasheet info.

By the way, this application is for a successor to the PongSat-18X (NLSE-1) near-space satellite that my eldest son and I built and have flown successfully in 2008, we are currently preparing for a new launch in September where we want to try to measure an increase in cosmic radiation with height using a similar approach as described be the Maxim app note 2236 were the following circuit is presented : http://www.maxim-ic.com/images/appnotes/2236/2236Fig01.gif (Here the comparator IC3 can be replaced by a Picaxe M2 comparator, and I hoped for 10K potmeter functionality to be arranged by the DAC as well in order to have a fully programmable noise canceler without any additional components required ...). We will report shortly on our progress.

Best regards,
Jurjen
 
Last edited:

hippy

Senior Member
I think I understand; you want to generate DACOUT, feed that back in to a comparator ?

That could/should work. Enabling the DAC makes output pin 0 an analogue output ( disconnects the digital Output 0 / Serial Out ) so DAC -> pin -> comparator input.

But ... one of the comparators input can be DACOUT even without DACOUT overriding Output 0 / Serial Out. It may be the wrong comparator input but the comparator can be inverted which achieves the same as swapping the inputs.

It might be worth drawing a block diagram of what you want as it may well be possible.
 

kranenborg

Senior Member
Hello Hippy,

I have included the diagram in this post. The issue is with Leg 13 which is Serial Out but should become Vref- (i.e. the lower input for the DAC). Now this pin is also DACOUT, but maybe it all works if 1) like you said enabling the DAC "removes" the Serial Out functionality from this pin and then 2) setting DACOE = 0 in the DACCON0 register disables the DAC output to be routed to this pin, making it effectively the Vref- pin (the datasheet is not very clear here but it should work like that for selecting between DACOUT and Vref-). What do you think? I will try to test this with a simple circuit setup as well

/Jurjen
 

Attachments

hippy

Senior Member
Thanks for the diagram. I believe the DAC may be more complicated than being a digital pot so the 150K to 0V may not work as expected, and, as you need Serial Out to be Vref- input, it's back to Serial Out being an output which stops this idea being implementable. If Vref- can be 0V it can probably be done but not otherwise.
 

kranenborg

Senior Member
It is time then for some testing. You are probably right (and Vref- at GND can be programmed but does not work for this application) but if a POKESFR command does not more than just setting the register bits (and does not include additional lower level commands to restate inputs & outputs) then it still might work (is it possible to say something about how POKESFR works on the machine level?)

Thanks,
Jurjen
 

hippy

Senior Member
POKESFR converts the location specified to an actual SFR address, then puts the byte value into the register at that SFR address, so it does update the SFR as expected.

You can set the TRIS registers this way, actually make the Serial Out pin an input, but it will only last for a few microseconds as the firmware does repeatedly update the TRIS and other registers to ensure the fixed output pins are outputs and fixed inputs are inputs. It's a bit like fly posting with an enforcement officer always on the lookout; as soon as the poster goes up it is torn down.

The only way I can see to achieve what is wanted is enabling some internal hardware that disconnects Output 0 from the pin and leaves that pin an input and I cannot find anything which would do that.
 

kranenborg

Senior Member
Yes, that settles it then most probably.

I have two options then:
1. Use an external pot (the six-pin FleaPot in a SOT23 package that I referred to earlier). That will work as well since a 08M2 will suffice then
2. Shift the reference voltage output level of the latest opamp before the comparator (IC2b in the maxim circuit above) from the reference level as defined by the voltage divider towards 0V instead (such that Vref- can be 0V instead of the reference level), but I do not see an easy way to do that without an extra opamp (from the opamp theory I get it that a single-opamp difference amplifier does not have the required characteristics)

I will pick option 1 unless someone has a good argument for option 2
Thanks for all your help
/Jurjen
 

hippy

Senior Member
Rather than implement as you envisage currently; is there some other way that what you need can be achieved which is actually implementable ? That is, approach it from the perspective of what inputs you have and what you want to achieve. Could you even do some of what you want purely in software ?
 

kranenborg

Senior Member
Indeed, with a small change in the analog part (the amplifier stage IC2b just before the comparator) it can be done I think: Just shifting the reference DC output voltage of that stage to a lower one (to be experimentally defined, something like 0.5V, sufficiently high to be able to discriminate between noise and the signal, sufficiently low to secure small-enough DAC voltage steps) I think the Picaxe DAC can be perfectly used with Vref- internally connected to GND:

Dacdiscussion2.JPG

The comparator output can then be routed to the interrupt logic. I have to see whether I can implement an SETINTFLAGS-like M2 implementation or otherwise route the comparator output externally to an input pin with a SETINT interrupt (or alternatively even to the gate of Timer1 to count the spikes automatically although that precludes the use of the neat Time variable on the M2)

Some further research to be done, but it seems all well possible right now
/Jurjen

PS: maybe good to clarify the goal of this circuit: I want to determine the photon-related number of spikes/second (above noise level, so therefore this circuit as a programmable noise canceler)
 
Last edited:

kranenborg

Senior Member
Hello,

Some investigations by my son and me seem to indicate that it should be possible on M2 chips to detect very fast spikes (above a certain noise level) using an interrupt (faster that the polled interrupt system generally can catch, and possibly equally fast as the hardware X2 interrupts). The following is a principal scheme of the setup that we tested (on a 08M2 , but also feasible on a 14M2, but not 18M2):

SpikeDetector.jpg

The DAC-comparator combination acts as a programmable noise canceler (Vref_DAC should be somewhat larger than the maximum expected noise amplitude), subsequently the SR-Latch acts as a memory bit to store the occurence of the fast event. This then can be discovered by the polled interrupt routine (SETINT only checks for interrupt conditions in between BASIC commands, it appears not to latch any interrupt conditions during command execution), which then uses the SRRESET command to reset the latch (and thereby remove the interrupt condition). The interrupt routine should of course only perform very basic and fast operations in order to allow the next event to be detected.

The documented code that we have used follows later, but it is nice to see that by using some of the chip's internal modules it seems to be possible to overcome the speed limitation of the PICAXE polled interrupt concept as well as implement the programmable noise canceler, all without any extra components. Only the comparator needs to be configured using POKESFR operations, both the DAC and the latch can be configured using supporting BASIC commands only (even though formally the M2 version of the SRLATCH command does not support the comparator set option)

Best regards,
Jurjen & Joost
 
Last edited:

kranenborg

Senior Member
The following code for a simple test setup (described in the code as well) shows how fast events (in this case generated by a button press) can be counted using the configuration as described in the previous post. It shows which kind of initializations are needed to connect the different modules to each other according to the above diagram:

Code:
REM *****************************************************
REM * Test: Fast spike detection using interrupts on M2 *
REM * Jurjen Kranenborg, June 2012                      *
REM * Reports number of key presses after 10 secs       *
REM *                                                   *
REM * The test code connects:                           *
REM * - DAC                                             *
REM * - Comparator (Yes, the M2 has one or more too)!   *
REM * - SR-Latch                                        *
REM * - Interrupt-enabled input                         * 
REM * to detect fast events using standard polled       *
REM * interrupt structure (SETINT)                      *
REM *****************************************************

#picaxe-08m2
#no_data


REM SYMBOL Declarations:
REM --------------------

REM Relevant settings for DAC
REM with maximum output level (31/32 of input at Vref_DAC)
SYMBOL DACCONFIG = %10000100
SYMBOL DACTESTLEVEL = 31

REM Relevant register addresses ansd settings for the comparator 
REM (See PIC12F1840 datasheet)
REM These settings imply that the comparator takes the DAC output and an input pin
REM as inputs, and the comparator output is not routed to an external pin:

SYMBOL CM1CON0 = %01010001		'Comparator Control register 0
SYMBOL CM1CON1 = %01010010		'Comparator Control register 1
SYMBOL CMOUT 	= %01010101		'Comparator Output register 

SYMBOL valCM1CON0 = %10000100		'Comparator Control register 0 value
SYMBOL valCM1CON1 = %00010001		'Comparator Control register 1 value
SYMBOL valCMOUT 	= %00000000	'Comparator Output register value

REM SRLatch configuration
REM - use 28X2 definition for SRConfig2 to let the C1 comparator output set the latch
REM - (not "officially" supported for M2 yet it works!)

SYMBOL SRConfig1 = %10001000
SYMBOL SRConfig2 = %00010000

REM Hardware I/O connections 08M2:

'                   Vcc
'                    |
'       -----        |
'     -|+ ¤ -|-     22k
'     -|-> C0|-      |
'   ---|C4 C1|-------| (Vref_DAC)
'  |  -|C3 C2|- SRQ  |
' >  |  -----  |    22k
'  |  ----<----      |
' ---               ---

Symbol SRLatchOutput = C.2	'Connected to IntInput
Symbol SwitchInput = C.4	'Internal pullup enabled for this test setup only
Symbol IntInput = C.3		'Connected to SRLatchOutput
Symbol Vref_DAC = C.1		'Defined as Vref+ input for DAC using DACSETUP

REM Interrupt defs (SETINT): Active-high polled interrupt on C.3 input

SYMBOL INTcondition = %00001000
SYMBOL INTmask = %00001000

REM Variables:

SYMBOL Counter = w1	'counter for number of key presses

REM --------------------
REM END of SYMBOL declarations



REM Initialization:
REM --------------

REM DAC and Comparator initialization (See SYMBOL declarations).
DACSETUP DACCONFIG
DACLEVEL DACTESTLEVEL
POKESFR CMOUT, valCMOUT
POKESFR CM1CON0, valCM1CON0
POKESFR CM1CON1, valCM1CON1

REM SR-Latch configuration:
SRLATCH SRConfig1, SRConfig2
SRRESET
OUTPUT SRLatchOutput



REM *****
REM MAIN:
REM *****

PULLUP %00010000	'at switch input -> only for this test setup!
ENABLETIME		'Start counting seconds
SETINT INTcondition, INTmask

REM count number of button presses during 10 secs
DO
	DO 	
	LOOP UNTIL time  >= 10
	
	SERTXD ("Counter: ", #Counter, CR, LF)	
	
	LET Counter = 0
	LET time = 0
	
LOOP


INTERRUPT:
	PAUSE 200	'Key debounce effect, remove this line for other apps
	SRRESET
	INC Counter
	SETINT INTcondition, INTmask
	RETURN
/Jurjen
 
Last edited:

PhilHornby

Senior Member
I realise I'm somewhat late to the party, but I think I've got a contribution to make :)

I've just embarked on a project to read the "Meter Pulses" (i.e. LED flashes) of my electricity meter, in order to gauge how much, if any, power is being taken from the grid - as part of a Solar PV diverter experiment.

I investigated reverse-biased LEDS, LDR's and (finally the sensible option), a phototransistor to read this pulse. I have no idea how long these pulses last - and the meter manual doesn't say, so I've been using a 14M2 as a 'Meter Emulator', to see what sort or waveforms I have to detect, in different scenarios. At very short pulse times, the output of a phototransistor starts to look very analogue in nature - which is what made me investigate the use of the in-built comparator.

I believe I have made two improvements to @kranenborg's original solution. The first is to use the FVR reference instead of the DAC and the second is the discovery that a 'polled interrupt' works on an Output pin (so no need to loop externally to another pin). This saves two pins and some external circuitry. I also dispensed with the second comparator as I couldn't really see what extra it added.

Software-wise, the only real change I made, relates to the resetting of the SRLATCH. At 4 MHz, the time spent in the ISR varies between 2.3 and 3.6mS (presumably depending on exactly when the interrupt fires). If the pulse happens to last longer than this, the ISR will fire again immediately and the counter will be wrong. I added a simple loop, waiting for the Comparator output to change back to zero.

Running at the default 4MHz, I can easily count 25µS pulses with this simple circuit. The Meter pulses must be > 100uS (because otherwise, they wouldn't be visible to the naked eye), so I've met my goal.

The circuit uses a 14M2 (why not!) to pulse an LED. The LED is stuffed into one end of a tube and a phototransistor in the other. The phototransistor is connected to an 08M2. D2 is connected to the SRQ output of the latch and because this is always high for at least 2mS, acts as pulse-stretching, visual monitor.

24666

Here is a trace of the signals as seen at the LED (D1) and the phototransistor collector (input to the 08M2).

24667

Rich (BB code):
; *****************************************************
; * Test: Fast spike detection using interrupts on M2 *
; * Jurjen Kranenborg, June 2012                      *
; * Reports number of input after 10 secs             *
; *                                                   *
; * The test code connects:                           *
; * - FVR                                             *
; * - Comparator (Yes, the M2 has one or more too)!   *
; * - SR-Latch                                        *
; * - Interrupt-enabled input                         * 
; * to detect fast events using standard polled       *
; * interrupt structure (SETINT)                      *
; *****************************************************

;Modified slightly by Phil Hornby, May 2021.

#picaxe 08m2
#no_data
#terminal 4800

; SYMBOL Declarations:

; Relevant register addresses ansd settings for the comparator 
; (See PIC12F1840 datasheet)
; These settings imply that the comparator takes the FVR output and an input pin
; as inputs, and the comparator output is not routed to an external pin:

;SFRs
SYMBOL CM1CON0 = %01010001          ;Comparator Control register 0 (111h)
SYMBOL CM1CON1 = %01010010          ;Comparator Control register 1 (112h)
SYMBOL CMOUT   = %01010101          ;Comparator Output register    (115h)
;
; Values to load to SFRs
;
SYMBOL valCM1CON0 = %10000100       ;Comparator Control register 0 value
                                    ;Normal power,high speed,C1out is internal,enabled
SYMBOL valCM1CON1 = %00100001       ;Comparator Control register 1 value
                                    ;c1VN connects to C1IN1-pin,C1VP is FVR reference
SYMBOL valCMOUT   = %00000000       ;Comparator Output register value
                                    ;Bit 0 will be 0 or 1. Init to 0.
                                    ;Apparently mirror copy of C1OUT bit.

; SRLatch configuration
; - use 28X2 definition for SRConfig2 to let the C1 comparator output set the latch
; - (not "officially" supported for M2 yet it works!)
;
; Values to load to SRLATCH config
;
SYMBOL SRConfig1 = %10001000        ;Latch active, "Q" present on SRQ
SYMBOL SRConfig2 = %00010000        ;C1 comparator sets latch (see compsetup)

; Hardware I/O connections 08M2:

;                        
;                       
;        +-----+        
;       -|+ ? -|-        
;       -|-> C0|-       
;    +---|C4 C1|-                  
;       -|C3 C2|-+SRQ  
;        +-----+         
;                       

Symbol SRLatchOutput = C.2          ;Could use a 'monitor' of input (pulse here is about 2.5mS)

; Interrupt defs (SETINT): Active-high polled interrupt on C.2 *OUTPUT*

SYMBOL INTcondition = %00000100     ;C.2 - even though it's an output, works FINE!
SYMBOL INTmask = %00000100          ;for a polled interrupt


; Variables:

SYMBOL Counter = W1                 ;counter for number of key presses


; Initialization:

      pause 2000:sertxd(cr,lf,"START PROGRAM")

;FVR config
      FVRsetup fvr2048                                ;2.048V - use this as a reference.

;
; Can't use Compsetup on 08M2
;
      POKESFR CMOUT, valCMOUT
      POKESFR CM1CON0, valCM1CON0
      POKESFR CM1CON1, valCM1CON1

; SR-Latch configuration:
      SRLATCH SRConfig1, SRConfig2
      SRRESET
      OUTPUT SRLatchOutput

; *****
; MAIN:
; *****

      gosub EnableInterrupts

; count number of input pulses in 10 secs
DO
      Counter = 0
      time = 0
      
      DO : LOOP UNTIL time  >= 10
      
      SERTXD ("Counter: ", #Counter, CR, LF)    
      
LOOP


INTERRUPT:

;
; The process of resetting the latch, takes somewhere between 2.3 and 3.6mS (variable!)
; (Measured from SRQ going high, to it getting cleared)
;
; If the incoming pulse length exceeds this in length, we will need to
; wait for it to end, before resetting the latch. 
; Otherwise, the latch will immediately be set again by the comparator o/p.

      do
            peeksfr CM1CON0,b0                  ;Read Comparator C1 Control register 0
      loop while bit6 = 1                       ;Wait for Comparator o/p to go low (C1OUT bit)
      
      srreset                                   ;now we can reset the latch

      INC Counter                               ;count the interrupt
      
EnableInterrupts: 
      SETINT INTcondition, INTmask              ;re-arm it
      RETURN                                    ;and return
 

AllyCat

Senior Member
Hi,
.... the discovery that a 'polled interrupt' works on an Output pin (so no need to loop externally to another pin).
That's very interesting; one of the reasons that I have always considered the SR Latch to be a fairly "useless" feature of the PICaxe M2 chips is because "the Program" cannot read the status of the Latch (i.e. there is no SFR flag which reads it). Also, you can't use an IF pinx.... to read an output pin which has been set by HIGH, LOW,... etc. because the interpreter first sets the pin back as an Input (but I suppose you can read the Port-Latch SFR). However, this raises more interesting questions of: What happens when an internal Hardware function over-rides the normal Port.pin function and which SFR flag does the Polled Interrupt read? With hindsight, I guess that reading a (suitable) SFR flag is NOT going to switch a Port.Pin direction from Output back to Input.

But this doesn't resolve another issue of C.2 being such a "Jack of All Trades" bottleneck on the 08M2; It's allocated to the PWM, Comparator and SR-Latch Outputs, in addition to SDA and the "normal" I/O pin functions with ADC, Touch, etc.. There are other pins that have a "Latch" function, for example the "Timer 1 Gate" (on pins C.4 or C.3) or the "Interrupt On Change FLAG"s register on ALL 08M2 I/O pins. All their SFR flags can be polled by a program loop, but I wonder about the internal (PICaxe) polled interrupt?
..... the ISR varies between 2.3 and 3.6mS (presumably depending on exactly when the interrupt fires).
Yes that seems a very plausible range for a tight DO : LOOP UNTIL... instruction in the main program. I suspect that enclosing a PAUSE within that loop could reduce it to 1ms, but have never checked if the PAUSE might poll the interrupt flags even faster than 1ms ?

On the hardware side, yes a phototransistor is inherently quite slow, particularly when its base has only an "internal connection" (i.e. floating). The photolectric current "leaks" from collector into the base, and is then amplified by the transistor action to increase the collector current to a more useful magnitude. However, the collector-base junction has the normal parasitic capacitance (a few pF) of any reverse-biassed diode, but this is magnified by the "Miller Effect". A Miller capacitor, from the output of a high negative gain voltage amplifer (Op-Amp, Collector-Base, Drain-Gate or Anode-Grid of a Valve/Vacuum Tube), is normally applied intentionally to deliver a linear ramp for a Sawtooth or Triangle Wave generator, so the exponential rise/fall edges are slightly surprising. My guess is that, as the voltage rises, the reducing current from the pullup resistor (and perhaps the 'scope input capacitance or the Base-Emitter capacitance) dominates, whilst on the falling edge the increase in Miller capacitance (as the reverse "diode" voltage falls) reduces the slope.

Incidentally, zener diodes can make excellent "variable capacitance" (Varicap) diodes with quite high capacitance, because their (theoretical) "parallel plates" are very close together: Essential either to permit "Zener Tunneling" (below about 5v) or the very high field strengths (voltage/distance) for the more common "Avalanche Breakdown" (non destructive) mode of higher voltage "zeners". Also, you could dispense with the 2k2 pullup resistor and use the (30k) Weak Pullup within the PICaxe, which might give 10x higher sensitivity, but at the expense of perhaps being as much as 10x slower!

Cheers, Alan.
 
Last edited:

PhilHornby

Senior Member
On the hardware side... ... you could dispense with the 2k2 pullup resistor and use the (30k) Weak Pullup within the PICaxe, which might give 10x higher sensitivity, but at the expense of perhaps being as much as 10x slower!
It turns out that the LED built-in to my electricity meter is much less bright than the one on my breadboard - so using 2K2 for R2 results in a voltage drop of only 0.8V. Whatever the weak pullup resistance is, it conveniently allows the collector voltage to drop to a very low level. It adds maybe a 100µS to the response time - but it turns out that my meter is set to output 20mS pulses anyway. (The datasheet for the PIC12(L)F1840 aka Picaxe 08M2 says that the source impedance of the input to the comparator should be less than 10K - but it does appear to work OK).

When I saw how much the collector voltage had changed - compared to my breadboard test - I wondered if dispensing with the DAC, in favour of the FVR, was such a good idea after all. Then I realised that the DAC can be fed from the FVR - thus giving a large degree of adjustability, without tying up any pins. I don't think I need it for my project, but might be useful in future.

A modified version of the program to implement :-

Code:
FVR -> DAC -> +COMPARATOR -> SR LATCH <- Polled interrupt
signal  ----> -COMPARATOR
follows in the next post. (More than 10000 chars apparently o_O)
 

PhilHornby

Senior Member
Rich (BB code):
#picaxe 08m2
#no_data
#terminal 4800

;SFRs - See PIC12F1840 datasheet
SYMBOL CM1CON0 = %01010001          ;Comparator Control register 0 (111h)
SYMBOL CM1CON1 = %01010010          ;Comparator Control register 1 (112h)
SYMBOL CMOUT   = %01010101          ;Comparator Output register    (115h)

; CM1CON0: COMPARATOR C1 CONTROL REGISTER 0
;
; C1ON            =  1-------       ;Comparator is enabled
; C1OUT           =  -0------       ;Comparator output bit
; C1OE            =  --0-----       ;C1OUT is internal only
; C1POL           =  ---0----       ;Comparator output is not inverted
; unimplemented   =  ----x---
; C1SP            =  -----1--       ;Comparator operating in normal power, higher speed mode
; C1HYS           =  ------0-       ;Comparator hysteresis disabled
; C1SYNC          =  -------0       ;output is not synched with TIMER1
SYMBOL valCM1CON0 = %10000100       ;composite of above

; CM1CON1: COMPARATOR C1 CONTROL REGISTER 1
;
; C1INTP          =  0-------       ;No interrupt flag will be set on +ve going edge of C1OUT bit
; C1INTN          =  -0------       ;No interrupt flag will be set on -ve going edge of C1OUT bit
; C1PCH           =  --01----       ;C1VP connects to DAC voltage reference
; unimplemented   =  ----xxx-
; C1NCH           =  -------1       ;C1VN connects to C1IN1- pin (RA4 aka C.4)
SYMBOL valCM1CON1 = %00010001       ;composite of above

; SRLatch configuration - see Picaxe Manual 2
; and Section 18.4
; SRCON0: SR LATCH CONTROL 0 REGISTER
;
; SRLEN           =  1-------       ;SR Latch is enabled
; SRCLK           =  -000----       ;1 Fosc wide pulse, every 4th cycle (not used here)
; SRQEN           =  ----1---       ;if SRLEN=1; Q is present on the SRQ pin (C.2)
; SRQEN           =  -----0--       ;External /Q is disabled. (Would be on SERIN)
; SRPS            =  ------0-       ;Pulse Set input = no effect
; SRPR            =  -------0       ;Pulse Reset input = no effect
SYMBOL SRConfig1  = %10001000       ;composite of above 

; SRCON1: SR LATCH CONTROL 1 REGISTER
;
; SRSPE           =  0-------       ;SRI pin has no effect on the set input of the latch
; SRSCKE          =  -0------       ;SRCLK has no effect on the set input of the latch
; reserved        =  --x-----
; SRSC1E          =  ---1----       ;SR latch is set when the C1 Comparator o/p is high
; SRRPE           =  ----0---       ;SRI pin has no effect on the reset input of the latch
; SRRCKE          =  -----0--       ;SRCLK has no effect on the reset input 
; reserved        =  ------x-
; SRRC1E          =  -------0       ;C1 Comparator output has no effect on the reset input
SYMBOL SRConfig2  = %00010000       ;composite of above

;See data sheet Section 14.3
; FVRCON: FIXED VOLTAGE REFERENCE CONTROL REGISTER
;
; FVREN           =  1-------       ;Fixed Voltage Reference is enabled
; FVRRDY          =  -1------       ;Fixed Voltage Reference output is ready for use.
; TSEN            =  --0-----       ;Temperature Indicator is disabled
; TSRNG           =  ---0----       ;Temperature Indicator Range Selection (not used)
; CDAFVR          =  ----11--       ;Comparator,DAC and CPS module Fixed Voltage Reference = 4.096V
; ADFVR           =  ------00       ;ADC Fixed Voltage Reference Peripheral is off
symbol FVRConfig  = %11001100       ;composite of above

;See data sheet Section 17.7 and Picaxe Manual 2
; DACCON0: VOLTAGE REFERENCE CONTROL REGISTER 0
;
; DACEN           =  1-------       ;DAC is enabled
; DACLPS          =  -0------       ;DAC negative source selected
; DACOE           =  --0-----       ;DAC voltage level is disconnected from DACOUT pin
; unimplemented   =  ---x----
; DACPSS          =  ----10--       ;+ve Source select bits = FVR Buffer 2 output
; unimplemented   =  ------xx
SYMBOL DACCONFIG  = %10001000       ;composite of above


; Interrupt defs (SETINT): Active-high polled interrupt on C.2 *OUTPUT*
SYMBOL INTcondition = %00000100     ;C.2 - even though it's an output, works FINE!
SYMBOL INTmask      = %00000100     ;for a polled interrupt

Symbol SRLatchOutput = C.2                      ;Could use a 'monitor' of input (pulse here is about 2.5mS)

; Variables:

SYMBOL Counter = W1                             ;counter for number of key presses


; Initialization:

      pause 2000:sertxd(cr,lf,"START PROGRAM")

      pullup %00010000                          ;pullup C.4, instead of using 2K2 resistor

      fvrsetup FVRConfig                        ;Configure Fixed Voltage Reference
      DACSETUP DACCONFIG                        ;COnfigure DAC
      DACLEVEL 16                               ;we can change the level...
                                                ;3 - 31 work with attached phototransistor circuit.
                                                ;3 / 32 * 4.096 = 0.384V

      POKESFR CM1CON0, valCM1CON0               ;Comparator has two
      POKESFR CM1CON1, valCM1CON1               ;control registers
                                                ;compsetup not supported on M2 :-(

      SRLATCH SRConfig1, SRConfig2              ;Configure latch
      SRRESET                                   ;ensure latch is cleared.
      
      OUTPUT SRLatchOutput                      ;bring it to the outside world.

      gosub EnableInterrupts

; *****
; MAIN:
; *****

DO
      Counter = 0
      time = 0
      
      DO : pause 1: LOOP UNTIL time  >= 10      ;count number of input pulses in 10 secs
      
      SERTXD ("Counter: ", #Counter, CR, LF)    
      
LOOP


INTERRUPT:

      do
            peeksfr CM1CON0,b0                  ;Read Comparator C1 Control register 0
      loop while bit6 = 1                       ;Wait for Comparator o/p to go low (C1OUT bit)...
                                                ;...before resetting the latch. 
      
      srreset                                   ;now we can reset the latch

      INC Counter                               ;count the interrupt
                                                ;fall through 
EnableInterrupts: 
      SETINT INTcondition, INTmask              ;re-arm it
      RETURN                                    ;and return
      
 
Last edited:

AllyCat

Senior Member
Hi,
The datasheet for the PIC12(L)F1840 aka Picaxe 08M2 says that the source impedance of the input to the comparator should be less than 10K - but it does appear to work OK
I thought that applied (only) to the ADC inputs (to ensure full 10-bit accuracy), but it's only likely to apply to "extreme" conditions (e.g. temperature) anyway. Not relevant in this application, but the "DAC" itself can be considered as a tapped 160k resistor (32 * 5k, nominally), with "switches" each end (across Legs 6 - 8 and/or Vcc/FVR) which can occasionally be useful (e.g. for a very weak pull-up or down).
... follows in the next post. (More than 10000 chars apparently o_O)
Probably because you've used the "Copy for Forum" option, or another "shortcut"? If you remove the "=RICH" from the CODE tag, you'll see how much "COLOR" bloat is being added. I normally just use the "Copy" option (and/or PE5 ;) ) for a black and white listing ........ and STILL manage to exceed the 10000 characters limit sometimes. :(

Cheers, Alan.
 

PhilHornby

Senior Member
I thought that applied (only) to the ADC inputs (to ensure full 10-bit accuracy), but it's only likely to apply to "extreme" conditions (e.g. temperature) anyway.
It's in Section "19.10 Analog Input Connection Considerations"
"A maximum source impedance of 10 k is recommended for the analog sources..."

There's diagram (Figure 19-3) that also shows "RS < 10K". But, as I said, it appears to work ok. :)
 

AllyCat

Senior Member
Hi,

Interesting. But that section references Figure 19-3 and the second paragraph suggests the context is the leakage current, i.e. "Also, any external component connected to an analog input pin, such as a capacitor or a Zener diode, should have very little leakage current to minimize inaccuracies introduced."

If we then look at Fig. 19-3 we see (as often with Microchip data sheets) the frustrating note to the "Leakage" element: "Note 1: See Section 30.0 “Electrical Specifications”.", which is somewhere within 36 pages (and sometimes there's further information in another 36 pages of section 31). :( However, the relevant section appears to be on page 312:

InputLeakage08M2..png


So at 125 degrees C, a leakage of up to 1 microAmp might flow, which would give a maximum "error" (voltage drop) across 10 kohms of 10 mV. That does indeed represent a few digits (steps) of a READADC10, particularly if using FVR2048 as Reference (remember that using a FVR1024 reference is also "not recommended"). But at 85 degrees, and particularly for the "Nominal" value, the error will be fractions of a mV (nominal = 50 uV across 10k).

IMHO that value is totally irrelevant to the Comparator, because if you look at page 326, the Comparator specification (at 25 degrees C) gives the Input Offset voltage as: Input Offset Voltage = Nominal ±7.5 mV and Maximum ±60 mV. , or about 100 times worse! The 10k recommendation applies to the ADC for a much better reason, because the ADC input has a Sample-And-Hold (pulse) stage which effectively "magnifies" the source resistance. Thus this "10k recommendation" is actually relaxed (by an undefined amount) if an external capacitor is added to the pin.

If you want to give yourself fright, look at D070 back on page 312; the Weak Pullup Current has a "Minimum" specified current limit of 25 uA at 5 volts, i.e. an equivalent "Resistance" of 200 k ohms (and minimum value of 17k) !

Cheers, Alan.
 

Technical

Technical Support
Staff member
Just as a point of interest,
Also, you can't use an IF pinx.... to read an output pin which has been set by HIGH, LOW,... etc. because the interpreter first sets the pin back as an Input (but I suppose you can read the Port-Latch SFR).
if outpinX.Y then... reads the latch state of an output, if pinX.Y then... reads the input
 
Top