| Author |
Message |
stevech
Joined: 23 Feb 2006
|
|
Posted: 08 October 2006, 3:48 AM Post subject: set the ZBasic VM's date/time using windows command line |
|
|
Here's a ditty that can be helpful if you need to set the ZX module's date and time to match that of a PC's clock.
This code accepts, on the console serial port input, a line of text that comes from a Windows "date" command line as shown below. This ZBasic code then parses the date time from this and sets the ZBasic Virtual Machine (VM) date and time.
The Windows command line begins with "d-8". This ("d") can be used by the application to detect that the date command follows. The -8 is parsed as the GMT offset in hours, for applications that automatically adjust daylight savings time or calculate GMT and local time.
The parsing code may need tweaking if you are in a country where your date/time formats differ.
Can't redirect the echo command's output directly to a com port on the PC because the port opens and the data flows before the ZBasic VM has finished resetting due to the change in DTR on the port. You can cut/paste the echo command's output into the debug window of the IDE. Or write a PC program that opens the com port and sends this data as from the echo command.
| Code: | ''''''''''''''''''''''''''''''''''''''''''''''''''''''
' echo d-8 %date% %time% Windows command in batch file yields...
' column numbers. second set is relative to i
' 0000000001111111112222
' 1234 0123456789012345678901
' d-8 Fri 10/06/2006 20:46:15.32 result of echo commmand, above. hr has leading space if < 10. 24 hr clock
function SetDateTime(s as string) as boolean
dim i as byte
dim mm as byte, d as byte, y as integer
dim h as byte, m as byte, secs as single
GMToffset = atoi(mid(s,2,3))
i=5 ' skip over GMT offset
do while not isnumeric(mid(s,i,1))
i=i+1
loop
mm = cbyte(atoi(mid(s,i+0,2)))
d = cbyte(atoi(mid(s,i+3,2)))
y = atoi(mid(s,i+6,4))
h = cbyte(atoi(mid(s,i+11,2)))
m = cbyte(atoi(mid(s,i+14,2)))
call valueS(mid(s,i+17, 5), secs, SetDateTime)
''' set date time in the VM
call PutTimeStamp(y, mm, d, h, m, secs)
'''debug.print cstr(GMToffset);" ";cstr(mm);" ";cstr(d);" ";cstr(y);" ";cstr(h);" ";cstr(m);" ";cstr(secs)
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
function isnumeric(byval s1 as string) as BOOLEAN
dim b as byte
b = asc(mid(s1,1,1))
if b >= asc("0") and b <= asc("9") then
isnumeric = TRUE
else
isnumeric = FALSE
end if
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
function atoi(byval s1 as string) as integer
dim ok as BOOLEAN
dim v as single
'debug.print "atoi ";s1
call valueS(s1, v, ok)
if (ok) then
atoi = cint(fix(v))
else
atoi = 0
end if
end function |
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 08 October 2006, 20:14 PM Post subject: |
|
|
Great idea.
I might suggest changing IsNumeric() to take a Byte parameter. In this particular use case that would avoid unnecessarily creating 1 byte strings and some compiler generated temporary variables to hold them. The implementation could then be:
| Code: | Function IsNumeric(ByVal b as Byte) as Boolean
IsNumeric = (b >= asc("0")) And (b <= asc("9"))
End Function |
Then, the invocation would be:
| Code: | | Do While Not IsNumeric(Chr(s, i)) |
|
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
|
|
Posted: 08 October 2006, 22:20 PM Post subject: |
|
|
thanks. will do.
wouldn't that have to be coded
IsNumeric(Asc(mid(s, i, 1)))
|
|
| Back to top |
|
 |
