PDA

View Full Version : Help to setup GPS connection.



mbox
- 22nd October 2010, 03:33
Hi everyone, I have a GPS with 57600 baud rate and runs on 3.3v, I'm using Pic16F877A with 4Mz crystal. I'm planning to use Serin to read GPS data on PortB.0 and use PortC.6 for Serout to transmit it an LCD or to PC. Do I need to have voltage divider...please give advice.


thanks
mbox

mackrackit
- 22nd October 2010, 04:14
Read this
http://www.picbasic.co.uk/forum/showthread.php?t=5667

To give you a good answer we would need the data sheet of the GPS.

ScaleRobotics
- 22nd October 2010, 05:21
I have a GPS with 57600 baud rate and runs on 3.3v, I'm using Pic16F877A with 4Mz crystal.

That's a little too high a baud rate for 4 mhz to handle. I think you will have better luck trying 57600 with a 20 mhz crystal.

mbox
- 23rd October 2010, 00:32
Hi,

Read this
http://www.picbasic.co.uk/forum/showthread.php?t=5667

To give you a good answer we would need the data sheet of the GPS.

So far based on what I read I think, voltage divider is not needed because I just want data reading from GPS(LS20031) to MCU or PC.
For GPS to Pic16F877A
GPS Tx--> Mcu Rx
For GPS to PC
GPS Tx--> PC Rx

thanks and regards,
mbox

mbox
- 23rd October 2010, 00:43
That's a little too high a baud rate for 4 mhz to handle. I think you will have better luck trying 57600 with a 20 mhz crystal.

okay I will try to change the crystal and update you the results.

thanks and regards,
mbox

ScaleRobotics
- 23rd October 2010, 01:18
So far based on what I read I think, voltage divider is not needed because I just want data reading from GPS(LS20031) to MCU or PC.
For GPS to Pic16F877A
GPS Tx--> Mcu Rx
For GPS to PC
GPS Tx--> PC Rx


The LS20031 is TTL, and not RS-232. So you will not be able to send it out directly to the PC. You will need something like a max232, or an equivalent to invert the signal levels.

Your PIC should be able to receive the TTL at 3.3v, even though I am guessing the PIC is at 5v. Just don't TX from the PIC to the GPS without a level shifter.

mbox
- 28th October 2010, 08:42
Sorry its been a while, been busy working with other things.

The LS20031 is TTL, and not RS-232. So you will not be able to send it out directly to the PC. You will need something like a max232, or an equivalent to invert the signal levels.

Your PIC should be able to receive the TTL at 3.3v, even though I am guessing the PIC is at 5v. Just don't TX from the PIC to the GPS without a level shifter.
Thanks for the info...one more question, I don't have 20Mz crystal, but I do have 20.945 Cyrstal, can I use it?

thanks in advance,
mbox

