serout2 apparently changing other I/O?
	
	
		Funny problem: The program below runs on a PIC12F1501. If I remove all of the SEROUT2 stuff, It runs fine, with RLY action as expected. It also works as is, but the RLY (PORTA.0) output only pulses for about 5 uS each time through the loop. Any ideas?
'*************************************************  ***** 
'* Battery saver for T-D industrial trucks 
'* Richard Baggett for Sodexo at P&G Lima 
'*************************************************  ***** 
 
DEFINE OSC 16         'Don't care about power in this app. 
DEFINE ADC_BITS 10 
DEFINE ADC_SAMPLEUS 50 
OSCCON = 111010 
AD  VAR PORTA.4 
STX VAR PORTA.5 
RLY VAR PORTA.0 
AV    VAR    WORD        'Average of 10 samples 
AN  VAR WORD        'Analog value for voltage 
EGG    VAR    WORD        'counter for 2 minute timer 
PT    VAR    BYTE        'Rolling average pointer 
IX    VAR    BYTE        'General use index 
IDX VAR BYTE        'General use index 
RL    VAR    WORD[10]    'Rolling average storage 
TRIP VAR WORD        'Trip value 
 
                    'AD config as follows 
                    'ANSEL register for PIC12F1501 
ANSELA.4 = 1        'Pin 4 analog  
Input AD            'Make the analog pin an input 
ADCON0 = 001101  'Set for chan 3, on, and not converting 
ADCON1 = 100000  'Right justify, Fosc/32, Vref is Vdd 
ADCON2 = 0          'No auto trigger of conversion 
 
FOR IX = 0 TO 9        'Initialize to full charge 
    RL[IX] = 1024    'to allow moving the truck 
NEXT                'for service on power up 
TRIP = 2560 
                    'Timer setup for sampler 
PR2 = 250            'count value 
T2CON = 111111    '1:64 prescale, 1:16 postscale, timer ON 
EGG = 1874            'First measurement immediately 
PIE1.1 = 1            'Enable the interrupt 
ON INTERRUPT GOTO SAMPLE: 
INTCON = 000000 
 
OUTPIN VAR RLY    'Set up output for relay 
OUTPUT OUTPIN         
AN = 0 
PT = 0 
 
MLOOP: 
 
    'Lets output some stuff for initial calibration 
    'and eventual troubleshooting 
 
    SEROUT2 STX,16780,["Raw value: "] 
    SEROUT2 STX,16780,[DEC AN] 
    FOR IDX = 0 TO 5 
        SEROUT2 STX,16780, [32] 
    NEXT 
    SEROUT2 STX,16780,[13] 
    SEROUT2 STX,16780,["Avg X 10:  "] 
    SEROUT2 STX,16780,[DEC AV] 
    FOR IDX = 0 TO 5 
        SEROUT2 STX,16780, [32] 
    NEXT 
    SEROUT2 STX,16780,[13] 
    SEROUT2 STX,16780,["Trip Point: "] 
    SEROUT2 STX,16780,[DEC TRIP] 
    FOR IDX = 0 TO 5 
        SEROUT2 STX,16780, [32] 
    NEXT 
    SEROUT2 STX,16780,[13] 
     
    'Decide if battery is charged enough 
    IF AV > TRIP THEN 
        RLY = 1 
        SEROUT2 STX,16780,["Truck is enabled "] 
    ELSE 
        RLY = 0 
        SEROUT2 STX,16780,["Truck is disabled"] 
    ENDIF 
 
    SEROUT2 STX,16780,[1] 
     
GOTO MLOOP: 
 
SAMPLE:                'Called 16.625 times per second 
                    'sample must run every 
                    '1875 calls for 1 iteration 
                    'every 2 minutes 
                    '10 samples in rolling average 
                    'make a 20 minute rolling average 
    DISABLE 
    ADCIN 3, AN            'Get the analog value 
    EGG = EGG + 1 
    IF EGG = 1875 THEN 
        EGG = 0 
        RL[PT] = AN        'Stuff it in the average pool 
        PT = PT + 1        'Set up next spot in the pool 
 
        IF PT = 10 THEN    'Recurse 
            PT = 0 
        ENDIF 
 
        AV = 0            'Compute average (*10) 
        FOR IX = 0 TO 9 
            AV = AV + RL[IX] 
        NEXT 
 
    ENDIF 
    PIR1.1 = 0 