dkinzer Site Admin
Joined: 03 Sep 2005
Location: Portland, OR
|
|
Posted: 08 October 2006, 23:13 PM Post subject: |
|
|
Actually, it should have been:
| Code: | | IsNumeric(Asc(s, i)) |
The optional second parameter to Asc() allows you to retrieve a particular character from a string without having to use Mid() as an intermediary.
|
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
|
|
Posted: 09 October 2006, 4:48 AM Post subject: |
|
|
here's the code with the changes discussed above...
| Code: | ''''''''''''''''''''''''''''''''''''''''''''''''''''''
' echo d-8 %date% %time% Windows command in batch file yields...
' column numbers. second set is relative to i
' 0000000001111111112222
' 1234 0123456789012345678901
' d-8 Fri 10/06/2006 20:46:15.32 result of echo commmand, above. hr has leading space if < 10. 24 hr clock
function SetDateTime(s as string) as boolean
dim i as byte
dim mm as byte, d as byte, y as integer
dim h as byte, m as byte, secs as single
GMToffset = atoi(mid(s,2,3))
i=5 ' skip over GMT offset
do while not IsNumeric(Asc(s, i))
i=i+1
loop
mm = cbyte(atoi(mid(s,i+0,2)))
d = cbyte(atoi(mid(s,i+3,2)))
y = atoi(mid(s,i+6,4))
h = cbyte(atoi(mid(s,i+11,2)))
m = cbyte(atoi(mid(s,i+14,2)))
call valueS(mid(s,i+17, 5), secs, SetDateTime)
''' set date time in the VM
call PutTimeStamp(y, mm, d, h, m, secs)
'''debug.print cstr(GMToffset);" ";cstr(mm);" ";cstr(d);" ";cstr(y);" ";cstr(h);" ";cstr(m);" ";cstr(secs)
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Function IsNumeric(ByVal b as Byte) as Boolean
IsNumeric = (b >= asc("0")) And (b <= asc("9"))
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
function atoi(byval s1 as string) as integer
dim ok as BOOLEAN
dim v as single
'debug.print "atoi ";s1
call valueS(s1, v, ok)
if (ok) then
atoi = cint(fix(v))
else
atoi = 0
end if
end function |
|
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
|
|
Posted: 22 October 2006, 3:38 AM Post subject: |
|
|
EDIT: I added in the comments some VBscript code to output date/time.
Here's a recode of the function to parse the date/time from a string as would come from the serial port and a windows batch file or a VBScript. And then put the date/time into the ZBasic VM.
This version accepts varied formats, such as
d-8 10/21/06 8:13:12.34 PM
and
d-8 12/21/2006 20:13:12.34
There's also a couple of number conversion functions that by themselves might be useful.
| Code: |
''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''
' VBscript:
'on error resume next
'~ GMToffset = "d-8"
'~ Set com_port = CreateObject("MSCOMMLib.MSComm")
'~ com_port.commport = 4
'~ com_port.settings = "19200,N,8,1"
'~ com_port.RThreshold = 0
'~ com_port.PortOpen = True
'~ if com_port.PortOpen = true then
'~ wsh.sleep(3000)
'~ do
'~ s = com_port.Input
'~ wsh.sleep(200)
'~ loop while s <> ""
'~ s = GMToffset & " " & FormatDateTime(now(),0) & vbcrlf
'~ com_port.output = s
'~ wsh.sleep(500)
'~ com_port.PortOpen = False
'~ msgbox s
'~ else
'~ msgbox "Cannot open COM" & com_port.commport
'~ end if
'~ set com_port = nothing
'GMToffset = "d-8"
' msgbox GMToffset & " " & FormatDateTime(now(),0)
' Windows command line/batch file:
' echo d-8 %date% %time% Windows command in batch file yields...
' column numbers. second set is relative to i
' 0000000001111111112222
' 1234 0123456789012345678901
' d-8 Fri 10/06/2006 20:46:15.32 result of echo commmand, above. hr has leading space if < 10. 24 hr clock
'************************************************************
' ZBasic
function SetDateTime(s as string) as boolean
dim i as byte, n as byte
dim mm as byte, d as byte, y as integer
dim h as byte, m as byte, secs as single
i = 2 ' skip over the 1st char in line
GMToffset = strInt(mid(s,i), n)
i = i + n + 1 ' skip over GMT offset, 1 or 2 digits
' skip over dayname if present, and spaces
do while (not isNumeric(asc(s,i)))
i = i + 1
loop
mm = cbyte(strInt(mid(s,i,2), n)) ' 1 or 2 digits
i = i + n + 1 ' skip the /
d = cbyte(strInt(mid(s,i,2), n)) ' 1 or 2 digits
i = i + n + 1 ' skip the /
y = strInt(mid(s,i,4), n) ' 4 digits
i = i + n + 1
i = i + skipSpace(mid(s, i))
' support either 12 or 24 hr format hh:mm:ss [AMPM]
h = cbyte(strInt(mid(s,i,2), n)) ' hours 1 or 2 digits
i = i + n + 1 ' skip the :
m = cbyte(strInt(mid(s,i,2), n)) ' minutes 1 or 2 digits
i = i + n + 1 ' slip the :
call valueS(mid(s,i, 5), secs, SetDateTime) ' seconds, may be a float
if strCompare(mid(s, i), "PM", TRUE) = 0 then
h = h + 12
end if
if (y < 100) then
y = y + 2000 ' y3K bug to come. I'll be gone!
end if
''' set date time in the VM
call PutTimeStamp(y, mm, d, h, m, secs)
debug.print "SetDateTime ";cstr(GMToffset);" ";cstr(mm);"/";cstr(d);"/";cstr(y);" ";cstr(h);":";cstr(m);":";cstr(secs)
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
Function IsNumeric(ByVal b as Byte) as Boolean
IsNumeric = TRUE ' assume
select case (b)
case asc("0") TO asc("9")
case asc("-")
case asc(".")
case else
IsNumeric = FALSE
end select
'''debug.print "IsNumeric '";chr(b);"' ";cstr(isNumeric)
End Function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
function skipSpace(byval s as string) as byte
skipSpace = 0
do while (asc(s, skipSpace+1) = asc(" ")) ' strings' index begins with 1
skipSpace = skipSpace + 1
loop
'''debug.print "skipSpace ";s;" ";cstr(skipSpace)
end function
'''''''''''''''''''''''''''''''''''''''''''''''''''''
function StrInt(byval s1 as string, byref count as byte) as integer
dim n as byte
dim ok as BOOLEAN
dim v as single
StrInt = 0
count = 0
' get number of digits in number
for n = 0 to cbyte(len(s1)) - 1
if not IsNumeric(asc(mid(s1,n+1,1))) then
exit for
end if
next
count = n
if (count > 0) then
' convert string number to float
call valueS(mid(s1, 1, count), v, ok)
if (ok) then ' convert to integer
StrInt = cint(v)
end if
end if
'''debug.print "StrInt ";s1;" ";cstr(strInt);" v=";cstr(v);" count=";cstr(count)
end functionFirst, PC side code, then ZBasic code.
|
| Description: |
|
 Download |
| Filename: |
ZBasic SetTime.zip |
| Filesize: |
444 Bytes |
| Downloaded: |
1144 Time(s) |
|
|
| Back to top |
|
 |
stevech
Joined: 23 Feb 2006
|
|
Posted: 24 October 2006, 0:57 AM Post subject: |
|
|
Oops. Bug fix due to insufficient programmer IQ:
In my ZBasic code, above, replace this
if strCompare(mid(s, i), "PM", TRUE) = 0 then
with this
if strFind(mid(s, i), "PM", i, TRUE) = 0 then
|
|
| Back to top |
|
 |
|