Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 04:26 07 Jul 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Day of week from GPS time GMT/BST

     Page 1 of 2    
Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 04:28am 22 Feb 2016
Copy link to clipboard 
Print this post

As some of you will know I'm "VERY" new to the Micromite and at the moment I'm in a heavy learning curve.

I'm trying to figure out how to get the day of the week from GPS either $GPRMC or $GPZDA

Getting the gps working wasn't too much of a problem, there are several code examples online including Geoff's code here

The problem I'm having is most of the code I can find for the Micromite is for people in Australia, and they use DST which is different from our GMT here in the UK

What I need if anyone already has it is a way to get the day of the week from a gps but allowing for GMT and BST

I know the GPS transmits in UTC which is actually GMT so that part is dead handy.

Using Geoff's code as an example,
[code]' Configuration constants
TimeZone = 8.0 ' hours from GMT (+ or -)

UseDST = 0 ' set to 1 to enable daylight saving time (DST) adjust
dms = 10 ' the month that DST starts
dhs = 2 ' the hour that DST starts
dme = 4 ' the month that DST ends
dhe = 2 ' the hour that DST ends
[/code]

Changing the timezone to 0 is dead simple, but I cannot work out how to change the start / end times for BST
Australia uses the 1st Sunday in October to put the clocks forward 1 hour
Australia uses the 2st Sunday in April to put the clocks back 1 hour (both use 2am to do this)

The UK uses the 4th (last) Sunday in March to put the clocks forward 1 hour at 2AM
The UK uses the 4th (last) Sunday in October to put the clocks back one hour at 2AM

Providing Geoff has no objections to me using his code in my weather station (or parts of it) Using his code as the example, how would I state the start/end of BST?

Sorry this is probably such a simple question for most of you.
Edited by lew247 2016-02-23
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1573
Posted: 05:23am 22 Feb 2016
Copy link to clipboard 
Print this post

Hi Lewis,

maybe this can help you:
http://www.cpearson.com/Excel/TimeZoneAndDaylightTime.aspx

There is a (VB)Basic file for download.

(I hate DST!)
EDIT: The BST reminds me somehow of the Indiana Pi Bill.

Regards
MichaelEdited by twofingers 2016-02-23
causality ≠ correlation ≠ coincidence
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 08:46am 22 Feb 2016
Copy link to clipboard 
Print this post

Hi Lewis,

Geoff kindly sent me the 'formula' for BST for us folk here in the UK. I'm busy at the moment but will post it later. . . .

WW
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 10:33am 22 Feb 2016
Copy link to clipboard 
Print this post

Thanks WW
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 11:39am 22 Feb 2016
Copy link to clipboard 
Print this post

Hi Lewis,

