xnihilo
- 25th November 2009, 07:51
Hi Guys,
I've wanted for some time now to build a simple application where a GPS mouse would be connected to a PIC16F684 to collect $GPRMC string and display some basic information on an LCD screen and when speed exceeds a set value, a buzzer would beep.
Using several sources I found on the net, I tried to assemble the simple circuit below and wrote/compiled some PBP code but it does not seem to be working and I'm wondering what's wrong.
The link to the Rikaline X5 GPS is here (it has RS232 and TTL I/Os):
http://www.tango-lasergame.be/GPS-6010-X5--Manual-E.pdf
I'm using a 2*16 characters LCD (which displays what it should display BTW, so the wiring is fine). I'm using a pic16f684 where A0 is connected to GPS TX (at TTL level). A1 is the piezzo buzzer. C0 to C3 are the LCD datalines 4 to 7 (4 bits mode), C4 is R/S with external 10K WPU, C5 is the Enable pin.
I connected the GPS and the application circuit to the same 5v source (9v power supply going through a LDO voltage regulator).
The pic pin 1 and pin 14 are linked using a 0.1Uf ceramic disc and 10Uf electrolytic capacitors for filtering.
When I run the program, it displays the right stuff on the LCD until it reaches the "GPS" label and stalls displaying "Serin start", which means is gets stuck in the SERIN2 instruction. It should either finish the instruction while all the $GPRMC data are collected or jump to the timeout subroutine. In both cases the LCD display should change but id does not, which means there is probably a problem with serin.
It should process the SERIN2 instruction even when there is no GPS, so for now I don't care if the GPS is not working.
The PIC16F684 has no hardware EUSART and I beleive the SERIN2 is a kind of bit banging instruction that can be used on any I/O pin. A0 is a TTL level I/O pin by the way.
Could anyone have a look at the code and check what may be wrong. It is probably obvious but I don't get it.
Thanks for any help.
Regards
'based on: http://list.picbasic.com/forum/messages/6851/7091.html?1080565370
and other sources on the net
@ device pic16F684, intrc_osc_noclkout, BOD_OFF, PWRT_OFF, wdt_off, mclr_off, protect_off
'quid freq horloge requise?
DEFINE OSC 8 'set OSC value to 8MHz for instructions PAUSE, PAUSEus and SOUND (instead of default 4MHz)
DEFINE LCD_DREG PORTC 'data port out is portC
DEFINE LCD_DBIT 0 'data on portC0-portC3
DEFINE LCD_RSREG PORTC 'r/s is on portC.4, with 10K WPU
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTC 'enable is on portC.5
DEFINE LCD_EBIT 5
DEFINE LCD_BITS 4 '4bits data bus
DEFINE LCD_LINES 2 '2lines display
DEFINE LCD_COMMANDUS 2000 '2ms cmd delay
DEFINE LCD_DATAUS 50 '50us data delay
INTCON = 0 'disable interrupts and clear int flags
OSCCON = %01110001 'int osc, hs, 8mhz
CMCON0 = %00000111
ANSEL = %00000000
OPTION_REG = %11111111
'alias in SERIN2
GPSin VAR PORTA.0 'A0 has TTL levels
TRISA = %000001
TRISC = 0
PORTA = %000001 'A0 is used for gps input, SERIN2 bitbanging (software eusart)
PORTC = 0
WPUA = 0
'Variables / Constants for GPS in SERIN2:
timeout CON 3000
'MODE: http://www.melabs.com/resources/pbpmanual/ser2modes.htm
mode CON 24764 '16572 + 8192 (bit 13) = 4800 Driven Inverted Even
hh VAR BYTE 'hours
mm VAR BYTE 'minutes
'knots VAR WORD 'speed in knots (units)
'knotsten VAR BYTE 'speed in knots (tens)
course VAR WORD 'heading
latdeg VAR BYTE 'degrees latitude
latmin VAR BYTE 'minutes latitude
NS VAR BYTE 'north or south
londeg VAR BYTE 'degrees longitude
lonmin VAR BYTE 'minutes longitude
EO VAR BYTE 'east or west
j VAR BYTE 'day
m VAR BYTE 'month
a VAR BYTE 'year
fix VAR WORD 'GPS fix
'for kmph calculation
Speed Var byte[5]
SpeedKnots VAR WORD
SpeedKm VAR WORD
Temp VAR BYTE
Dummy VAR WORD
i var byte
'programming custom characters
LCDOUT $FE,$40,$00,$0A,$0A,$00,$11,$0E,$00,$00 ' Cust Char #0: happy smiley
LCDOUT $FE,$48,$0E,$15,$1B,$19,$1B,$15,$0E,$00 ' Cust Char #1: copyright
LCDOUT $FE,$50,$0E,$0E,$1F,$0E,$04,$00,$1F,$00 ' Cust Char #2: press
LCDOUT $FE,$58,$0A,$1F,$1F,$1F,$0E,$04,$00,$00 ' Cust Char #3: heart
LCDOUT $FE,$60,$03,$05,$19,$19,$19,$19,$05,$03 ' Cust Char #4: speaker
LCDOUT $FE,$68,$00,$00,$04,$0E,$0E,$0E,$0E,$00 ' Cust Char #5: bullet
LCDOUT $FE,$70,$1F,$11,$11,$11,$11,$11,$11,$1F ' Cust Char #6: empty square
LCDOUT $FE,$78,$04,$0E,$1F,$0E,$0E,$00,$1F,$00 ' Cust Char #7: release
for i = 0 to 10
HIGH PORTA.1
pause 300
LOW PORTA.1
PAUSE 300
NEXT i
'TEST block
'display a sample of the custom charas
LCDOUT $fe,1,"new charas: "
LCDOUT $fe,$c0,0,1,2,3,4,5,6,7 'will write the "speaker" symbol.
PAUSE 4000
'--------------------------------------------------------------------------------------------------------------------------------------------
'PAUSE 3000 'let the power level stabilize
LCDOUT $fe,1,"GPS display"
PAUSE 2000
LCDOUT $fe,1,"24.11.2009"
PAUSE 2000
'************************************************* ******************************
'************************************************* ******************************
'eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,1 91194,020.3,E*68
'225446 Time of fix 22:54:46 UTC A Navigation receiver warning A = Valid position, V = Warning 4916.45,N Latitude 49 deg. 16.45 min. North 12311.12,W Longitude 123 deg. 11.12 min. West 000.5 Speed over ground, Knots 054.7 Course Made Good, degrees true 191194 UTC Date of fix, 19 November 1994 020.3,E Magnetic variation, 20.3 deg. East *68 mandatory checksum
'1 Knot = 1.852 Kilometers per Hour
'45.12 Knots = 83.56224 Kilometers per Hour
GPS:
LCDOUT $fe,1,"in GPS"
PAUSE 2000
LCDOUT $fe,1,"Serin start"
PAUSE 2000
SerIn2 PORTA.0,mode,Timeout,nogps,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait(","),EO,wait(","),Speed[0],Speed[1],Speed[2],Speed[3],Speed[4],wait(","),DEC3 course,wait(","),DEC2 j,DEC2 m,DEC2 a]
IF (fix == "V") Then
LCDOut $FE, 1 'Clear Screen
LCDOut "No Fix"
Pause 1000
GOTO GPS
ENDIF
LCDOUT $fe,1,"Serin end"
PAUSE 2000
'Convert from ASCII to normal numbers times 10
SpeedKnots = 0
Dummy = 1000
Speed[3] = Speed[4] '"skip" the decimal
For Temp = 0 TO 3
Speed[Temp] = Speed[Temp] - "0" 'Remove the ASCII portion = 48
SpeedKnots = SpeedKnots + (Speed[Temp] * Dummy)
Dummy = Dummy / 10
NEXT
'Use theese two lines if you want a value that is rounded correctly.
'There will however be a limit to your speed, it must be <= 353.7kn (655.3km/h)
SpeedKm = (SpeedKnots*18) + (SpeedKnots ** 34260) 'Multiply with 18.5227661
SpeedKm = (SpeedKm + 5) /10 '5 is for rounding
LCDOut "SPEED :",dec4 SpeedKm/10,".",DEC1 SpeedKm,"km/h"
LCDOut $fe,$c0
LCDOut "HEADING:",DEC3 course," DEG"
Pause 3000
LCDOut $FE, 1 'Clear Screen
LCDOut "LAT:",DEC2 latdeg,",",DEC2 latmin," ",NS
LCDOut $fe,$c0
LCDOut "LON:",DEC2 londeg,",",DEC2 lonmin," ",EO
Pause 3000
GoTo GPS
Nogps:
LCDOut $FE, 1 'Clear Screen
LCDOut "NO GPS"
Pause 1000
GOTO GPS
I've wanted for some time now to build a simple application where a GPS mouse would be connected to a PIC16F684 to collect $GPRMC string and display some basic information on an LCD screen and when speed exceeds a set value, a buzzer would beep.
Using several sources I found on the net, I tried to assemble the simple circuit below and wrote/compiled some PBP code but it does not seem to be working and I'm wondering what's wrong.
The link to the Rikaline X5 GPS is here (it has RS232 and TTL I/Os):
http://www.tango-lasergame.be/GPS-6010-X5--Manual-E.pdf
I'm using a 2*16 characters LCD (which displays what it should display BTW, so the wiring is fine). I'm using a pic16f684 where A0 is connected to GPS TX (at TTL level). A1 is the piezzo buzzer. C0 to C3 are the LCD datalines 4 to 7 (4 bits mode), C4 is R/S with external 10K WPU, C5 is the Enable pin.
I connected the GPS and the application circuit to the same 5v source (9v power supply going through a LDO voltage regulator).
The pic pin 1 and pin 14 are linked using a 0.1Uf ceramic disc and 10Uf electrolytic capacitors for filtering.
When I run the program, it displays the right stuff on the LCD until it reaches the "GPS" label and stalls displaying "Serin start", which means is gets stuck in the SERIN2 instruction. It should either finish the instruction while all the $GPRMC data are collected or jump to the timeout subroutine. In both cases the LCD display should change but id does not, which means there is probably a problem with serin.
It should process the SERIN2 instruction even when there is no GPS, so for now I don't care if the GPS is not working.
The PIC16F684 has no hardware EUSART and I beleive the SERIN2 is a kind of bit banging instruction that can be used on any I/O pin. A0 is a TTL level I/O pin by the way.
Could anyone have a look at the code and check what may be wrong. It is probably obvious but I don't get it.
Thanks for any help.
Regards
'based on: http://list.picbasic.com/forum/messages/6851/7091.html?1080565370
and other sources on the net
@ device pic16F684, intrc_osc_noclkout, BOD_OFF, PWRT_OFF, wdt_off, mclr_off, protect_off
'quid freq horloge requise?
DEFINE OSC 8 'set OSC value to 8MHz for instructions PAUSE, PAUSEus and SOUND (instead of default 4MHz)
DEFINE LCD_DREG PORTC 'data port out is portC
DEFINE LCD_DBIT 0 'data on portC0-portC3
DEFINE LCD_RSREG PORTC 'r/s is on portC.4, with 10K WPU
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTC 'enable is on portC.5
DEFINE LCD_EBIT 5
DEFINE LCD_BITS 4 '4bits data bus
DEFINE LCD_LINES 2 '2lines display
DEFINE LCD_COMMANDUS 2000 '2ms cmd delay
DEFINE LCD_DATAUS 50 '50us data delay
INTCON = 0 'disable interrupts and clear int flags
OSCCON = %01110001 'int osc, hs, 8mhz
CMCON0 = %00000111
ANSEL = %00000000
OPTION_REG = %11111111
'alias in SERIN2
GPSin VAR PORTA.0 'A0 has TTL levels
TRISA = %000001
TRISC = 0
PORTA = %000001 'A0 is used for gps input, SERIN2 bitbanging (software eusart)
PORTC = 0
WPUA = 0
'Variables / Constants for GPS in SERIN2:
timeout CON 3000
'MODE: http://www.melabs.com/resources/pbpmanual/ser2modes.htm
mode CON 24764 '16572 + 8192 (bit 13) = 4800 Driven Inverted Even
hh VAR BYTE 'hours
mm VAR BYTE 'minutes
'knots VAR WORD 'speed in knots (units)
'knotsten VAR BYTE 'speed in knots (tens)
course VAR WORD 'heading
latdeg VAR BYTE 'degrees latitude
latmin VAR BYTE 'minutes latitude
NS VAR BYTE 'north or south
londeg VAR BYTE 'degrees longitude
lonmin VAR BYTE 'minutes longitude
EO VAR BYTE 'east or west
j VAR BYTE 'day
m VAR BYTE 'month
a VAR BYTE 'year
fix VAR WORD 'GPS fix
'for kmph calculation
Speed Var byte[5]
SpeedKnots VAR WORD
SpeedKm VAR WORD
Temp VAR BYTE
Dummy VAR WORD
i var byte
'programming custom characters
LCDOUT $FE,$40,$00,$0A,$0A,$00,$11,$0E,$00,$00 ' Cust Char #0: happy smiley
LCDOUT $FE,$48,$0E,$15,$1B,$19,$1B,$15,$0E,$00 ' Cust Char #1: copyright
LCDOUT $FE,$50,$0E,$0E,$1F,$0E,$04,$00,$1F,$00 ' Cust Char #2: press
LCDOUT $FE,$58,$0A,$1F,$1F,$1F,$0E,$04,$00,$00 ' Cust Char #3: heart
LCDOUT $FE,$60,$03,$05,$19,$19,$19,$19,$05,$03 ' Cust Char #4: speaker
LCDOUT $FE,$68,$00,$00,$04,$0E,$0E,$0E,$0E,$00 ' Cust Char #5: bullet
LCDOUT $FE,$70,$1F,$11,$11,$11,$11,$11,$11,$1F ' Cust Char #6: empty square
LCDOUT $FE,$78,$04,$0E,$1F,$0E,$0E,$00,$1F,$00 ' Cust Char #7: release
for i = 0 to 10
HIGH PORTA.1
pause 300
LOW PORTA.1
PAUSE 300
NEXT i
'TEST block
'display a sample of the custom charas
LCDOUT $fe,1,"new charas: "
LCDOUT $fe,$c0,0,1,2,3,4,5,6,7 'will write the "speaker" symbol.
PAUSE 4000
'--------------------------------------------------------------------------------------------------------------------------------------------
'PAUSE 3000 'let the power level stabilize
LCDOUT $fe,1,"GPS display"
PAUSE 2000
LCDOUT $fe,1,"24.11.2009"
PAUSE 2000
'************************************************* ******************************
'************************************************* ******************************
'eg2. $GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,1 91194,020.3,E*68
'225446 Time of fix 22:54:46 UTC A Navigation receiver warning A = Valid position, V = Warning 4916.45,N Latitude 49 deg. 16.45 min. North 12311.12,W Longitude 123 deg. 11.12 min. West 000.5 Speed over ground, Knots 054.7 Course Made Good, degrees true 191194 UTC Date of fix, 19 November 1994 020.3,E Magnetic variation, 20.3 deg. East *68 mandatory checksum
'1 Knot = 1.852 Kilometers per Hour
'45.12 Knots = 83.56224 Kilometers per Hour
GPS:
LCDOUT $fe,1,"in GPS"
PAUSE 2000
LCDOUT $fe,1,"Serin start"
PAUSE 2000
SerIn2 PORTA.0,mode,Timeout,nogps,[wait("$GPRMC"),wait(","),DEC2 hh,DEC2 mm,wait(","),fix,wait(","),DEC2 latdeg,DEC2 latmin,wait(","),NS,wait(","),DEC3 londeg,DEC2 lonmin,wait(","),EO,wait(","),Speed[0],Speed[1],Speed[2],Speed[3],Speed[4],wait(","),DEC3 course,wait(","),DEC2 j,DEC2 m,DEC2 a]
IF (fix == "V") Then
LCDOut $FE, 1 'Clear Screen
LCDOut "No Fix"
Pause 1000
GOTO GPS
ENDIF
LCDOUT $fe,1,"Serin end"
PAUSE 2000
'Convert from ASCII to normal numbers times 10
SpeedKnots = 0
Dummy = 1000
Speed[3] = Speed[4] '"skip" the decimal
For Temp = 0 TO 3
Speed[Temp] = Speed[Temp] - "0" 'Remove the ASCII portion = 48
SpeedKnots = SpeedKnots + (Speed[Temp] * Dummy)
Dummy = Dummy / 10
NEXT
'Use theese two lines if you want a value that is rounded correctly.
'There will however be a limit to your speed, it must be <= 353.7kn (655.3km/h)
SpeedKm = (SpeedKnots*18) + (SpeedKnots ** 34260) 'Multiply with 18.5227661
SpeedKm = (SpeedKm + 5) /10 '5 is for rounding
LCDOut "SPEED :",dec4 SpeedKm/10,".",DEC1 SpeedKm,"km/h"
LCDOut $fe,$c0
LCDOut "HEADING:",DEC3 course," DEG"
Pause 3000
LCDOut $FE, 1 'Clear Screen
LCDOut "LAT:",DEC2 latdeg,",",DEC2 latmin," ",NS
LCDOut $fe,$c0
LCDOut "LON:",DEC2 londeg,",",DEC2 lonmin," ",EO
Pause 3000
GoTo GPS
Nogps:
LCDOut $FE, 1 'Clear Screen
LCDOut "NO GPS"
Pause 1000
GOTO GPS