RESUME 
     
    END
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		Whenever an output doesn't behave the expected way and there are other operations on the same port (RLY and STX both on PortA in this case) I always suspect a read-modify-write issue - especially so when the operating frequency goes up. To verify if this is the case try inserting a short PAUSE between setting/resetting RLY and doing the SEROUT2.
Are you driving the relay directly from the PIC (heavy load) or do you have driver in between?
/Henrik.
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		Your ANSELA setting is wrong
use LATA instead of PORTA for your output (refer to section 11 for more details)
double check the POR register default
	 
	
	
	
		SOLVED! serout2 apparently changing other I/O?
	
	
		ANSELA was the problem. I now set it to zero before turning on bit 4. This fixed the problem!. I wonder if PBP sets the correct ANSELA bit for me when using ADCIN, I didn't have time to test current consumption today to find out. Thanks Mr.E!
@Henrik, I too suspected RMW trouble and inserted a delay. I also moved the RLY portion of the program around, even putting it in the ISR to no avail.
Yes, there is a transistor to drive the relay. I have found it troublesome in many ways to drive 5V (Or 3.3V!) relays from my logic supply. I typically power relays from the highest voltage available in the project in order to reduce current consumption and reduce the demand on my regulators, as well as reduce spontaneous resets, glitches, and outright frying stuff.
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		Hi,
I still think it WAS a RMW write issue but the cause wasn't heavy loading of the output and/or speed as I initially suspected. The cause was, as Steve noticed, the ANSEL register.
A pin configured for analog input will, when read, return '0'. The SEROUT2 statement, doing RMW operations, will read the port, flip a bit and re-write the port. What's happening then is that the port is read and since the RLY-pin is configured as analog it will (always) read '0', the STX pin/bit will then be modified and the port will be re-written - this time with the RLY-bit/pin as 0 because that is what was read.
With ANSEL correctly setup (RLY-bit/pin as digital) the RMW process of the SEROUT2 statement will read the correct state of the RLY-pin so when the port byte is re-written it will keep the '1'-state previously set.
Steves suggestion of using LAT instead of PORT is great, however in this particular case I don't think it would have made any difference because I don't think (I'm not sure though) SEROUT2 actually targets the LAT registers so the result would have been the same anyway. However, for manual 'bit-flipping' using the LAT register would prevent RMW-issues caused by capacitive loading of the pin etc.
(Actually it's not the SEROUT2 statement per se that performs the RMW operation, it's just the way the PIC works internally.)
/Henrik.
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		@ Henrik Yep, agreed on all counts. I tried the LATA solution, too, and then found that PIC12F1501 doesn't have LATA...
Correct ANSELA fixed the problem and allowed me to keep the diagnostics.
I also had time to look at the effects of not setting the ANSELA bit on the analog input. While there was no measurable difference near the power supply rails, at 1.2V input a correct setting reduced power consumption by about 700uA.
I can't explain why, but adding a delay before the SEROUT2 didn't change the duration of the pulse... but removing the SEROUT2 removed the problem... curious.
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		What?  It have LATA register, it compile and it works.... maybe you need to upgrade, or double check the chip you compile for?
 ;)
anyway, since the problem is solved...
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		mister_e, I just downloaded a new data sheet to prove you wrong. but you're right... I will need spend more time on why it didn't work for me, (And why I didn't find it when I searched my data sheet before...) When I get LATA to compile I'll use that method just for the correct-ness of it.:D
	 
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
	
	
	
		Re: serout2 apparently changing other I/O?
	
	
		Yep, that was it. The version of PBP in my shop was current, and had no problem. The copy at the customer's site was ordered from DigiKey, must have been on the shelf a while...