ScaleRobotics
- 28th October 2010, 12:34
For the baud rate to be timed right, PicBasic needs to told exactly what frequency the crystal is. PicBasic only allows certain crystals to be defined. Here are the settings allowed: MHz: 3(3.58) 4 8 10 12 16 20 24 25 32 33 40 48 64. Of course your chip has restrictions as well. (It max's out at 20 mhz).

If you have a 16mhz crystal, you might give it a try while you wait for a 20mhz to come in. 38400 baud works with debug out at 8 mhz, so at 16mhz I figure your 57600 might work. In the meantime, you could connect the gps to a max232 device, and change the baud lower with your computer. Then you could connect it to your pic at a lower baud rate, using a lower speed crystal. But 20mhz is highly recommended.

mbox
- 29th October 2010, 23:02
Hi,
Finally I manage to make the baudrate to 9600 with this guide http://docs.trenz-electronic.de/GlobalT ... ket_01.pdf but I have not connected it yet to PIC16F877A.
I'm going to use SERIN on PortB.0 to fetch data from GPS using 4Mz crytsal....feed back you later the result when I get back home.

regards,
mbox

mbox
- 30th October 2010, 01:19
Hi, I got a follow up question, I need to get latitude and longitude from this string
$GPRMC,053740.000,A,250.6319,N,12136.0099,E,2.69,7 9.65,100106,,,A*53. How can I achieve it using SERIN?

thanks,
mbox

mackrackit
- 30th October 2010, 01:54
You would be better off using SERIN2.
Here is a snippet from something .

SERIN2 PORTB.2,16572,[WAIT("$GPGGA"),WAIT(","),DEC2 H,DEC2 M,DEC2 S,_
WAIT(","),DEC2 ND,DEC2 NM,WAIT("."),DEC3 NMD,WAIT(",N,"),_
DEC3 WD,DEC2 WM,WAIT("."),DEC3 WMD]

mbox
- 1st November 2010, 14:17
You would be better off using SERIN2.
Here is a snippet from something .

SERIN2 PORTB.2,16572,[WAIT("$GPGGA"),WAIT(","),DEC2 H,DEC2 M,DEC2 S,_
WAIT(","),DEC2 ND,DEC2 NM,WAIT("."),DEC3 NMD,WAIT(",N,"),_
DEC3 WD,DEC2 WM,WAIT("."),DEC3 WMD]

Hi, I'm trying to understand SERIN2 command. why this code do not work when I entered "hello"?

Include "modedefs.bas"
main:
Serin2 PORTC.7, T9600, error, [WAIT("hello")]
serout2 PortC.6, T9600, ["Valid"]
goto main

error:
serout2 PortC.6, T9600, ["Invalid"]
goto main
end

regards,
mbox

mackrackit
- 1st November 2010, 21:12
I imagine many are thinking, "have you read the manual?".

Include "modedefs.bas"
Does nothing with SERIN2/SEROUT2.

T9600
Is for SERIN/SEROUT. "T" is for true mode anyways so if you are connecting directly to a PC you want INVERTED mode.

Appendix A from the manual has the modes for SERIN2. At 9600 baud the mode will be 16468. To see how that is calculated look here. http://www.picbasic.co.uk/forum/content.php?r=106-How-to-calculate-the-MODE-number-for SERIN2-SEROUT2

You will also want to specify a time for the GOTO LABEL "error".

Try this

SERIN2 PORTC.7, 16468,100, error, [WAIT("hello")]
The above will wait for 100 milliseconds, then GOTO "error" if "hello" is not received.

mbox
- 1st November 2010, 23:57
Hi mackrackit, thanks for the help, appreciated very much. I manage to run this code MCU to PC and use this guide http://melabs.com/resources/ser2modes.htm

main:
SERIN2 PORTC.7, 84,200, error, [WAIT("Hello")]
serout2 PortC.6,84, ["Valid",10,13]
goto main

error:
serout2 PortC.6, 84, ["Invalid",10,13]
goto main
end
I know u have given me an example, but dont really get it ,
Is there a way I could receive this value "$GPRMC,053740.000" and place it on a variable?

thanks and regards,
mbox

mackrackit
- 2nd November 2010, 02:15
H VAR BYTE 'HOURS
M VAR BYTE 'MINUTES
S VAR BYTE 'SECONDS
[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Waits for GPRMC

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Waits for ","

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the first two digits into VAR H

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the middle two digits into VAR M

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the last two digits into VAR S

"$GPRMC,053740.000"
053740 =
H = 05 Hours
M = 37 Minutes
S = 40 Seconds

mackrackit
- 2nd November 2010, 02:40
If you have not seen this it might be handy
http://aprs.gids.nl/nmea/

flotulopex
- 2nd November 2010, 10:33
Be careful while using TIMEOUT - you may get fuzzy results.

Have a look here http://www.picbasic.co.uk/forum/showthread.php?t=13470&p=91443#post91443.

mbox
- 3rd November 2010, 11:46
Be careful while using TIMEOUT - you may get fuzzy results.

Have a look here http://www.picbasic.co.uk/forum/showthread.php?t=13470&p=91443#post91443.

Hi, thanks for the tip, it sure did saved me from trouble :)

regards,
mbox

mbox
- 3rd November 2010, 11:48
H VAR BYTE 'HOURS
M VAR BYTE 'MINUTES
S VAR BYTE 'SECONDS
[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Waits for GPRMC

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Waits for ","

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the first two digits into VAR H

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the middle two digits into VAR M

[WAIT("$GPRMC"),WAIT(","),DEC2 H,DEC2 M,DEC2 S]
Places the last two digits into VAR S

"$GPRMC,053740.000"
053740 =
H = 05 Hours
M = 37 Minutes
S = 40 Seconds

Thanks so much mackrackit.

regards,
mbox

mbox
- 5th November 2010, 15:28
Hi, I want to try to use 38400 baud rate with 20Mz crystal. I want to test it first in the hyperterminal by entering this line "$GPGGA,115209.600,1114.5166,N,12500.3439,E,1,10,0. 83,16.9,M,55.4,M,,*5E" and I use this code

DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 32 ' 38400 Baud @ -1.36%
define HSER_BAUD 38400
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
define OSC 20

gpsin var portc.7 'rx
gpsout var portc.6 'tx


HH VAR byte
MM VAR BYTE
SS VAR BYTE
ND VAR BYTE
NM VAR BYTE
NMD VAR WORD
WD VAR BYTE
WM VAR BYTE
WMD VAR WORD
AR VAR BYTE[20]

START:
SERIN2 gpsin,16572,[WAIT("$GPGGA"),WAIT(","),DEC2 hH,DEC2 mM,DEC2 sS,_
WAIT(","),DEC2 ND,DEC2 NM,WAIT("."),DEC3 NMD,WAIT(",N,"),_
DEC3 WD,DEC2 WM,WAIT("."),DEC3 WMD]

PAUSE 1000

SEROUT2 gpsin,16572,[DEC2 HH,DEC2 MM,DEC2 SS,_
DEC2 ND,DEC2 NM,DEC3 NMD,DEC3 WD,DEC2 WM,DEC3 WMD,13,10]


goto START
end but I dont have any display on the recieve window. Please help..

regards,
mbox

mackrackit
- 5th November 2010, 15:42
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 32 ' 38400 Baud @ -1.36%
define HSER_BAUD 38400
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
Get rid of the above. You are not using the hardware with SERIN2

ScaleRobotics
- 5th November 2010, 15:45
It looks like you have not quite decided whether to use the hardware serial port, or serin2/serout2. Once you decide which one you are using, you may have better luck. Let us know how it goes.

EDIT: Once again, beaten by Dave....

mbox
- 5th November 2010, 22:54
Hi, I was happy when I got the GPS set to 9600 but yesterday I found out that it reset itself to 57600. I tried to reset it back to 9600 but failed and I tried it the whole afternoon...I use this as my reference http://www.laptopgpsworld.com/3701-diy-gps-module-using-locosys-ls20031 it can only lowered to 38400, so I have no choice but to try this baudrate. My first time to use 20Mz crystal. I'm showing my codes when the GPS was running fine in 9600 baudrate. Please forgive my codings, still learning :o

clear
Include "modedefs.bas"
H VAR BYTE[2]

TRISD = %00000000 ' PortD.0 LCD connection
TRISC = %10000000 ' PortC.6 as tx and PortC.7 as rx
TRISB = %00000001 ' PortB.0 as rx from GPS
PortB = %00000000
PortD = %00000000

'This following serout2 command is use for bluetooth initialization
SerOut2 PortC.6,84, [$02,$52,$27,$06,$00,$7F,$12,$13,$23,$17,$09,$00,$0 3]
pause 200
SerOut2 PortC.6,84, [$02,$52,$66,$00,$00,$B8,$03]
pause 200
Serout2 PortC.6,84, [$02,$52,$04,$11,$00,$67,$10,$4D,$49,$43,$52,$4F,$4 2,$4F,$58,$42,$54,$31,$20,$20,$20,$20,$00,$03]

RX var byte ' Receive byte

serout PortD.0,T9600,[$1B,$45]
serout PortD.0,T9600,["Loging on.."]
pause 300

''Main Code
Pause 1000

serout PortD.0,T9600,[$1B,$45]
serout PortD.0,T9600,["**GPS Locator**"]

Menu:
pause 200

'****** [Menu setup on PC screen] *************************

serout PortD.0,T9600,[$1B,$45,"**System Ready**"]

Receive:
' ***** [Receive the menu selection from Bluetooth receiver] ***************
serin PortC.7, T9600, RX 'Receive menu from Bluetooth
'serout PortD.0,T9600,[$D,RX] 'Check Input
RX = RX - $30 'Convert ASCII to decimal value

If RX > 1 then Error ' Test for good value
Branch RX, [zero, one] 'redirect to menu selection code

error:
serout2 PortC.6, 84, ["Oops Try again ",#RX,10,13]
goto menu

Zero:
'***** [ Code for zero value ] *****************************
goto menu 'Return to menu, zero is not a valid selection

One:
'***** [Code for selection 1] ************************

;serout PortD.0,T9600,[$D,"Request ",#rx]
;serout PortD.0,T9600,[$1B,$45,"**System Ready**"]
;serout PortD.0,T9600,[$D,"Data sent"]

SERIN2 PORTB.0, 84,40, error,[WAIT("$GPRMC"),WAIT("A,"),str H\24]
pause 500
serout2 PortC.6, 84, [str H\24,10,13] 'Send data to bt
' example output: 1114.5089,N,12500.3864,E
pause 500
goto menu 'Return to main menu


goto menu

End

Please help me make it run to 38400 baudrate, I have the 20Mz crystal.

thanks in advance,
mbox

mbox
- 5th November 2010, 23:08
I am trying to run this code...
define OSC 20

gpsin var portc.7 'rx
gpsout var portc.6 'tx


HH VAR byte
MM VAR BYTE
SS VAR BYTE
ND VAR BYTE
NM VAR BYTE
NMD VAR WORD
WD VAR BYTE
WM VAR BYTE
WMD VAR WORD
AR VAR BYTE[20]

START:
SERIN2 gpsin,16572,[WAIT("$GPGGA"),WAIT(","),DEC2 hH,DEC2 mM,DEC2 sS,_
WAIT(","),DEC2 ND,DEC2 NM,WAIT("."),DEC3 NMD,WAIT(",N,"),_
DEC3 WD,DEC2 WM,WAIT("."),DEC3 WMD]

PAUSE 1000

SEROUT2 gpsout,16572,[DEC2 HH,DEC2 MM,DEC2 SS,_
DEC2 ND,DEC2 NM,DEC3 NMD,DEC3 WD,DEC2 WM,DEC3 WMD,13,10]
goto start
I'm testing PC to MCU first, but I don't have response when entering $GPGGA,114708.600,1114.5089,N,12500.3864,E,1,6,1.6 7,23.5,M,55.4,M,,*69

regards,
mbox

mbox
- 7th November 2010, 08:53
:cool:I manage to run this code for a start
@ DEVICE HS_OSC
DEFINE OSC 20
main:

serout2 PortC.6,32774,["To PC",$D] ;@38400 To PC
serout2 PortB.6,84,[$1B,$45]
serout2 PortB.6,84,["To LCD"] ;@9600 To Lcd
pause 500

goto main
end

I will update my codes with the Gps, and post it here later...

regards,
mbox

mackrackit
- 7th November 2010, 10:43
That is more like it.
Start small and build your way up :)

mbox
- 7th November 2010, 14:20
I'm trying to add two numbers, 1st number is 140000 and the 2nd is 5377 which will give me 145377. And after getting the sum it will be divided by 60. x= (140000+ 537)/60, I think WORD can not hold much of the integers I need.
Ho do I do this in PBP?

ScaleRobotics
- 7th November 2010, 14:56
You are right, a word only goes up to 65535. If you have PBP v 2.5 or later, (and were using a PIC18 chip) you could select to use PBPL to compile, and define your large variables as LONG instead of WORD.

If you want to stick with the PIC16 series, you could use N-BIT math. http://www.picbasic.co.uk/forum/content.php?r=153-N-Bit_MATH

By the way, it looks like you are using PM as your assembler.



@ DEVICE HS_OSC

You probably need to use MPASM for N-Bit Math to work. For that, you define your configs like this:

@ __config _HS_OSC & _WDT_OFF & _LVP_OFF & _CP_OFFBut you must comment out the configs in you C:/PBP/16F877A.INC file.

See : http://www.picbasic.co.uk/forum/content.php?r=157-Presetting-Configuration-Fuses-%28PIC-Defines%29-into-your-Program

mbox
- 8th November 2010, 00:46
Hi scalerobotics, I got my setup using Mpasm, and trying to figure out how Darrel's N-Bit_Math works, I need a sample to study its output. Try to use wozzy's code in pic16f877A
PRECISION CON 8 SYSTEM ' 8 bytes = 64-bit
INCLUDE "N-Bit_Math.pbp" ' Include Alexander Avtanski's Multibyte Arithmetic
' Assembly Library Wrapped for PBP by Darryl Taylor
' Version:1.3 Beta (1/7/2010)
;@ DEVICE HS_OSC
@ __config _HS_OSC & _WDT_OFF & _LVP_OFF & _CP_OFF
DEFINE OSC 20 ' 20 MHz Crystal Oscillator

DEFINE DEBUG_REG PORTC ' PORT C6
DEFINE DEBUG_BIT 6 ' PORT C6
DEFINE DEBUG_BAUD 57600 ' BAUD 57600
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true


I VAR BYTE

AA64 VAR BYTE[PRECISION]
BB64 VAR BYTE[PRECISION]
CC64 VAR BYTE[PRECISION]
DD64 VAR BYTE[PRECISION]

XX64 VAR BYTE[PRECISION]
YY64 VAR BYTE[PRECISION]
ZZ64 VAR BYTE[PRECISION]

PAUSE 500 : DEBUG " ",10,13,10,13 : PAUSE 500

MAIN:


@ MATH_MUL _AA64, _BB64, _XX64 ; @ MATH_MUL _A, _B, _Res ; Res = A / B - Remainder in REG_Z
@ MATH_DIV _CC64, _DD64, _YY64 ; @ MATH_DIV _A, _B, _Res ; Res = A / B - Remainder in REG_Z
@ MATH_DIV _DD64, _CC64, _ZZ64 ; @ MATH_DIV _A, _B, _Res ; Res = A / B - Remainder in REG_Z

DEBUG "BYTE ORDER BYTE[7],BYTE[6],BYTE[5],BYTE[4],BYTE[3],BYTE[2],BYTE[1],BYTE[0]",10,13,10,13
DEBUG "AA64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 AA64[I] : NEXT I : DEBUG 10,13
DEBUG "BB64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 BB64[I] : NEXT I : DEBUG 10,13
DEBUG "CC64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 CC64[I] : NEXT I : DEBUG 10,13
DEBUG "DD64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 DD64[I] : NEXT I : DEBUG 10,13
DEBUG "XX64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 XX64[I] : NEXT I : DEBUG 10,13
DEBUG "YY64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 YY64[I] : NEXT I : DEBUG 10,13
DEBUG "ZZ64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 ZZ64[I] : NEXT I : DEBUG 10,13
DEBUG "REG_Z = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 REG_Z[I] : NEXT I : DEBUG 10,13
DEBUG 10,13,10,13,10,13,10,13
PAUSE 10000
GOTO MAIN

END
I don't have any display on the hyper terminal window, My first time to encounter DEBUG command, but I think its similar to Serout2, is not it?

regards,
mbox

mackrackit
- 8th November 2010, 00:54
I'm trying to add two numbers, 1st number is 140000 and the 2nd is 5377 which will give me 145377. And after getting the sum it will be divided by 60. x= (140000+ 537)/60, I think WORD can not hold much of the integers I need.
Ho do I do this in PBP?
is this still part of the GPS project or something new?
Either way, where are the numbers coming from?

mbox
- 8th November 2010, 01:41
Yes it's part of the GPS. Google map can interpret this "11 14.5377,125 00.3560". But for my Mobile map application it can not, it reads this format "11.242295, 125.005933", I will explain my alternative solution only for th the latitude part using data "$GPRMC,115209.200,A,1114.5377,N,12500.3439,E,0.02, 296.54,021110,,,A*65", I extract data to this format "Deg 11 Min 14 Sec 5377". Then I need 14 and 5377 to be this 145377 format (my alternative solution is to 14x10000+5377) then divide it by 60 which will give me 2422.95. I need to make it whole number so 2422.95 x 100 = 242295. Then format the data to this deg 11.242295 ans send it to PortC.6, 11 is the degree and add a "." in between. Any alternative solution would be nice.

regards,
mbox

mackrackit
- 8th November 2010, 06:05
Not quite the accuracy you want but it is close. Maybe someone else can get it closer.
This returns 2422.


K CON 10000
MINS VAR BYTE
SECS VAR WORD
MINS = 14
SECS = 5377
Y VAR WORD
Z VAR WORD 'DUMMY VAR
Z1 VAR WORD 'DUMMY VAR

START:
SECS = SECS / 10
Z = (MINS * K)
Z1 = DIV32 10
Y = Z1 + SECS
Z = (Y / 6)
LCDOUT $FE,1,"Z= ",DEC Z
END

ScaleRobotics
- 8th November 2010, 06:42
Hey Mbox,

I think you are close, but your degrees calculation is a little off (if I am right about you converting minutes and seconds to degrees). I know a short cut, if you can live without decimal seconds.

Say you want to convert 11 deg 14 min and 53.77 seconds to degrees. If you can live without decimal seconds, we have 11 deg 14 min and 54 seconds. To convert to degrees.degrees:

to convert minutes to degrees

(14 * 500)/3 = 2333 (really .2333 degrees)

and now convert seconds

(54 * 50)/18 = 150 (really .015 degrees)

2333
+150
=2483

or 11.2483 degrees. This result fares well with http://www.satsig.net/degrees-minutes-seconds-calculator.htm , which says the result should be 11.24827 using the seconds decimals.

So with two variables you could store the result. lon_hi would = 11 and lon_low would = 2483. If you need to turn this out the serial port, your code can also place the decimal point between them.

mbox
- 8th November 2010, 23:02
Hi everyone, thanks for the inputs appreciated it very much...I will make tests and see the results regarding the calculation part. So far I made 30 queries by sms from the device and works okay without yet the format and calculation I desire in the mcu, right now the calculation are done and formatting within the mobile codings. I'll be away for 3 days, hopefully by end of the week I can smoothen it more.

Technos: PBP 2.50 and Python for the mobile app.

regards,
mbox