Have extracted the code from a much larger program - hopefully it is all there!
Take a look at the last function; this is the one Geoff modified for me (but can't remember if more mods elsewhere.

The code removed was for driving a large LED Matrix display (SPI) so if you find any SPI code left in by accident then it can be ignored.

Hope the following makes sense . . . .

WW



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' GPS CLOCK
' WhiteWizzard July 2014
' Based on Geoff Graham's code, March 2014
'
' Demonstration of the MAX7219 SPI driven
' This program will get the time from a U-Blox 7 GPS module, add the timezone
' and daylight saving then display on a 40x8 LED Matrix
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'----------------------MAIN----------------------------



' Configuration constants
TimeZone = 0.0 ' hours from GMT (+ or -)

UseDST = 1 ' set to 1 to enable daylight saving time (DST) adjust, 0 to disable
dms = 3 ' the month that DST starts
dhs = 2 ' the hour that DST starts
dme = 10 ' the month that DST ends
dhe = 2 ' the hour that DST ends

' global arrays
DIM md(12), arg$(20)
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
FOR i = 1 TO 12: READ md(i): NEXT i

OPEN "COM2:9600" AS #1 ' open the GPS serial interface

' this is the main program loop, it never exits
DO
TIMER=0
SF=0
GetRMC:
arg$(0)="": arg$(2)=""
GetGPSRecord ' get a GPS record
if timer>550 then goto ContMain
if arg$(0)<>"GPRMC" then goto GetRMC:
IF arg$(2) = "A" THEN ' we only want the RMC record. "A" means valid record
'? "Fix"
SF=1
' the GPS has the valid time
' first extract the elements of the date/time from the GPS record
year = VAL(RIGHT$(arg$(9), 2)) ' extract the date
month = VAL(MID$(arg$(9), 3, 2))
day = VAL(LEFT$(arg$(9), 2))
hour = VAL(LEFT$(arg$(1), 2)) ' extract the time
min = VAL(MID$(arg$(1), 3, 2))
sec = VAL(MID$(arg$(1), 5, 2))

' convert the time to minutes since midnight 1st Jan 2014
' then add/subtract the timezone and if required add daylight saving
' this calculation takes just 15mS at 40MHz
mins = GetMins(year, month, day, hour, min)
mins = mins + TimeZone * 60 ' adjust for the timezone
IF UseDST THEN ' if we observe daylight saving
IF mins > GetDST(year, dms, dhs) AND mins < GetDST(year, dme, dhe) THEN
mins = mins + 60 ' adjust for AWST DST
ENDIF
ENDIF

' because we will display the time at the start of the next second
' we have to add 1 second to th e current time
sec = sec '+ 1
IF sec >= 60 THEN sec = 0 : mins = mins + 1
' finally convert the minutes back into the current date/time
Time$ = GetTime$(mins)
'Line2$ = GetDate$(mins)

else
if Timer>200 then
SF=0
goto ContMain
endif
goto GetRMC
ENDIF
ContMain:
LoadTime
DispData

LOOP


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutine to get a GPS record into the array arg$()
SUB GetGPSRecord
arg$(0)="": arg$(2)=""
SF=0
timer=0
do
if INPUT$(1, 1) = "$" then exit do ' wait for the start
if Timer>600 then exit sub
loop

Timer = 0
FOR i = 0 TO 20
arg$(i) = "" ' clear ready for data
DO ' loops until a specific exit
x$ = INPUT$(1, 1) ' get the character
IF x$ = "," THEN EXIT DO ' new data item, new field
IF x$ = "*" THEN EXIT SUB ' end of record, so return with it
IF asc(x$)>31 AND ASC(x$)<127 then arg$(i) = arg$(i) + x$ ' add to the data
if Timer>600 then exit sub
LOOP ' keep going
NEXT i ' increment the field
END SUB


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' calculate the minutes since midnight 1st Jan 2014
FUNCTION GetMins(yr, mth, day, hr, min)
GetMins = (yr - 14) * (365 * 24 * 60) + ((yr - 13) \ 4) * (24 * 60)
GetMins = GetMins + (md(mth) * (24 * 60))
GetMins = GetMins + ((day - 1) * (24 * 60))
GetMins = GetMins + (hr * 60)
GetMins = GetMins + min
IF (yr - 16) MOD 4 = 0 AND mth > 2 THEN GetMins = GetMins + (24 * 60)
END FUNCTION


' convert minutes back into the time (as a string)
FUNCTION GetTime$(minutes)
LOCAL hr, min, am$
am$ = "AM"
hr = (minutes \ 60) MOD 24
IF hr > 12 THEN am$ = "PM" : hr = hr - 12
IF hr = 0 THEN hr = 12
min = minutes MOD 60
GetTime$ = STR$(hr) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$
END FUNCTION


' convert minutes back into the date (as a string)
FUNCTION GetDate$(minutes)
LOCAL yr, mth, day, mths$, days$
mths$ = " JanFebMarAprMayJunJulAugSepOctNovDec"
days$ = "SunMonTueWedThuFriSat"
FOR yr = 14 TO 99
IF minutes < GetMins(yr + 1, 1, 1, 0, 0) THEN EXIT FOR
NEXT yr
FOR mth = 1 TO 12
IF minutes < GetMins(yr, mth, 1, 0, 0) THEN EXIT FOR
NEXT mth
mth = mth - 1
day = ((minutes - GetMins(yr, mth, 1, 0, 0)) \ (24 * 60)) + 1
GetDate$ = MID$(days$, ((((minutes \ (24 * 60)) + 3) MOD 7) * 3) + 1,3)+" "
GetDate$ = GetDate$ + RIGHT$(" " + STR$(day), 2)
GetDate$ = GetDate$ + "-" + MID$(mths$,mth*3,3) + "-" + STR$(yr + 2000)
END FUNCTION


' get the minutes that DST will start or end in a month
' modified for UK DST which starts on the LAST Sunday of the month
FUNCTION GetDST(yr, mth, hr)
LOCAL d, m, n
m = GetMins(yr, mth, 1, hr, 0)
d = ((m \ (24 * 60)) + 3) MOD 7
m = m + (((7 - d) MOD 7) * 24 * 60)
n = GetMins(yr, mth + 1, 1, 0, 0)
do while m + (7 * 24 * 60) < n
m = m + (7 * 24 * 60)
loop
GetDST = m
END FUNCTION
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 11:31pm 22 Feb 2016
Copy link to clipboard 
Print this post

Thanks WW that's excellent
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 11:40pm 22 Feb 2016
Copy link to clipboard 
Print this post

  lew247 said   Thanks WW that's excellent


The 'Thanks' should really go to Geoff!

Anyway, I hope the code gets you sorted. Do update when you're able to . . . .
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 12:09am 29 Feb 2016
Copy link to clipboard 
Print this post

WhiteWizzard - or anyone really

Any idea how to get rid of the AM/PM indicators and have 24 hour time?

I tried just deleting all references to am$ but it didn;t work, it just froze the program

I'm testing each section of the weather station one bit at a time till I've got all sections working, then I'll "combine" the code.

Also anyone know how to instead of the clock running "all the time" to get it to run say once every hour at say 5 minutes past the hour?

I'll be using it to update the clock in the weather station inside the house and don't need it running all the time, just to update it now and then

Lew

EDIT**** I've just noticed it's an hour ahead any ideas why?
It's showing 11:17 now and it's actually 10:17


[code]
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'GPS CLOCK
' Geoff Graham, March 2014
'"Slightly" modified by lew247 February 2016
'Thanks to WhiteWizzard for his help with this as well
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

' Configuration constants
TimeZone = 0.0 ' hours from GMT (+ or -)

UseDST = 1 ' set to 1 to enable daylight saving time (DST) adjust
dms = 3 ' the month that DST starts
dhs = 2 ' the hour that DST starts
dme = 10 ' the month that DST ends
dhe = 2 ' the hour that DST ends

' global arrays
DIM md(12), arg$(20)
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
FOR i = 1 TO 12: READ md(i): NEXT i

OPEN "COM2:9600" AS #1 ' open the GPS serial interface

' this is the main program loop, it never exits
DO
KeepSearching:
DO
GetGPSRecord ' get a GPS record
LOOP UNTIL arg$(0) = "GPRMC" ' we only want the RMC record
IF arg$(2) <> "A" THEN ' "A" means valid record
print "Searching", "For Satellites"
GOTO KeepSearching ' go back and keep looking
ENDIF

' the GPS has the valid time
' first extract the elements of the date/time from the GPS record
year = VAL(RIGHT$(arg$(9), 2)) ' extract the date
month = VAL(MID$(arg$(9), 3, 2))
day = VAL(LEFT$(arg$(9), 2))
hour = VAL(LEFT$(arg$(1), 2)) ' extract the time
min = VAL(MID$(arg$(1), 3, 2))
sec = VAL(MID$(arg$(1), 5, 2))

' convert the time to minutes since midnight 1st Jan 2014
' then add/subtract the timezone and if required add daylight saving
' this calculation takes just 15mS at 40MHz
mins = GetMins(year, month, day, hour, min)
mins = mins + TimeZone * 60 ' adjust for the timezone
IF UseDST THEN ' if we observe daylight saving
IF mins < GetDST(year, dme, dhe) OR mins > GetDST(year, dms, dhs) THEN
mins = mins + 60 ' adjust for AWST DST
ENDIF
ENDIF

' because we will display the time at the start of the next second
' we have to add 1 second to the current time
sec = sec + 1
IF sec >= 60 THEN sec = 0 : mins = mins + 1

' finally convert the minutes back into the current date/time
Line1$ = GetDate$(mins)
Line2$ = GetTime$(mins)

' we now have the date/time for the next second ready for display
' we have to wait for the end of the data stream from the GPS
' then we wait for the start of the next second and only then update the LCD
DO : LOOP WHILE TIMER < 950 ' wait for the data to finish
DO : LOOP WHILE INPUT$(200, #1) <> "" ' clear the input buffer
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for a new second to start
TIMER = 0

' display the date and time for this second
print Line1$ " ", Line2$ " "
LOOP


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutine to get a GPS record into the array arg$()
SUB GetGPSRecord
DO
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for the start
FOR i = 0 TO 20
arg$(i) = "" ' clear ready for data
DO ' loops until a specific exit
x$ = INPUT$(1, #1) ' get the character
IF x$ = "," THEN EXIT DO ' new data item, new field
IF x$ = "*" THEN EXIT SUB ' end of record, so return with it
arg$(i) = arg$(i) + x$ ' add to the data
LOOP ' keep going
NEXT i ' increment the field
LOOP
END SUB


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' calculate the minutes since midnight 1st Jan 2014
FUNCTION GetMins(yr, mth, day, hr, min)
GetMins = (yr - 14) * (365 * 24 * 60) + ((yr - 13) \ 4) * (24 * 60)
GetMins = GetMins + (md(mth) * (24 * 60))
GetMins = GetMins + ((day - 1) * (24 * 60))
GetMins = GetMins + (hr * 60)
GetMins = GetMins + min
IF (yr - 16) MOD 4 = 0 AND mth > 2 THEN GetMins = GetMins + (24 * 60)
END FUNCTION


' convert minutes back into the time (as a string)
FUNCTION GetTime$(minutes)
LOCAL hr, min, am$
am$ = "AM"
hr = (minutes \ 60) MOD 24
IF hr >= 12 THEN am$ = “PM”
IF hr > 12 THEN hr = hr – 12
IF hr = 0 THEN hr = 12
min = minutes MOD 60
GetTime$ = STR$(hr) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$
END FUNCTION


' convert minutes back into the date (as a string)
FUNCTION GetDate$(minutes)
LOCAL yr, mth, day, mths$, days$
mths$ = " JanFebMarAprMayJunJulAugSepOctNovDec"
days$ = "SunMonTueWedThuFriSat"
FOR yr = 14 TO 99
IF minutes < GetMins(yr + 1, 1, 1, 0, 0) THEN EXIT FOR
NEXT yr
FOR mth = 1 TO 12
IF minutes < GetMins(yr, mth, 1, 0, 0) THEN EXIT FOR
NEXT mth
mth = mth - 1
day = ((minutes - GetMins(yr, mth, 1, 0, 0)) \ (24 * 60)) + 1
GetDate$ = MID$(days$, ((((minutes \ (24 * 60)) + 3) MOD 7) * 3) + 1,3)+" "
GetDate$ = GetDate$ + RIGHT$(" " + STR$(day), 2)
GetDate$ = GetDate$ + "-" + MID$(mths$,mth*3,3) + "-" + STR$(yr + 2000)
END FUNCTION


' get the minutes that DST will start or end in a month
' modified for UK DST which starts on the LAST Sunday of the month
FUNCTION GetDST(yr, mth, hr)
LOCAL d, m, n
m = GetMins(yr, mth, 1, hr, 0)
d = ((m \ (24 * 60)) + 3) MOD 7
m = m + (((7 - d) MOD 7) * 24 * 60)
n = GetMins(yr, mth + 1, 1, 0, 0)
do while m + (7 * 24 * 60) < n
m = m + (7 * 24 * 60)
loop
GetDST = m
END FUNCTION[/code]Edited by lew247 2016-03-01
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 12:27am 29 Feb 2016
Copy link to clipboard 
Print this post

For 24hr format you need to comment out three lines (shown in bold below) in the function GetTime$(minutes) as follows:

FUNCTION GetTime$(minutes)
LOCAL hr, min, am$
'am$ = "AM"
hr = (minutes \ 60) MOD 24
'IF hr >= 12 THEN am$ = “PM”
'IF hr > 12 THEN hr = hr – 12

IF hr = 0 THEN hr = 12
min = minutes MOD 60
GetTime$ = STR$(hr) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$
END FUNCTION


Obviously format any printing to omit the am$ - so in the above function, the last line needs to leave off the '+ am$' at the end!

Will look at your other points shortly . . .

WW
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 12:39am 29 Feb 2016
Copy link to clipboard 
Print this post

  lew247 said  Also anyone know how to instead of the clock running "all the time" to get it to run say once every hour at say 5 minutes past the hour?


I assume you mean get a 'GPS time' every hour?

In essence you convert the main Do...Loop into a SUB (i.e. take all the code between DO and LOOP and put it in a SUB).

Then set up a SETTICK period,target,[nbr] where target is the name of your SUB. Set period to 3,600,000 (number of milliSeconds in an hour).

Then at the end of your SUB, set MMBasics inbuilt Time$/Date$ to the GPS Time & Date.

In your main program where you need to show and/or update time/date, simply read the Time$ and Date$ values which MMBasic will roughly maintain.

There are other ways to do this, but this is one approach that is simple. Warning, you may need to use Watchdog to save the GPS loop getting 'stuck' when no signal. Also be careful not to update Time$ & Date$ with incorrect data - so some form of error checking is always good.

Hope this gives you some ideas . . .

WW
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 01:22am 29 Feb 2016
Copy link to clipboard 
Print this post

Thanks WW
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 10:00am 02 Mar 2016
Copy link to clipboard 
Print this post

  lew247 said   EDIT**** I've just noticed it's an hour ahead any ideas why?
It's showing 11:17 now and it's actually 10:17


SOLVED; at long last!

In the main DO...LOOP, about half way down you have:
If UseDST Then ‘if we observe daylight saving
If mins < GetDST(year, dme, dhe) OR mins > GetDST(year, dms, dhs) THEN
mins = mins + 60 ‘adjust for AWST DST
EndIf
EndIf


The OR test needs to be an AND test (checked against running code on my main GPS LED Matrix clock)

Let me know if this fixes things finally . . .

WW

EDIT: To clarify, you need:
If mins > GetDST(year, dms, dhs) AND mins < GetDST(year, dme, dhe) THEN
Edited by WhiteWizzard 2016-03-03
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 10:33am 02 Mar 2016
Copy link to clipboard 
Print this post

Thanks WW you're a star :)
 
jimbotron
Regular Member

Joined: 27/11/2013
Location: Australia
Posts: 50
Posted: 04:28pm 04 Mar 2016
Copy link to clipboard 
Print this post

Hi Guys,
An interesting observation.
The reason the OR had to replaced by an AND is due to the inversion of seasons.
This makes the AND logic work for the North and OR logic work for the south.

The below shows a truth table for each month. The inputs are the clauses for the start of DST and end of DST.
The way to make it work for both cases is to check if End of DST is greater than Star of DST then use the OR or AND logic accordingly.

South
JFMAMJJASOND
111000000000 End
000000000111 Start
------------ AND
000000000000 <= Incorrect

111000000000 End
000000000111 Start
------------ OR
111000000111 <= Correct

North
JFMAMJJASOND
111111111000 End
000111111111 Start
------------ AND
000111111000 <= Correct

111111111000 End
000111111111 Start
------------ OR
111111111111 <= Incorrect

 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 09:30am 19 Jun 2016
Copy link to clipboard 
Print this post

Back to this again- sorry

How can I get this to print the date/time etc every 10 seconds?

I THOUGHT [code]if secs mod 20 = 0 then
print Line1$ " ", Line2$ " " latitude "" ,(arg$(4))"",longitude "",(arg$(6))""
[/code] would do it
but it prints the info every second and not every 10 seconds like I'd like

[code]''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'GPS CLOCK
' Geoff Graham, March 2014
'"Very Slightly" modified by lew247 February 2016
'Thanks to WhiteWizzard for his help with this as well
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
SETPIN 23, DOUT 'GPS Power
PIN(23) = 1 'GPS Power OFF

' Configuration constants
TimeZone = 0.0 ' hours from GMT (+ or -)

UseDST = 1 ' set to 1 to enable daylight saving time (DST) adjust
dms = 3 ' the month that DST starts
dhs = 2 ' the hour that DST starts
dme = 10 ' the month that DST ends
dhe = 2 ' the hour that DST ends

' global arrays
DIM md(12), arg$(20)
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
FOR i = 1 TO 12: READ md(i): NEXT i

PIN(23) = 0 'GPS Power ON
OPEN "COM2:9600" AS #1 ' open the GPS serial interface

' this is the main program loop, it never exits
DO
KeepSearching:
DO
GetGPSRecord ' get a GPS record
LOOP UNTIL arg$(0) = "GPRMC" ' we only want the RMC record
IF arg$(2) <> "A" THEN ' "A" means valid record
print "Searching", " For Satellites"
GOTO KeepSearching ' go back and keep looking
ENDIF

' the GPS has the valid time
' first extract the elements of the date/time from the GPS record
year = VAL(RIGHT$(arg$(9), 2)) ' extract the date
month = VAL(MID$(arg$(9), 3, 2))
day = VAL(LEFT$(arg$(9), 2))
hour = VAL(LEFT$(arg$(1), 2)) ' extract the time
min = VAL(MID$(arg$(1), 3, 2))
sec = VAL(MID$(arg$(1), 5, 2))

' extract and format latitude (data element #3, ddmm.mmmm)

lat_deg$ = LEFT$(arg$(3), 2)
lat_min$ = MID$(arg$(3), 3, 2)
lat_sec$ = str$(cint(val(mid$(arg$(3), 5, 9)) * 60.0))
latitude = val(lat_deg$) + val(lat_min$) / 60.0 + val(lat_sec$) / 3600.0

' extract and format longitude (data element #5, dddmm.mmmm)
long_deg$ = LEFT$(arg$(5), 3)
long_min$ = MID$(arg$(5), 4, 2)
long_sec$ = str$(cint(val(mid$(arg$(5), 6, 10)) * 60.0))
longitude = val(long_deg$) + val(long_min$) / 60.0 + val(long_sec$) / 3600.0


' convert the time to minutes since midnight 1st Jan 2014
' then add/subtract the timezone and if required add daylight saving
' this calculation takes just 15mS at 40MHz
mins = GetMins(year, month, day, hour, min)
mins = mins + TimeZone * 60 ' adjust for the timezone
IF UseDST THEN ' if we observe daylight saving
If mins > GetDST(year, dms, dhs) AND mins < GetDST(year, dme, dhe) THEN
mins = mins + 60 ' adjust for AWST DST
ENDIF
ENDIF

' because we will display the time at the start of the next second
' we have to add 1 second to the current time
sec = sec + 1
IF sec >= 60 THEN sec = 0 : mins = mins + 1

' finally convert the minutes back into the current date/time
Line1$ = GetDate$(mins)
Line2$ = GetTime$(mins)

' we now have the date/time for the next second ready for display
' we have to wait for the end of the data stream from the GPS
' then we wait for the start of the next second and only then update the LCD
DO : LOOP WHILE TIMER < 950 ' wait for the data to finish
DO : LOOP WHILE INPUT$(200, #1) <> "" ' clear the input buffer
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for a new second to start
TIMER = 0

' display the date and time for this second
if secs mod 20 = 0 then
print Line1$ " ", Line2$ " " latitude "" ,(arg$(4))"",longitude "",(arg$(6))""

LOOP


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutine to get a GPS record into the array arg$()
SUB GetGPSRecord
DO
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for the start
FOR i = 0 TO 20
arg$(i) = "" ' clear ready for data
DO ' loops until a specific exit
x$ = INPUT$(1, #1) ' get the character
IF x$ = "," THEN EXIT DO ' new data item, new field
IF x$ = "*" THEN EXIT SUB ' end of record, so return with it
arg$(i) = arg$(i) + x$ ' add to the data
LOOP ' keep going
NEXT i ' increment the field
LOOP
END SUB


''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' calculate the minutes since midnight 1st Jan 2014
FUNCTION GetMins(yr, mth, day, hr, min)
GetMins = (yr - 14) * (365 * 24 * 60) + ((yr - 13) \ 4) * (24 * 60)
GetMins = GetMins + (md(mth) * (24 * 60))
GetMins = GetMins + ((day - 1) * (24 * 60))
GetMins = GetMins + (hr * 60)
GetMins = GetMins + min
IF (yr - 16) MOD 4 = 0 AND mth > 2 THEN GetMins = GetMins + (24 * 60)
END FUNCTION


' convert minutes back into the time (as a string)
FUNCTION GetTime$(minutes)
LOCAL hr, min, am$
hr = (minutes \ 60) MOD 24
IF hr = 0 THEN hr = 12
min = minutes MOD 60
GetTime$ = STR$(hr) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$
END FUNCTION


' convert minutes back into the date (as a string)
FUNCTION GetDate$(minutes)
LOCAL yr, mth, day, mths$, days$
mths$ = " JanFebMarAprMayJunJulAugSepOctNovDec"
days$ = "SunMonTueWedThuFriSat"
FOR yr = 14 TO 99
IF minutes < GetMins(yr + 1, 1, 1, 0, 0) THEN EXIT FOR
NEXT yr
FOR mth = 1 TO 12
IF minutes < GetMins(yr, mth, 1, 0, 0) THEN EXIT FOR
NEXT mth
mth = mth - 1
day = ((minutes - GetMins(yr, mth, 1, 0, 0)) \ (24 * 60)) + 1
GetDate$ = MID$(days$, ((((minutes \ (24 * 60)) + 3) MOD 7) * 3) + 1,3)+" "
GetDate$ = GetDate$ + RIGHT$(" " + STR$(day), 2)
GetDate$ = GetDate$ + "-" + MID$(mths$,mth*3,3) + "-" + STR$(yr + 2000)
END FUNCTION


' get the minutes that DST will start or end in a month
' modified for UK DST which starts on the LAST Sunday of the month
FUNCTION GetDST(yr, mth, hr)
LOCAL d, m, n
m = GetMins(yr, mth, 1, hr, 0)
d = ((m \ (24 * 60)) + 3) MOD 7
m = m + (((7 - d) MOD 7) * 24 * 60)
n = GetMins(yr, mth + 1, 1, 0, 0)
do while m + (7 * 24 * 60) < n
m = m + (7 * 24 * 60)
loop
GetDST = m
END FUNCTION

[/code]
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6269
Posted: 12:01pm 19 Jun 2016
Copy link to clipboard 
Print this post

You are using sec as a variable in one location and secs as the variable in the test.

I also think that you have a LOOP where an ENDIF is expected, but I haven't looked at the full code.


IF secs MOD 20 = 0 THEN
PRINT Line1$ " ", Line2$ " " latitude "" ,(arg$(4))"",longitude "",(arg$(6))""

LOOP


should be

IF sec MOD 20 = 0 THEN
PRINT Line1$ " ", Line2$ " " latitude "" ,(arg$(4))"",longitude "",(arg$(6))""

ENDIF
LOOP


JimEdited by TassyJim 2016-06-20
VK7JH
MMedit
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 08:35pm 19 Jun 2016
Copy link to clipboard 
Print this post

Thanks
that worked
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 06:05am 20 Jun 2016
Copy link to clipboard 
Print this post

I have another problem

I'm getting after a few minutes this problem
I have no idea why it's popping up.

[code]>
[231] GetDate$ = GetDate$ + "-" + Mid$(mths$,mth*3,3) + "-" + Str$(yr + 2000)
Error: Number out of bounds
[/code]

The actual code I'm using is below, its the start of my weather station code and I'm going to end up using the gps to update the clock on the lcd unit at regular intervals

The weird thing is - if I use the gps code on it's own I don't get this error!!!!!!!!!!!!!


[code]
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Weather station “almost full test” V2 '
'Thanks to Geoff Graham for the GPS code, microblocks and Matherp for their help
'And Many thanks to WhiteWizzard and MikeO without their help I’d have given up long ago '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Constants
Const swVer="0.7"
Const wSpeedPin=6 'Wind speed sensor
Const RainPin=14 'Rain sensor
Const wDirPin=26 'Direction sensor
Const WindFactor=0.4166666666666667 'unique to each enenemeter type
Const RainFactor=0.2794 'mm rain for every switch closure
Const TestPause=3000 'Wind speed sample time
SETPIN 23, DOUT 'GPS Power
SETPIN 16, DOUT 'HC-12 Power

'Define I/O
Setpin wSpeedPin,Intl,anemometerClick,Pullup
Setpin RainPin,Intl,rainguageClick,Pullup
SETPIN 26, AIN 'wind speed sensor
PIN(23) = 1 'GPS Power OFF
PIN(16) = 1 'HC12 Power OFF

' Global variables
dim anem_count,anem_last,wspeed,wcount
dim anem_min=1000
dim Wgust
dim thistime as integer
Dim rain_count
DIM mmrain,wdir,rain_last
'******************************************************************************************************************

' Configuration constants
TimeZone = 0.0 ' hours from GMT (+ or -)

UseDST = 1 ' set to 1 to enable daylight saving time (DST) adjust
dms = 3 ' the month that DST starts
dhs = 2 ' the hour that DST starts
dme = 10 ' the month that DST ends
dhe = 2 ' the hour that DST ends

' BME280 routines and test harness
const BME280_ADDRESS = &H77
const BME280_REGISTER_T1 = &H88
const BME280_REGISTER_P1 = &H8E
const BME280_REGISTER_H1 = &HA1
const BME280_REGISTER_H2 = &HE1
const BME280_REGISTER_CHIPID = &HD0
const BME280_REGISTER_CONTROLHUMID = &HF2
const BME280_REGISTER_CONTROL = &HF4
const BME280_REGISTER_PRESSUREDATA = &HF7
const BME280_REGISTER_TEMPDATA = &HFA
const BME280_REGISTER_HUMIDDATA = &HFD
'
dim integer s16=&HFFFFFFFFFFFF0000 , s16b=&H8000
dim integer s12=&HFFFFFFFFFFFFF000 , s12b=&H800
dim integer s8= &HFFFFFFFFFFFFFF00 , s8b=&H80
'
DIM INTEGER T1,T2,T3 'uint16_t, int16_t, int16_t
DIM INTEGER P1,P2,P3,P4,P5,P6,P7,P8,P9 'uint16_t, 8 x int16_t
DIM INTEGER H1,H2,H3,H4,H5,H6 'uint8_t, int16_t , uint8_t, int16_t, int16_t, int8_t
'
dim INTEGER t_fine 'used to store accurate temp reading from temp conversion for use in pressure and humidity conversions

' global arrays
DIM md(12), arg$(20)
DATA 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
FOR i = 1 TO 12: READ md(i): NEXT i

'*********************************************************************************************************

Init:

'interupts
Settick 1000 ,L1,1 'establish seconds "Tick Timer"
PIN(23) = 0 'GPS Power ON
OPEN "COM2:9600" AS #1 'OPEN port for GPS
'PIN(16) = 0 'HC12 Power ON
'OPEN "COM1:19200" AS #2 'Open port for HC-12 TX/RX

' ******************this is the main program loop, it never exits ******************************

DO
KeepSearching:
DO
GetGPSRecord ' get a GPS record
LOOP UNTIL arg$(0) = "GPRMC" ' we only want the RMC record
IF arg$(2) <> "A" THEN ' "A" means valid record
print "Searching", " For Satellites"
GOTO KeepSearching ' go back and keep looking
ENDIF



' the GPS has the valid time
' first extract the elements of the date/time from the GPS record
year = VAL(RIGHT$(arg$(9), 2)) ' extract the date
month = VAL(MID$(arg$(9), 3, 2))
day = VAL(LEFT$(arg$(9), 2))
hour = VAL(LEFT$(arg$(1), 2)) ' extract the time
min = VAL(MID$(arg$(1), 3, 2))
sec = VAL(MID$(arg$(1), 5, 2))

' extract and format latitude (data element #3, ddmm.mmmm)
lat_deg$ = LEFT$(arg$(3), 2)
lat_min$ = MID$(arg$(3), 3, 2)
lat_sec$ = str$(cint(val(mid$(arg$(3), 5, 9)) * 60.0))
latitude = val(lat_deg$) + val(lat_min$) / 60.0 + val(lat_sec$) / 3600.0

' extract and format longitude (data element #5, dddmm.mmmm)
long_deg$ = LEFT$(arg$(5), 3)
long_min$ = MID$(arg$(5), 4, 2)
long_sec$ = str$(cint(val(mid$(arg$(5), 6, 10)) * 60.0))
longitude = val(long_deg$) + val(long_min$) / 60.0 + val(long_sec$) / 3600.0

' convert the time to minutes since midnight 1st Jan 2014
' then add/subtract the timezone and if required add daylight saving
' this calculation takes just 15mS at 40MHz
mins = GetMins(year, month, day, hour, min)
mins = mins + TimeZone * 60 ' adjust for the timezone
If UseDST Then 'if we observe daylight saving
If mins > GetDST(year, dms, dhs) AND mins < GetDST(year, dme, dhe) THEN
mins = mins + 60 'adjust for AWST DST
EndIf
EndIf

' because we will display the time at the start of the next second
' we have to add 1 second to the current time
sec = sec + 1
IF sec >= 60 THEN sec = 0 : mins = mins + 1

' finally convert the minutes back into the current date/time
Line1$ = GetDate$(mins)
Line2$ = GetTime$(mins)

'*******************************************************************************************



' we now have the date/time for the next second ready for display
' we have to wait for the end of the data stream from the GPS
' then we wait for the start of the next second and only then update indoor unit
DO : LOOP WHILE TIMER < 950 ' wait for the data to finish
DO : LOOP WHILE INPUT$(200, #1) <> "" ' clear the input buffer
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for a new second to start
'TIMER = 0
' display the date and time for this second
'Print Line1$ "", Line2$ "", latitude "",(arg$(4))"",longitude "",(arg$(6))"" 'Print Day date time & location to console for test purposes (every second)
pause 1000 ' pause
Watchdog 600000 'checks program every 10 minutes and if stuck in loop reboots

if secs mod 10 = 0 then 'Mod 10 = every 10 seconds , Mod 3 = every 3 seconds - use whichever you want
windSpeedProc 'calculates speed and sends data every 10 seconds
WindDirProc 'process wind direction
rainProc 'process rain sensor readings
SendDataUpdate ' Displays data every 10 seconds
end if

i2c close 'So the program won't get confused - it wil open it again before a reading

end if

LOOP

Loop

End

'***** End main program loop*************************************************************************************
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutine to get a GPS record into the array arg$()
SUB GetGPSRecord
DO
DO WHILE INPUT$(1, #1) <> "$" : LOOP ' wait for the start
FOR i = 0 TO 20
arg$(i) = "" ' clear ready for data
DO ' loops until a specific exit
x$ = INPUT$(1, #1) ' get the character
IF x$ = "," THEN EXIT DO ' new data item, new field
IF x$ = "*" THEN EXIT SUB ' end of record, so return with it
arg$(i) = arg$(i) + x$ ' add to the data
LOOP ' keep going
NEXT i ' increment the field
LOOP
END SUB



''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' calculate the minutes since midnight 1st Jan 2014
FUNCTION GetMins(yr, mth, day, hr, min)
GetMins = (yr - 14) * (365 * 24 * 60) + ((yr - 13) \ 4) * (24 * 60)
GetMins = GetMins + (md(mth) * (24 * 60))
GetMins = GetMins + ((day - 1) * (24 * 60))
GetMins = GetMins + (hr * 60)
GetMins = GetMins + min
IF (yr - 16) MOD 4 = 0 AND mth > 2 THEN GetMins = GetMins + (24 * 60)
END FUNCTION


' convert minutes back into the time (as a string)
FUNCTION GetTime$(minutes)
LOCAL hr, min, am$
' am$ = "AM"
hr = (minutes \ 60) MOD 24
' IF hr >= 12 THEN am$ = “PM”
' IF hr > 12 THEN hr = hr – 12
IF hr = 0 THEN hr = 12
min = minutes MOD 60
GetTime$ = STR$(hr) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(min), 2) + ":"
GetTime$ = GetTime$ + RIGHT$("0" + STR$(sec), 2) + " " + am$
END FUNCTION


' convert minutes back into the date (as a string)
FUNCTION GetDate$(minutes)
LOCAL yr, mth, day, mths$, days$
mths$ = " JanFebMarAprMayJunJulAugSepOctNovDec"
days$ = "SunMonTueWedThuFriSat"
FOR yr = 14 TO 99
IF minutes < GetMins(yr + 1, 1, 1, 0, 0) THEN EXIT FOR
NEXT yr
FOR mth = 1 TO 12
IF minutes < GetMins(yr, mth, 1, 0, 0) THEN EXIT FOR
NEXT mth
mth = mth - 1
day = ((minutes - GetMins(yr, mth, 1, 0, 0)) \ (24 * 60)) + 1
GetDate$ = MID$(days$, ((((minutes \ (24 * 60)) + 3) MOD 7) * 3) + 1,3)+" "
GetDate$ = GetDate$ + RIGHT$(" " + STR$(day), 2)
GetDate$ = GetDate$ + "-" + MID$(mths$,mth*3,3) + "-" + STR$(yr + 2000)
END FUNCTION
' get the minutes that DST will start or end in a month
' modified for UK DST which starts on the LAST Sunday of the month
FUNCTION GetDST(yr, mth, hr)
LOCAL d, m, n
m = GetMins(yr, mth, 1, hr, 0)
d = ((m \ (24 * 60)) + 3) MOD 7
m = m + (((7 - d) MOD 7) * 24 * 60)
n = GetMins(yr, mth + 1, 1, 0, 0)
do while m + (7 * 24 * 60) < n
m = m + (7 * 24 * 60)
loop
GetDST = m
END FUNCTION

'***************************************************************************************************
'
function bme280_read_temp() as float
local integer var1,var2,adc_T
local adc%(2)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_TEMPDATA
i2c read BME280_ADDRESS,0,3,adc%()
adc_T=((adc%(0)<<16) OR (adc%(1)<<8) or adc%(2))>>4
var1 = ((((adc_T>>3) - (T1 <<1))) * T2) \ q(11)
var2 = (((((adc_T>>4) - (T1)) * ((adc_T\ q(4)) - (T1))) \ q(12)) * (T3)) \ q(14)
t_fine = var1 + var2
bme280_read_temp = ((t_fine * 5 + 128) \ q(8))/100.0
end function

function bme280_read_pressure() as float
local integer var1, var2, adc_P, p
local adc%(2)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_PRESSUREDATA
i2c read BME280_ADDRESS,0,3,adc%()
adc_P=((adc%(0)<<16) OR (adc%(1)<<8) or adc%(2))>>4
var1 = t_fine - 128000
var2 = var1 * var1 * P6
var2 = var2 + ((var1 * P5)<<17)
var2 = var2 + (P4 << 35)
var1 = ((var1 * var1 * P3)\ q(8)) + ((var1 * P2)<<12)
var1 = ((1<<47)+var1)*P1\ q(33)
if var1 = 0 THEN
bme280_read_pressure = 0' avoid exception caused by division by zero
exit function
endif
p = 1048576 - adc_P
p = (((p<<31) - var2)*3125) \ var1
var1 = (P9 * (p\ q(13)) * (p\ q(13))) \ q(25)
var2 = (P8 * p) \ q(19)
p = ((p + var1 + var2) \ q(8)) + (P7<<4)
bme280_read_pressure = p/25600.0
end function
'
function bme280_read_humidity() as float
local integer v_x1,adc_H
local adc%(1)
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_HUMIDDATA
i2c read BME280_ADDRESS,0,2,adc%()
adc_H=(adc%(0)<<8) or adc%(1)
v_x1 = t_fine - 76800
v_x1=(((((adc_H<<14)-((H4)<<20)-(H5*v_x1))+16384)\ q(15))*(((((((v_x1*H6)\ q(10))*(((v_x1*H3)\ q(11))+32768))\ q(10))+2097152)*H2+8192)\ q(14)))
v_x1 = (v_x1 - (((((v_x1 \ q(15)) * (v_x1 \ q(15))) \ q(7)) * (H1)) \ q(4)))
if v_x1< 0 then v_x1 = 0
if v_x1 > 419430400 then v_x1= 419430400
bme280_read_humidity = (v_x1\ q(12)) / 1024.0
end function

sub bme280_init
local i%,cal%(17)
i2c open 400,1000 '400KHz bus speed
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_CHIPID
i2c read BME280_ADDRESS,0,1,i%
if i%<>&H60 then print "Error BME280 not found"
' if i%<>&H60 then print #7, "Error BME280 not found"
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_T1
i2c read BME280_ADDRESS,0,6,cal%()
T1=cal%(0) OR (cal%(1)<< 8)
T2=cal%(2) OR (cal%(3)<< 8): if T2 and s16b then T2=T2 OR s16 'sign extend if required
T3=cal%(4) OR (cal%(5)<< 8): if T3 and s16b then T3=T3 OR s16
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_P1
i2c read BME280_ADDRESS,0,18,cal%()
P1=cal%(0) OR (cal%(1)<<8)
P2=cal%(2) OR (cal%(3)<<8): if P2 and s16b then P2=P2 OR s16 'sign extend if required
P3=cal%(4) OR (cal%(5)<<8): if P3 and s16b then P3=P3 OR s16
P4=cal%(6) OR (cal%(7)<<8): if P4 and s16b then P4=P4 OR s16
P5=cal%(8) OR (cal%(9)<<8): if P5 and s16b then P5=P5 OR s16
P6=cal%(10) OR (cal%(11)<<8): if P6 and s16b then P6=P6 OR s16
P7=cal%(12) OR (cal%(13)<<8): if P7 and s16b then P7=P7 OR s16
P8=cal%(14) OR (cal%(15)<<8): if P8 and s16b then P8=P8 OR s16
P9=cal%(16) OR (cal%(17)<<8): if P9 and s16b then P9=P9 OR s16
'
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_H1
i2c read BME280_ADDRESS,0,1,H1
i2c write BME280_ADDRESS,1,1,BME280_REGISTER_H2
i2c read BME280_ADDRESS,0,7,cal%()
H2=cal%(0) OR (cal%(1)<< 8): if H2 and s16b then H2=H2 OR s16 'sign extend if required
H3=cal%(2)
H6=cal%(6): if H6 and s8b then H6=H6 OR s8 'sign extend if required
H4=(cal%(3)<<4) OR (cal%(4) and &H0F): if H4 and s12b then H4=H4 OR s12 'sign extend if required
H5=(cal%(5)<<4) OR (cal%(4)>>4): if H5 and s12b then H5=H5 OR s12
'
i2c write BME280_ADDRESS,0,2,BME280_REGISTER_CONTROLHUMID,&H05 '16x oversampling humidity
i2c write BME280_ADDRESS,0,2,BME280_REGISTER_CONTROL,&HB7 '16x oversampling pressure/temp, normal mode
'
end sub
'
function q(x as integer) as integer 'returns 2 raised to the power
q=(1<<x)
End Function

'**************************************************************************************

'Sub routines
rainguage sensor interrupt
Sub rainguageClick
thistime=Timer-rain_last
rain_last=Timer
If thistime>10 Then
rain_count=rain_count+1
Print "Rain click"
End If
End Sub

'Wind speed sensor interrupt
Sub anemometerClick
thistime=Timer-anem_last 'thistime measures the time between pulses
'thistime=thistime/3 '****similation for 3 pulses only - Rem when not used ****
anem_last=Timer
If thistime>5 Then 'only process if > 5mSec, for switch debounce
anem_count=anem_count+1 'Adds up pulses single pulse per/rotation
'anem_count=anem_count+3 'Adds up pulses '****similation for 3 pulses only - Rem when not used ****
If thistime<anem_min Then 'If the time is less than 1 second
anem_min=thistime 'gust 'then thistime = gust
End If
'Print "Wind click" 'Prints this EVERY time the reed switch closes=**TEST USE ONLY - DELETE WHEN happy its working properly
'use this to check how many switch closures per revolution when turning by hand
end if
'print "Incr Anem counts:";anem_count;" This Pulse interval:";thistime;" Min Pulse interval:";anem_min
End Sub

'Wind Direction data process ** Checked with multimeter 0-3.3v 0-360 deg*****
Sub WindDirProc
value=pin(26)
select case value
CASE 0.0 to 0.103125 ' 0.00916666666666666666666666666667V per degree
Wheading$ = "North"
case 0.103126 to 0.309375
wheading$ = "NNE"
case 0.309376 to 0.515625
wheading$ = "NE"
case 0.515626 to 0.721875
wheading$ = "East"
case 0.721876 to 0.928125
wheading$ = "ESE"
case 0.928126 to 1.134375
wheading$ = "ESE"
case 1.134376 to 1.340625
wheading$ = "SEast"
case 1.340626 to 1.56875
wheading$ = "SSE"
case 1.56876 to 1.753125
wheading$ = "South"
case 1.753126 to 1.959375
wheading$ = "SSw"
case 1.959376 to 2.165625
wheading$ = "SWest"
case 2.165626 to 2.371875
wheading$ = "WSE"
case 2.371876 to 2.578125
wheading$ = "West"
case 2.578126 to 2.784375
wheading$ = "WNW"
case 2.784375 to 2.990625
wheading$ = "NWest"
case 2.990626 to 3.196875
wheading$ = "NNW"
CASE 3.196875 to 3.3
wheading$ = "North"
CASE ELSE
wheading$="not yet assigned"
end select

'********need to implement this next**********
'For x=1 To 9 'move data up array
' wdArray(x)=wdArray(x+1)
'Next x
'wdArray(10)=wHeading 'place latest reading in Array
'For x=1 To 10 'addup all data in array
' wdResult=wdResult+wdArray(x)
'Next x
'wdCount=wdCount+1
'If wdCount=10 Then wdCount=1
'wHeading=wdResult/10 'get average the the last 10 wind dir samples
lastreading=wheading2
'********************************************


End Sub


'Wind Speed data process
Sub WindSpeedProc
local wResult, reading,x
'Print "Total Anem counts:";anem_count;" Last Pulse interval:";thistime;" Min Pulse interval:";anem_min 'to console for testing purposes
'calc wind speed
if anem_count>0 then
wSpeed=(windfactor*anem_count)/(testpause/1000)
else
wspeed=0
end if
anem_count=0
'calc Gust
Print "Wind Count:";wcount
Print "ActualWindSpeed:";wspeed
if anem_min<1000 then
wGust=(1/(anem_min/1000))*windfactor 'only if there is wind 1000=no wind
else
wgust=0
end if
anem_min=1000

If wgust>hgust Then hgust=wgust
'Print "WindSpeedArray:";wresult
Print "AvgWindSpeed:";wspeed
Print "Windgust:";wgust
Print "Highest Windgust:";Hgust
End Sub

'Rain sensor process
Sub RainProc
reading=rain_count
rain_count=0
mmRain=mmRain + (reading*rainfactor)
Print "Rain:";mmrain
End Sub


Sub SendDataUpdate
bme280_init
'print #2, " Direction:"; wheading$ " WindSpeed: "; wspeed ;" Average Wind Speed: "; wspeed ;" Gust "; wgust ;" Highest Gust "; hgust;" mm Rain"; mmrain 'RF serial tx/rx
print Line1$ " ", Line2$ "", latitude "",(arg$(4))"",longitude "",(arg$(6))""
print bme280_read_temp()"C " bme280_read_pressure()"mB " bme280_read_humidity()"% Humidity" 'Temp must be run before pressure or humidity
print " Direction: "; wheading$ " WindSpeed: "; wspeed ;" Average Wind Speed: "; wspeed ;" Gust "; wgust ;" Highest Gust "; hgust;" " " Wind Count:";wcount " mm Rain"; mmrain 'Console for test purposes

End Sub

'*****************************************************************************************

' Put clock update Sub here

'IF hour = 02 and if min = 05 then sync clock *** NEED TO implement this later***
'end if

'L1 - 1second Tick interrupt
Sub L1
secs=secs+1 'update seconds timer
if secs => 86400 then '24 hrs reached
secs = 0 'reset counter
endif

If Time$="02:05" Then 'Update RTC
'put clock update sub here
Endif

If Time$="09:00" Then 'New Met day
'put code here 'sync Clock
Hgust=0 'reset High Gust
mmRainday=mmRain
mmRain=0 'reset Rain
Endif
end if

If mins>60 Then 'reset after 1 min
mins=0
End If

End Sub

[/code]

The code works perfectly to start here is a section of it working (no weather station attached hence 0 for wind speed and so on)

[quote]

> run
Searching For Satellites
Searching For Satellites
Searching For Satellites
Searching For Satellites
Wind Count: 0
ActualWindSpeed: 0
AvgWindSpeed: 0
Windgust: 0
Highest Windgust: 0
Rain: 0
Mon 20-Jun-2016 16:58:17 53.44 N 2.10611 W
23.92C 1000.7mB 46.4512% Humidity
Direction: ESE WindSpeed: 0 Average Wind Speed: 0 Gust 0 Highest Gust 0 Wind Count: 0 mm Rain 0
Wind Count: 0
ActualWindSpeed: 0
AvgWindSpeed: 0
Windgust: 0
Highest Windgust: 0
Rain: 0
Mon 20-Jun-2016 16:58:37 53.44 N 2.10611 W
23.92C 1000.7mB 46.4297% Humidity
Direction: ESE WindSpeed: 0 Average Wind Speed: 0 Gust 0 Highest Gust 0 Wind Count: 0 mm Rain 0
Wind Count: 0
ActualWindSpeed: 0
AvgWindSpeed: 0
Windgust: 0
Highest Windgust: 0
Rain: 0
Mon 20-Jun-2016 16:58:46 53.44 N 2.10611 W
23.92C 1000.71mB 46.4287% Humidity
Direction: ESE WindSpeed: 0 Average Wind Speed: 0 Gust 0 Highest Gust 0 Wind Count: 0 mm Rain 0
[231] GetDate$ = GetDate$ + "-" + Mid$(mths$,mth*3,3) + "-" + Str$(yr + 2000)
Error: Number out of bounds
[/quote]
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1702
Posted: 07:33am 21 Jun 2016
Copy link to clipboard 
Print this post

I know people are probably getting really peeved off with me asking so many questions and always looking for help and I'm sorry. I am the first to admit I know nothing about programming, pic chips and similar stuff.
Complicated maths is also something I am very bad at - I am literally "learning as I go" and "trial and error"

but
I really cannot find why this fault is happening

It's with in this line that it fails
GetDate$ = GetDate$ + "-" + Mid$(mths$,mth*3,3) + "-" + Str$(yr + 2000)
Error: Number out of bounds

When I type "print Print mth, yr" the month comes back as 0

I've no idea why, and I've no clue how to fix it as unfortunately I really don't understand the maths of the gps clock code.

Any suggestions or do I just give up on the gps section?
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2932
Posted: 09:56am 21 Jun 2016
Copy link to clipboard 
Print this post

With mth equal to zero, the MID$ statement will fail with the middle of the three parameters.

The middle parameter is the starting position within the string which cannot be zero (0*3 = 0)). It must be a value greater than zero.

I have not yet had time to look at your code to find out where the 'mth' variable is 'loaded'.

Could it be that if no GPS data is received then the value becomes zero? If this is the case then need to add a check for 'valid' GPS data. If no valid data, then bypass the GetDate$ line of code (and possibly display a message saying GPS signal lost)

Please can someone confirm if middle parameter of MID$ command must be greater than zero (some BASICs allowed a zero value).

WW
 
     Page 1 of 2    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025