Log in

View Full Version : serout2 apparently changing other I/O?



rabaggett
- 12th November 2012, 22:41
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

HenrikOlsson
- 13th November 2012, 06:16
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.

mister_e
- 13th November 2012, 06:37
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

rabaggett
- 13th November 2012, 21:43
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.

HenrikOlsson
- 14th November 2012, 06:30
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.

rabaggett
- 19th November 2012, 12:01
@ 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.

mister_e
- 19th November 2012, 15:10
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...

rabaggett
- 21st November 2012, 18:44
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

mister_e
- 22nd November 2012, 01:31
check this out ;)
http://support.melabs.com/content/29-PicBasic-Pro-Version-History?

rabaggett
- 26th November 2012, 14:11
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...