Page 1 of 1

PIC halts when GPS turned off, using NMEA module

Posted: Wed Feb 06, 2008 6:21 pm
by RadioT
Hi,

1. I have the power line to the GPS controlled by the PIC. When I'm done with it, I turn it off to save power.

However, I'm finding that about 1 in 10 times, when I turn off the GPS, the PIC halts and has to be reset. I'm using the NMEA module.

It was halting nearly every time I turned off the GPS until I disabled the interrupt (made it public then called it from the main routine).

I also tried (and none worked):
- disabling the serial port altogether before shutting it down
- just turning off the EUSART2 interrupt: PIE3.5 = 0
- slowed speed from 32 MHz to 16 MHz - there is a silicon errata that says the chip may get errors accessing RAM above 32 MHz when using the PLL - no difference
- different combinations of disable interrupt, turning off GPS, delays in between each to see if things needed time to settle before going on to the next operation
- scoped the power and on/off lines to the GPS and PIC - no abnormal spikes/sags were noted

None of these measures offered a solution. Any ideas out there??

It would sure be nice to be able to have visibility of just where the program is going when it halts. Can anyone recommend a good method of debugging to see what's going on in the chip? I guess SF does not have a debug capability at all?


2. On another note, when the PIC does wake up and I want to turn the GPS on again, I call the NMEA.Initialize subroutine first (I made this public in the NMEA module, too), then turn on the GPS, and the GPS readings are picked up again in NMEA.bas's TNMEA structure. It's a bit unexpected, though, that NMEA.GetItem(NMEAItem) doesn't seem to trigger the USART2.Write debug statement to the serial port like it does the first time through the code before sleeping, but so far I've been able to get my data out of the structure. I don't have a lot of confidence in this, though, and am still testing it:

Code: Select all

If NMEA.GetItem(NMEAItem) Then
      GLCD.WriteAt(0,95,"in loop,index=",DecToStr(index))
      USART2.Write("index",DecToStr(index),$0D)
      NMEA.GetField(NMEAItem,0,EUSART2_Input)
      If EUSART2_Input = "$GPRMC" Then
         GLCD.SSD1339.Rectangle(0,19,132,107,$FF,$FF,$FF,$FF) //clear middle of screen             
         NMEA.GetField(NMEAItem, 2, lock_status)
         NMEA.GetField(NMEAItem, 3, lat)
         GLCD.WriteAt(0,20,"Lat: ", lat)
         NMEA.GetField(NMEAItem, 5, long)
         GLCD.WriteAt(0,33,"Long: ", long)
         NMEA.GetField(NMEAItem, 9, EUSART2_Input)
         GLCD.WriteAt(0,47,"Date: ", EUSART2_Input)
         NMEA.GetField(NMEAItem, 1, GMT_time)
         GLCD.WriteAt(0,60,"Time: ", GMT_time) 
         NMEA.GetField(NMEAItem, 2, EUSART2_Input)
         NMEA.GetField(NMEAItem, 7, EUSART2_Input)
         GLCD.WriteAt(0,73,"Speed: ", EUSART2_Input)
         speed = EUSART2_Input
         speed = TrimToChar(speed,".")        
         speed_int = StrToDec(speed)  
       EndIf
   EndIf

Posted: Wed Feb 06, 2008 10:46 pm
by xor
Disable MCLR in the Configs and see if the the effect persists.

When you say the PIC is controlling power to the GPS... how? Is there a FET/BJT or are you driving it directly from a PIC pin?

Nothing like making sure the both devices are decoupled nicely. Throw a little heavier cap across on the GPS power line to let it power down a little slower.

Nothing like being a back-seat driver with these types of problems... 8)

There are a few things that can reset a PIC... low/no voltage (BODEN), MCLR, WDT. Halting might be using the SLEEP instruction, or the Crystal Oscillator gets disconnected or stops.

Posted: Wed Feb 06, 2008 11:12 pm
by RadioT
Hi XOR,

I'm turning on a transistor. I have a a resistor between the port and the base, with power from VCC to the GPS on emitter & collector. I was tying it high as well but dropped that since I would save the part and fuss of placing it. The behaviour of the circuit didn't change one way or the other after I took it off.

Disable MCLR? Well, I have it tied high now, with a cap going to ground to round out the corners. I also have a diode on it to the port after the resistor & cap.

I'm wondering if it's something to do with the interrupt. I'm going through the assembler to see if there's a possibility it's being sent to la-la land on not seeing GPS data when it's disabled. I did manage to get MPLab to run the debugger....after I upgraded it to the latest version, the .asm file compiled and then ran under the debugger. It wouldn't run under the older version I had. Still can't see where exactly it's going on failure.

I know what I'll do - I'll make a copy of the file and cut out as much of the bulk of it as possible, then see if it still behaves this way. Maybe that'll give better insight. At least, it'll be less .asm to wade through.

-Tom

Posted: Thu Feb 07, 2008 12:31 am
by xor
A small PFET works nicely as a power switch. It requires no power from the PIC and they come with 25milliohms of On resistance. Just connect the source to +5 and the drain directly to the GPS power. When the PIC output is low the FET turns on and when the PIC output is high the FET is off.

Posted: Thu Feb 07, 2008 3:45 am
by RadioT
I doubt it's a hardware thing. I'm using port G which can't source much, but then it doesn't need to turning on a transistor. I'll keep digging at it and post when I find a solution.

73's
de Tom

Posted: Thu Feb 07, 2008 4:35 am
by RadioT
Interesting. If I comment out the NMEA module's initialize command at the bottom of the file, and call it when I'm ready to use the GPS, the GPS data is not picked up. If I call the interrupt service routine directly with enable, it works. How can there be a difference?

-Tom

Posted: Thu Feb 07, 2008 7:03 pm
by RadioT
OK I think I've found the answer. I think it was just a coincidence that the unit died when the GPS was turned off. I narrowed down the problem to this particular line of code, that was located right after the GPS power down command:

Code: Select all

Local_time = (DecToStr(temp) + ":" + Mid(GMT_time,2,2) + ":" + Mid(GMT_time,4,2))
 

Seems the unit would halt or reset at this line. I split it up:

Code: Select all

Temp_string = DecToStr(temp) 
Temp_string2 = Temp_string + ":" + Mid(GMT_time,2,2) 
Local_time = Temp_string2 + ":" + Mid(GMT_time,4,2)
After about 50 tests, no halts. I would usually get to about 10 and see something go wrong.

-Tom