| 
 
 This projects page contains some software projects, some
were written in compiled BASIC others in C. Others without an in depth
description appear in a Software Portfolio listing.  
 
      The source code is available via FTP at ftp://ftp.frontiernet.net/pub/users/erickclasen/public_ftp/C/ and ftp://ftp.frontiernet.net/pub/users/erickclasen/public_ftp/BAS/ 
respectively for C files or BASIC files. Most of them are simple command line utilities, however a
few are quite complex. The BASIC programs I compile with the Power Basic
compiler. The C programs are compiled with Borland 3.0 or GCC depending
on the target. 
 
Data Encryption Program Basic description of data encryption.
Lunar Phase Program Creates an almanac of moon and sun positions.
Weather Statistics Program Approximate sunrise and sunset, average temperatures for a given day.
Command Line Calculator Program A very simple calculator that works directly from the DOS command line.
Cellular Automata Graphics Programs Draws various cellular Automata on the screen.
CAT Transceiver Control Program Controls a Yaseu FT767GX HF Transceiver using a PC via the serial port.
  
First a bit of history 
When I started with computers in 6th grade it was with a TRS-80
pocket computer (Clock speed 540 kHz, ~1K RAM), the first version that
they sold. This was followed quickly by a VIC-20 (6502@2mHz, 3K RAM).
As I got used to BASIC, I started writing more and more complicated
programs. Some favorite non-graphical games were a stock market game
based on random prices attached to letter sequences that were
generated. From the initial price, small random deltas were introduced
to the prices. The object of the game was to watch the "ticker tape"
ASCII go by on the screen and buy and sell the stocks, making a profit.
This was sort of a day trading game, simple but entertaining. 
Another was a non-graphical flight simulator that was based on some basic physics, using numerical methods. 
On the screen you would see the instruments represented in numbers and would fly based on these instruments.
A lot of work was put into this one and it worked fairly good for what it was. 
The next big step was graphics, most programs written with graphics
were a hybrid, BASIC for the main program with machine language calls
for the graphics routines. One of the initial hurdles was the fact that
there was no assembler available at the time for the VIC-20. I wrote a
few short segments of machine language by poking in the op-codes using
the 6502 book, this got old fast. But it did prove the merits of
machine code. The speed difference was amazing. Filling the screen
entirely with one repeated character would take a noticeable amount of
time in BASIC. Using machine code, it would appear to instantly flash
the entire screen at once. I was hooked. 
I then wrote an assembler/machine language monitor tool in BASIC using
the 6502 book as a guide. This enabled me to write in assembly and
load the machine code into memory. This worked better, still slow going
to write software. But the payoff was that the machine language could
write to the screen at a much higher rate that the interpreted BASIC.
The easiest way to load the assembly was to treat it
as data and allow the BASIC program to load it into RAM on start up. 
 This made it possible to write games that had a lot of graphics refresh such as Pacman and grotto style games. 
Besides writing game software I wrote some software that would model
physics such as simulations of launching artillery and
missiles. One other thing I used frequently and toyed with was
numerical methods. I was basically doing calculus type math on
the computer, years before I knew what it was. One of my favorites at
that time was algorithms along the lines of Newton's method. Newton's
method is typically used to find a square root by successive
approximations. I used it and an algorithm that closes in on a target
value using
a Tractrix curve in a lot of places. These were used as control
algorithms behind the flight simulator and controlling the ghosts on
the Pacman
game. 
That sums up how I started with programming. 
  
Data Encryption of Files Using Random Files as Keys 
The concept used is to take 2 files reading them in as
binary data, and applying a mathematical operation between them. The
key file must be at least
as long as the file to be encrypted. Preferably the key file would be
created by a random number generator. Simplistically the encode
operation could
just add the 2 files byte wise and simply allowing rollover to occur.
The decode operation would then subtract the characters of the key file
back out
from the encrypted file. 
The following shows an example of encrypting the word hello. 
  Add Method 
  Input File      Key File   Output File   Letter  ASCII      ASCII         value    value      value
  h        104       63       203 e        101       87       188 l        108      135       243 l        108       68       176 o        111      222        77 (111+222 = 333 with '8 bit rollover' 333-256 = 77)
 
   
To decode the output file requires the key file and works by subtraction. 
  Subtract Decryption
  Input File   Key File   Output File     ASCII       ASCII      ASCII     Letter   value       value      value
     203          63        104        h    188          87        101        e    243         135        108        l    176          68        108        l     77         222        111        o   (77-222 = -145 with '8 bit rollover' -145+256 = 111  )
 
   
The previous description requires 2 programs. One
to encrypt and another to decrypt. A way to make decryption and
encryption work with one program
is to make it a mirrored process. Instead of adding for encryption and
subtracting for decryption using an operation such as a logical XOR
(exclusive
or) would accomplish the mirroring process. In electromechanical
cryptography (i.e. Enigma machine) this would be a reflector operation. 
The encode operation would appear as follows. 
  XOR Method
  Input File      Key File   Output File   Letter  ASCII    ASCII      ASCII         value    value      value
  h        104       63        87 e        101       87        50 l        108      135       235 l        108       68        40 o        111      222       177 
 
   
To decode the output file requires the key file and works by subtraction. 
  XOR Decryption
  Input File   Key File   Output File     ASCII       ASCII      ASCII     Letter   value       value      value
      87          63        104        h     50          87        101        e    235         135        108        l     40          68        108        l    177         222        111        o   (77-222 = -145 with '8 bit rollover' -145+256 = 111  )
 
   
The result is that the same algorithm and program
can be used both ways in the XOR case. The weakness in both the
add-subtract and the XOR method is that using a key of zero allows the
character to be sent to the output file unencrypted. If this happens
intermittently only a few instances per message
it is OK. If it happens to often it may be possible to decode the file
using a frequency analysis attack. The object in any type of encryption
is to completely mix the message with the key. This mix should make the
output as random as possible. The frequency table of the output should
be as close to
white noise as possible. The key should be large enough that it does
not repeat within the message. If the key does not have enough
combinations in it
so that a pattern forms, as in it repeats after some number of bytes
then it is not a good key. By having a pattern in a key, there is a
possibility of attack on the encrypted data by detection of this
pattern and working backwards from it. 
The best key and in the case of using a file as a key,
the best file would be a file of white noise. Pseudo-random number
generators suffer from the problem that they are generated using an
algorithm themselves. This leads to the problem that eventually the key
may repeat. If the key repeats after n
characters and the message/file that is to be encrypted is less than n
no problem, if not the key is weak. Another problem with pseudo-random
number generators is the fact that they require a seed value. They are
a finite number of seed values, for a given seed value the sequence of
pseudo-random numbers
will be the same. Generally the programmer tries to use tricks like
reading a clock and a piece of memory like a register that can have any
sort of data
in it at that time. But the fact remains that the same seed with
generate the same key sequence. If you encrypt enough files and
messages eventually over
time two of them will be using the same key. This lends itself to
cracking the code by pattern matching between files/messages. 
This pattern matching to crack codes can get elaborate
and use common English works as tries against the patterns. These so
called cribs provide
shortcuts to cracking codes. For instance it could be assumed that a
message from John to Sue will contain Sue in the message, not mention
words like
(the) and (and). This fact can be used in combination with pattern
matching, looking for messages or segments of messages encoded with the
same key sequence. 
The best random numbers to use as a key and create a
key file from would be true random numbers. Random number generators
that work by use Johnson
(thermal) noise as there source would be the best. It is possible to
generate such a source by using Zener diode noise fed into an A to D
converter.
That would allow getting a digital value for the noise, best would be
to have it mapped to a memory location where it can be easily read.
This number
then could be read to the key file, generating a truly random key. This
could even be done using the microphone input on a computer. By
connecting a noise source to the microphone input and generating a WAV
file from it, this file can be used as the random key with which to
encode the message. 
This is just a small simple (although very effective)
example and taste of cryptography. Other information can be read
on-line about it. The history
of the Enigma machine and decoding it in project Ultra is interesting
in particular. There is something called public key encryption, so
called PGP is
an example. This is worth looking at as well. Books Here????? 
Back to Top
  
Lunar Phase Program  
The almanac and calender information presented on the Almanac with Sun and Moon Position
 and Lunar Events
pages was generated by a software algorithm. It is quite accurate, so far it seems to line up well with
the reality in the sky.  
 For the lunar months, the numbering was considered to start with the first new moon of the
new calender year, this is somewhat arbitrary and there might be some better suggestions. 
 
The time base for the calculations is UTC. Items calculated for
a given day are calculated at 00:00 UTC for that day. The moon Zodiac gives the moons position
exactly when it is in a given sign. The sun Zodiac follows the traditional, divide the year up into
12 equal parts method.
 
Glossary of abbreviations
 
 
AGE		= Moons age in days since it became new.
 
D(AU)	= The suns distance from the earth, in Astronomical Units.
 
D(ER)	= The moons distance in Earth radii.
 
Exct Zodiac = Zodiac that the moon is in, exactly, no rounding to a 30 degree window.
 
LAT		= The moons latitude along the ecliptic, in degrees.
 
LONG or Mn LONG	= The moons longitude along the ecliptic, in degrees.
 
MM/DD/YYYY:HH:MM = Format in date and 24 Hour time UTC.
 
Sun Age	= The number of days since the last spring equinox.
 
Sun LAT	= The Suns latitude along the ecliptic, in degrees.
 
Sun LONG= The approximate position of the Sun in degrees latitude with reference to the earths equator.
 
 The software was built in C some of the parts of the code namely
the algorithms for the moon and sun position were available on-line
from
observatories. SAAO- NAO Technical Note No. 46(1978) and Moonlight
Cascade Observatory/BBS. Around the algorithms an interface was built
that drives the
program from the command line. I consider the data to be accurate, but
there are no guarantees as with any software. 
Code was then created to format the output. Tables in the code was
created, for example one to interpret the Zodiac sign correctly,
deriving the zodiac given the ecliptic longitude. 
Internal to the program the date that is input by the user is
converted to Julian date. The program is aware of the switch over from
Julian to Gregorian calender and accommodates this as well. The
Gregorian calender fix is to, force a date in the range 10/4 -
10/14/1582 to 10/15/1582.
  This forces the values in range, being that the calender omitted
9 days when switching from Julian to Gregorian. A table exists in the
code to
interpret where we are in the season, early,late and the midpoint by
determining the approximate midpoints of each season. The day of the
week is selected
using a look-up table function, the input to this table is a modulo 7
operation on the Julian date. Monday 12/3/2007 for example is JD
2454438. Doing the
operation 2454438 % 7 yields 0. An input of zero to the look-up table
references the string "Monday" from which the screen output is
generate. This is
similar to the operations for picking the Zodiac string as well as the
part of the Season, lunar phase. However these are provided by dividing
the month
into subsets of time for the lunar phase and dividing the angle of the
sun along the ecliptic (longitude) into the specific 30 degree sections
that
resolve into the 12 Zodiac symbols.  
For the lunar Zodiac a table was found on-line that resolves the lunar
position to the exact Zodiac. The premise here is that the Zodiac
regions in the
sky do not all take up 30 degrees, some are wider and some are
narrower. So a look-up table was constructed based on this fact to
resolved the lunar Zodiac more precisely. Remember the fact that the
Moon traverses the entire Zodiac in 27.321582241 days, this is its
complete course of 360 degrees of ecliptic longitude. The moon goes
through its phases every 29.530588853 days so this is divided into the
various phases in a look-up table within the
program. There are also similar relationships for the ecliptic latitude
for the moon and distance from the earth to the moon. 
While the moon on average rides along the ecliptic plane it oscillates
above and below it plus or minus approximately 5.1 degrees. The period
of this oscillation is 27.212220817 days. There are times when the moon
will ride 'high' in the sky during the month and then ride 'low' at the
opposite time
of the month (more closer to 2 weeks for half cycles, a fortnight). The
moons distance varies with a sort of ellipse relationship with a period
of
27.55454988 days, this as well is handled by the program and is given
in terms of earth radii. 
In this process phase based on the age of the room is converted to
degrees and the finally radians to carry out the actual math. From this
the results are displayed in degrees latitude/longitude, earth radii as
appropriate or fed into the Zodiac look-up table function. For the Sun
very similar calculations are carried out, so you can extrapolate in
your mind what was done for the moon is similarly done for the sun
calculations. 
 
The following is a printout of the help menu generated when the program is runs using the /? option 
Lunar phase and position & Solar position calculator DOS Version:00.9 
NOTE 1) Solar latitude is approximate. 2) Lunar Zodiac is exact.
Enter  lphase /t  at the command line to compute data for
 the moon on todays date.
Enter  lphase /c  to produce a perpetual calender view using
a starting date and a number of days to span out.
Enter  lphase /h  to produce a detailed output of lunar data
for one day on a 0.5 hour basis.
Enter  lphase /e  at the command line to produce 1 yr calender
data for up to the minute full/new moon & eclipses.
Otherwise run the program and enter the date
in MM/DD/YYYY format.
 
Entering the program with no parameters will prompt you for a date and show the following output.
Lunar phase and position & Solar position calculator DOS Version:00.9 
NOTE 1) Solar latitude is approximate. 2) Lunar Zodiac is exact.
Input date in this format MM/DD/YYYY 
Target Date: 12/1/2007  
Julian Date =  2454436        day = Saturday 
     Moon Data        
----------------------
phase         = Last quarter      
age           = 21.432411  days 
distance      = 61.464302  earth radii 
ecliptic 
 latitude     = 0.105118  
 longitude    = 158.001190  
constellation = Leo          
      Sun Data        
----------------------
season        = Late Autumn  
age           = 254.994125 (days since spring equinox)
distance      = 0.953412 AU 
aprx. latitude= -21.9 (with ref. to the equator)
ecliptic 
 longitude    = 248.908997      alt calc = 248.403625
constellation = Sagittarius
 
For the tabular output, potential eclipses are marked off as well.
The algorithm searches the entire year on a minute by minute basis for
when the moon crosses the ecliptic plane and marks these events off. It
also marks off the points where the moon is exactly full or new. This
mode is invoked by calling the program with the /e option. 
New and Full Moons Date and Time and eclipses.
MM/DD/YYYY:HH:MM          Day         Phase                      Age             Dist(ER)           LAT         LONG            Mn Zodiac  Solar LONG
01/07/2008:15:05	Monday   	*NEW            	0.000225	56.002979	-3.502999	286.661469	Sagittarius286.556732
01/22/2008:09:28	Tuesday  	*FULL            	14.765902	56.128639	2.397222	122.302750	Cancer     301.835297
02/06/2008:03:49	Wednesday	*NEW            	0.000225	56.400490	-1.122187	317.778534	Aquarius   317.070587
*02/20/2008:22:12	Wednesday	*FULL            	14.765902	59.869110	-0.234372	155.133789	Leo        331.224060
03/06/2008:16:33	Thursday 	*NEW            	0.000000	60.642876	1.572592	349.585266	Pisces     346.294556
03/21/2008:10:56	Friday   	*FULL            	14.765676	61.454948	-2.800189	183.824554	Virgo      1.248665
04/05/2008:05:17	Saturday 	*NEW            	0.000000	62.133255	3.827228	17.884167	Pisces     16.077461
04/19/2008:23:40	Saturday 	*FULL            	14.765676	63.759281	-4.582811	207.623703	Virgo      29.803162
05/04/2008:18:01	Sunday   	*NEW            	0.000000	63.571266	5.011314	41.203468	Aries      44.394379
05/19/2008:12:24	Monday   	*FULL            	14.765676	63.198814	-5.083253	234.785599	Libra      58.879509
06/03/2008:06:45	Tuesday  	*NEW            	0.000000	62.720821	4.793333	68.543419	Taurus     73.279495
06/18/2008:01:08	Wednesday	*FULL            	14.765676	62.070129	-4.161643	262.403992	Scorpio    87.619057
07/02/2008:19:29	Wednesday	*NEW            	0.000000	58.041470	3.234461	96.705940	Gemini     100.972939
07/17/2008:13:52	Thursday 	*FULL            	14.765676	57.342579	-2.075667	291.889771	Sagittarius115.276794
*08/01/2008:08:13	Friday   	*NEW            	0.000000	56.809528	0.770566	127.160133	Cancer     129.606400
*08/16/2008:02:36	Saturday 	*FULL            	14.765676	56.367432	0.590797	322.654419	Aquarius   143.990601
08/30/2008:20:57	Saturday 	*NEW            	0.000000	56.793522	-1.908690	162.338470	Leo        157.486954
09/14/2008:15:20	Sunday   	*FULL            	14.765676	57.378357	3.092191	357.692719	Pisces     172.044525
09/29/2008:09:42	Monday   	*NEW            	0.000676	58.050694	-4.054620	192.834625	Virgo      186.719177
10/14/2008:04:04	Tuesday  	*FULL            	14.765450	58.803432	4.728450	27.781933	Pisces     201.519135
10/28/2008:22:26	Tuesday  	*NEW            	0.000451	62.728092	-5.065466	220.980331	Virgo      215.445679
11/12/2008:16:48	Wednesday	*FULL            	14.765450	63.223751	5.041820	54.704449	Taurus     230.483215
11/27/2008:11:10	Thursday 	*NEW            	0.000451	63.574810	-4.659095	248.317261	Scorpio    245.624420
12/12/2008:05:32	Friday   	*FULL            	14.765450	63.765827	3.944679	81.857407	Taurus     260.845642
12/26/2008:23:54	Friday   	*NEW            	0.000451	62.124603	-2.949401	271.641693	Sagittarius275.097992
 
 In the above tabular chart the dates preceded by an asterisk are
potential eclipse dates. If the moon phase is listed as FULL for that
date the eclipse will be a lunar eclipse. If the moon phase is listed
as NEW for that day it will be a solar eclipse.  
Finally below is the tabular almanac output. This mode is invoked by calling the program with the /c option. 
The page on this siteAlmanac has an extended printout of this output. 
MM/DD/YYYY  Day         Phase               AGE     D(ER)   LAT     LONG    Exct Zodiac     Sun Age D(AU)   Sun LAT Sun LONG
12/01/2007	Saturday 	Last quarter    	21.432	61.46	0.11	158.00	Leo        		254.99	0.953	-21.9	248.91
---- Sagittarius	Late Autumn -----
12/02/2007	Sunday   	*Last quarter    	22.432	62.28	-1.06	170.45	Leo        		255.99	0.953	-22.1	249.92
12/03/2007	Monday   	Last quarter    	23.432	62.93	-2.18	182.58	Virgo      		256.99	0.953	-22.2	250.94
12/04/2007	Tuesday  	Waning crescent 	24.432	63.40	-3.18	194.49	Virgo      		257.99	0.953	-22.3	251.95
12/05/2007	Wednesday	Waning crescent 	25.432	63.68	-4.00	206.26	Virgo      		258.99	0.953	-22.5	252.97
12/06/2007	Thursday 	Waning crescent 	26.432	63.77	-4.62	217.99	Virgo      		259.99	0.953	-22.6	253.98
12/07/2007	Friday   	Waning crescent 	27.432	63.71	-4.99	229.74	Libra      		260.99	0.953	-22.7	255.00
12/08/2007	Saturday 	NEW             	28.432	63.53	-5.10	241.58	Libra      		261.99	0.952	-22.8	256.01
12/09/2007	Sunday   	NEW             	29.432	63.24	-4.93	253.53	Scorpio    		262.99	0.952	-22.9	257.03
------------------ Lunar Month 1 ------------------
12/10/2007	Monday   	NEW		 	0.902	62.88	-4.51	265.63	Scorpio    		263.99	0.952	-23.0	258.04
12/11/2007	Tuesday  	Waxing crescent 	1.902	62.45	-3.84	277.89	Sagittarius		264.99	0.952	-23.1	259.06
12/12/2007	Wednesday	Waxing crescent 	2.902	61.97	-2.97	290.32	Sagittarius		265.99	0.952	-23.1	260.08
12/13/2007	Thursday 	Waxing crescent 	3.902	61.44	-1.95	302.94	Capricorn  		266.99	0.952	-23.2	261.09
12/14/2007	Friday   	Waxing crescent 	4.902	60.85	-0.82	315.78	Aquarius   		267.99	0.952	-23.3	262.11
12/15/2007	Saturday 	First quarter   	5.902	60.22	0.36	328.84	Aquarius   		268.99	0.952	-23.3	263.13
12/16/2007	Sunday   	*First quarter   	6.902	59.55	1.51	342.17	Aquarius   		269.99	0.952	-23.4	264.14
12/17/2007	Monday   	First quarter   	7.902	58.87	2.59	-4.21	Pisces     		270.99	0.951	-23.4	265.16
12/18/2007	Tuesday  	First quarter   	8.902	58.21	3.52	9.71	Pisces     		271.99	0.951	-23.4	266.18
12/19/2007	Wednesday	Waxing gibbous  	9.902	57.62	4.27	23.92	Pisces     		272.99	0.951	-23.5	267.20
12/20/2007	Thursday 	Waxing gibbous  	10.902	57.14	4.80	38.40	Aries      		273.99	0.951	-23.5	268.22
12/21/2007	Friday   	Waxing gibbous  	11.902	56.82	5.07	53.08	Taurus    		274.99	0.951	-23.5	269.23
12/22/2007	Saturday 	Waxing gibbous  	12.902	56.71	5.07	67.89	Taurus    		275.99	0.951	-23.5	270.25
---- Capricorn  	      Winter Solstice -----
12/23/2007	Sunday   	FULL            	13.902	56.84	4.80	82.71	Taurus    		276.99	0.951	-23.5	271.27
12/24/2007	Monday   	*FULL            	14.902	57.20	4.27	97.44	Gemini     		277.99	0.951	-23.5	272.29
12/25/2007	Tuesday  	FULL            	15.902	57.79	3.52	111.97	Gemini     		278.99	0.951	-23.5	273.31
12/26/2007	Wednesday	Waning gibbous  	16.902	58.56	2.58	126.18	Cancer     		279.99	0.951	-23.4	274.33
12/27/2007	Thursday 	Waning gibbous  	17.902	59.45	1.51	139.99	Leo        		280.99	0.951	-23.4	275.35
12/28/2007	Friday   	Waning gibbous  	18.902	60.41	0.35	153.38	Leo        		281.99	0.951	-23.4	276.36
12/29/2007	Saturday 	Waning gibbous  	19.902	61.34	-0.82	166.31	Leo        		282.99	0.951	-23.3	277.38
12/30/2007	Sunday   	Last quarter    	20.902	62.18	-1.95	178.82	Virgo      		283.99	0.951	-23.2	278.40
12/31/2007	Monday   	*Last quarter    	21.902	62.87	-2.98	190.99	Virgo      		284.99	0.951	-23.2	279.42
 
Back to Top
  
Wxstat program  
The Wxstat so called weather statistics program is
a branch off of the lunar phase program that uses the core
functionality of it. Only the sun data
is displayed and additional calculations are performed based on this.
The first important calculation beyond the sun data performed is the
calculation
of the equation of time. 
I bought an digital appliance timer that is capable
of turning on or off with sunrise and sunset and vice versa. It allowed
you to pick 3 regions of
latitude in order to calculate the approximate sunrise and sunset.
Using this device got me interested in how simple of an algorithm could
be used to
calculate an approximate sunrise and sunset. I essence I was trying to
reverse engineer what might be going on inside the device. This lead me
to
expand on the lunar and sun program that turned into wxstat. The
following is a description of what came out of those thoughts. 
  The equation of time is the sum of two offset
sine curves, with periods of one year and six months respectively. The
equation of time is the difference, over the course of a year, between
time as read from a sundial and a clock. It can be ahead by as much as
16 min 33 s (around November 3) or fall behind by as much as 14 min 6 s
(around February 12). It results from an apparent irregular movement of
the Sun caused by a combination of the obliquity of the Earths rotation
axis and the eccentricity of its orbit. The equation of time is
visually illustrated by an analemma. Apparent solar time (or true or
real solar time) is the time indicated by the Sun on a sundial, while
mean solar time is the average as indicated by clocks.
A length of daylight calculation is performed
using the sun data. The calculation is based off of the sine of the
angle of the suns longitude along the
ecliptic. At the equinoxes the calculation is set so that the result is
zero. At the summer solstice the result is +1, at the winter solstice
the result
is -1. To this result 1 is added so that the values will run from +2 to
0, with the value being 1 at the equinoxes. For my location, I know
that the
maximum length of day is 15.25 hours and the minimum is 9.1 hours. The
following formula yields the length of day. 
  retVal = (sin(suns ecliptic longitude)+1)*(UPPER_LIMIT - LOWER_LIMIT)/2 + LOWER_LIMIT
  
where...
 UPPER_LIMIT = 15.25 LOWER_LIMIT = 9.1 
  
Once the length of day is known the approximate
sunrise and sunset can be calculated by using the equation of time. The
equation of time becomes the offset applied. For example with a length
of day of 12, the sun will rise 6 hours before noon and set 6 hours
after noon, using standard time. If the
equation of time is 5 minutes this applies an offset of 5 minutes at
either end. Effectively the approximate sunrise and set in that example
would be 6:05 AM and PM. The equation of time lets you line up mean
solar time with apparent solar time. The math behind the length of day
which is based on mean solar time has to be converted to apparent solar
time( time by the sundial) to yield the sunrise and sunset. There are
other more accurate ways
to derived the sunrise and set times but this method gives a quick and
fairly close approximation. 
Average daily temperature calculation. This
calculation required some preliminary research into what the lowest and
highest daily average temperatures and when they occur. It was
determined by looking at data from the NCDC that for the Binghamton
region that the temperature excursions lag the actual seasons by
approximately 36 degrees. See the weather
class page for more information on climates.The lowest average
temperature for the winter season here will occur Jan 27, 2007. The
maximum average summer temperature will occur July 27, 2007. Knowing
these 2 points and looking up the average temperature on both is what
is needed to generate a approximation for average temperature. It is
basically a sine curve that is offset 36 days from the seasons so that
its minima and maxima occur ,Jan 27 and July 27 respectively. The
scaling function is similar to the function that generates the length
of day.
 
  temp = sin((age + SEAS_OFFSET) * DAY_RADIAN);
  retVal = (temp+1)*(upperLim - lowerLim)/2 + lowerLim;
 Where upper and lowerLim are values passed into the
function for the extremes on Jan 27 and July 27. From this point
approximations were picked for offsets to generate the average high and
low temperatures. This simple approximation holds close to the real
averages and is a fairly good guideline
as to whether any particular day is above or below average. This helps
gain more familiarity with the climate in general. Gaining some
familiarity
with weather and climate is one of the points made in the weather class
that I have taught. Using simple math relationships as examples helps
to reveal the cyclic nature of the suns position in the sky in
different seasons, length of day and the average temperature.
 
The following is a printout that the wxstat program outputs for an example. 
 DOS Version:00.1 
NOTE 1
Input date in this format MM/DD/YYYY 
Target Date: 12/1/2007  
Julian Date =  2454436        day = Saturday 
      Sun Data        
----------------------
season        = Late Autumn  
age           = 254.994125 (days since spring equinox)
aprx. latitude= -21.9 (with ref. to the equator)
Apx.Day Len.   09:15  hrs 
Apx.Rise: 07:14 EST	Apx.Set: 16:28 EST
Equation of Time 11:40 min
Fudge Factor:0.018039
Mean moon rise: 00:-10 
   Weather Data  
 ----------------------
Avg Low Temp   17 F	Avg High Temp  35 F	Mean Temp      26 F
 
Back to Top
  
Cmdcalc program  
Cmdcalc is a very simple program written in BASIC
which is then compiled. It is a command line calculator that handles
very basic math in order to
get a quick answer to simple math while working on a PC. It takes up to
3 arguments, 2 are the numbers upon which the operation is to be
performed
and the third argument is the "+ Add","- Sub","/ Div","* Mul","p Raise
to Power","v Root" and M for memory. An example on the screen
would look like the following. 
c:\cmdcalc 5*5 25 c:\
  
 
When this is executed the 25 is also stored
into a cmdcalc.dat file. So that the calculator can be slightly more
powerful and capable of stringing together operations. The M for memory
is used instead of an entered value, the M must be the first character
that is entered.
An example on the screen would look like the following.
 
c:\cmdcalc M*5 125 c:\
  
 
The BASIC for this program is so simple that I have included the source as follows. 
 
10 ver = 1.02:dim a$[10], a[10]:arg = 1 20 if command$ ="/?" then 5000 25 lencommand = len(command$) 26 open "c:\tools\cmdcalc.dat" for input as #1:input #1,readdat:close #1
 
  30 for stepping = 1 to lencommand 50 temp$ = mid$(command$,stepping,1) 60 if  temp$ => "0" and  temp$ <= "9" or temp$ = "." then a$[arg] = a$[arg] + temp$:goto 99   ' A number 62 incr arg	 65 a$[arg] = temp$ ' An operator 70 incr arg	 99 next stepping
 
  100 for n = 1 to arg: REM print">>";a$[n];"<<" 110 if left$(a$[n],1) => "0" and left$(a$[n],1) <= "9" then a[n] = val(a$[n]) :  REM print a[n] 120 next n
 
  200 for n = 1 to arg 205 if n = 1 then gosub 2000 210 if a$[n] = "+" then accum = accum + a[n+1] 220 if a$[n] = "-" then accum = accum - a[n+1] 230 if a$[n] = "/" then accum = accum / a[n+1] 240 if a$[n] = "*" then accum = accum * a[n+1] 250 if a$[n] = "p" then accum = accum  ^ a[n+1] 260 if a$[n] = "v" then accum = accum  ^ (1/(a[n+1])) '  root shortcut 270 if a$[n] = "r" then accum = accum  ^ (a[n+1]*.5) '  sqr root shortcut
  299 next n
  300 print accum 310 open "c:\tools\cmdcalc.dat" for output as #1 320 print #1,accum 330 close #1 999 end
  ' Fetch value from memory of last calculation. 2000 if a$[2] = "M" then accum = readdat else accum = a[1] 2010 return
  5000 print "Command Line Calculate, Simple Form.    V";ver 5001 print "Does not consider order of operations." 5002 print "Allows use of M as first character to substiute contents of memory for a value." 5005 print:print:print"Commands..." 5010 print "+  Add" 5020 print "-  Sub" 5030 print "/  Div" 5040 print "*  Mul" 5050 print "p  Raise to Power" 5060 print "v  Root" rem 5070 print "r  Sqr Root"
  5999 end
  
Back to Top
  
Cellular Automata Graphics Programs  
These programs were based off of reading New Kind of Science, A - Stephen Wolfram - Wolfram Media
which covers cellular automata. While reading the book it seemed that
it would be interesting not only to see the cellular automata work on
something other than the printed page, but to
learn more detail by becoming familiar with algorithms that can
generate these patterns. Ideally this would be carried out graphically. 
The end result was an entire suite of programs that
progressed from an initial 'experiment' with the idea into more
details. meanwhile tuning the
logic for speed and best graphical representation. The programs were
written in BASIC which was then compiled into EXE files. These BASIC
files would
run the monitor in a CGA graphics mode and draw the CA(cellular
automata) on the screen pixel by pixel. 
Below are some screenshots of the outputs for a few
of the more interesting CA 8-bit rule (0-255)diagrams. This shows a
progression from simple, patterned, fractal, mixed pattern/chaos and
finally chaotic. The thumbnails are a bit distorted
due to re-sizing, click on them for a larger cleaner 640 x 480 view. 
         
      
      
                
 
CA basically exhibits a few types of behavior. It can have the
following behavior and the programs draw graphical representations of
it. It can dead end and do nothing. Some cases don't go anywhere,
nothing happens past the initial seed pixel which is intentional put on
the screen. It
can draw a straight or angled one dimensional line off of the initial
seed pixel. It can fill the screen either with one solid color or a
pattern such
as alternating lines. It can produce a filled area of additive growth,
such as a filled triangle that extends off of the seed pixel. It can
produce
regular and nested fractal patterns, which usually contain triangular
forms. Finally it can produce, most surprising, chaos, patterns that
look quite
random but seem to have islands of order within them. I am not going to
go into the details of CA here for a deeper look go to
Stephen Wolfram A New Kind of Science where the entire text is available on line. For more one chaos
theory material on this site see the Recursive Logistic Equation Page. 
The basic concept uses AND/OR type of logic and a 8 bit bitmap to
decide what color a pixel will become in a particular row and column
based on
values in the row before it at the positions directly above, above and
to the left and above and to the right. The decisions made are based on
a rule
number. For example rule 0 = 00000000 results in a non-operation, no
matter what the previous row had for the state of the pixel directly
above and left/
right, the new pixel will be blank. The rule 255 = 11111111 will turn
on the new pixel no matter what the state of the pixel directly above
and left/
right. In between there are a bunch of different rules that respond by
say turning on the new pixel when the pixel above it is on but the ones
above it to the left and right are not on for example. Which would be
rule 64 (0100000). The BASIC code for the pixel operations is as
follows. 
 
230 if point(x-1,y) <> 15 and point(x,y) <> 15 and point(x+1,y) <> 15 then pset(x,y+1),a[7]
240 if point(x-1,y) <> 15 and point(x,y) <> 15 and point(x+1,y) = 15 then pset(x,y+1),a[6]
250 if point(x-1,y) <> 15 and point(x,y) = 15 and point(x+1,y) <> 15 then pset(x,y+1),a[5]
260 if point(x-1,y) <> 15 and point(x,y) = 15 and point(x+1,y) = 15 then pset(x,y+1),a[4]
270 if point(x-1,y) = 15 and point(x,y) <> 15 and point(x+1,y) <> 15 then pset(x,y+1),a[3]
280 if point(x-1,y) = 15 and point(x,y) <> 15 and point(x+1,y) = 15 then pset(x,y+1),a[2]
290 if point(x-1,y) = 15 and point(x,y) = 15 and point(x+1,y) <> 15 then pset(x,y+1),a[1]
300 if point(x-1,y) = 15 and point(x,y) = 15 and point(x+1,y) = 15 then pset(x,y+1),a[0]
 
 
The function point returns TRUE or FALSE based on whether or not the
pixel in that location contains the value 15, which is white in CGA, 4
bit color.
Black corresponds to 0. Based on the logic <> ( not equal) or =
(equal) plus anding the previous left, right and center pixels the new
pixel in the row below the old is set using the pset function. The pset
sets the pixel to color value a[0...7], the array a is encoded with the
rule. What this means
is that for let's say rule zero a[0] to a[7] are set to zero for black.
So no matter what happens a black pixel is generated. As you can image
if the rule turns the pixel black no matter what the CA will die out.
The inverse case of 255 sets all of a[0] to a[7] 15 white, which floods
the screen with
white. The truth table for the rule number versus the logic used to
represent it is as follows. 
 
Rule LCR
128  000
 64  001
 32  010
 16  011
  8  100
  4  101
  2  110
  1  111
 
 
 L represents Left, C center and R right for the pixels(cells) above
the pixel that needs to be drawn. The logic is such that the values
shown yield
a true. For instance rule 128 would mean Left pixel white = FALSE and
Center pixel white = FALSE and Right pixel white = FALSE means paint
new pixel
with. Obviously the rules can be compounded to yield all the values
from 0 - 255. For example rule 30 means apply 16+8+4+2 = 30, so apply
the ones
listed (16,8,4,2) in the truth table together. Thirty would be 011 AND
100 AND 101 AND 110. 
Later versions of the programs used coding schemes for color so that
the pixels were not just black and white but a shade of color depending
on which
part of the logic was being applied. This was done by loading the array
a with values in terms of CGA color in the color handler subroutine.
Looking
at the code itself is the best way to understand it. 
 
'color handler
1000 if n = 7 then a[n] = 0 '!RGB = blk
1001 if n = 6 then a[n] = 1	'XXB = blue
1002 if n = 5 then a[n] = 2	'XGX
1003 if n = 4 then a[n] = 3	'XGB = torq
1004 if n = 3 then a[n] = 4	'RXX
1005 if n = 2 then a[n] = 5	'RXB = pur
1006 if n = 1 then a[n] = 14 'RGX = yel
1007 if n = 0 then a[n] = 8	 ' RGB but not, use gray
1008 return
 
 
Where n is the number of the array position for the corresponding
line of the rule in the truth table (think 128 = 2^7), n is the
exponent in
terms of powers of 2. The color runs from black to gray, gray chosen
instead of white to yield a higher color contrast. !RGB means black,
with
RGB ( Red/Green/Blue) turned off. XXB means turn CGA blue on a value of
1. XGB means green and blue ON for torquise, a value of 3 and so on.  
 
This is the core functionality of the programs. Other than the logic
above the initialization section converted the rule entered by the user
0-255
to the binary pattern of the rule which loads the color into the array
a. From this point there is a nested looping that runs from 0-640 for
the X direction and 0 - 480 for the Y direction. The loops are such
that the X incrementing loop is inside of the Y loop. The program
effectively scans each horizontal line pixel by pixel and performs a
return at the end to the next row in the Y direction. In order to start
off somewhere an initial seed
pixel or pixels is needed in the first row. In the code there is an
initialization that writes one white pixel in the center of the first
row. I have
also tried to put multiple initial pixels and patterns of them, this
makes for interesting graphics as the multiple CA diagrams crash, merge
or
bounce off of one another. One of the most interesting ones looks like
the migration of a fatigue crack in a solid material. For more on this
topic on this site see
CAFL Control Algorithm 
      
Back to Top
  
CAT Transceiver control program  
This program is used to control the Yaseu HF
Transceiver CAT serial link. I am using a FT767GX in particular. The
code is written in C. The transceiver
has a serial port that operates at 4800 baud. The program was written
over the Winter 2005-06, when there wasn't much else going on. The
depths of winter become a hibernation mode time, a perfect time for
indoor projects like these. The protocol followed while writing this
program was not to try connect right away with the transceiver. Trying
to write a program to control the transceiver and using it would be
flying blind. I already had written a terminal program to allow 2 PC's
to connect using the serial port. The core of this program was built on
to create the CAT control program by a first sending a basic message
and looking for the echo and then sending the acknowledge. Another
program was then written from this that simulated what the
transceiver would be doing during the exchange of messages. The
transceiver simulator put what it received on the serial bus on the
screen and then
echoed back the commands to the main program, which in return displayed
this on the screen and returned an acknowledge when there was a match.
Using
the main CAT control program and a simulation program for the
transceiver and linking the 2 pc's in my office together serially made
the debugging go fast. Once a few basic messages went through OK it was
time to concentrate on decode the status messages shown below (Figure
2). Once a few basic
5 byte status messages decoded fine it was time to complete the
program. This basically meant handling every command in the list. At
first I just tried out turning the CAT control off and on and adjusting
frequency, now I filled in the blanks for all of the rest of the
messaging. 
Once the program could send all of the commands and
receive 5 byte status blocks back from the transceiver simulator, I
tried it out on the real
transceiver. It was time to solder up an adapter cable and let it run.
From the very beginning the transceiver would respond correctly to the
commands sent
by the PC. The PC was glitching on the echo and the status blocks and I
had temporarily set things up to unconditionally send an acknowledge to
the
transceiver. I confirmed that part of it worked. The processor in the
transceiver which is circa 1987 runs slow, it takes time to react to
the commands that
come across the serial line. All I needed to put into the program was a
5ms delay between messages and all of it worked fine. I finished up by
writing the
code to handle all 86 bytes of the status message. This was once again
done using the transceiver simulator program to play against the main
CAT control
program for some of the cases. I did not test them all with the
simulator because there was a lot of redundancy in the status message. 
Eventually it all worked well and I went on to write
some DOS batch files that can execute the CAT control program
automatically. There is even a feature to active certain controls based
on the time of day, so the transceiver can change controls on a
schedule through the batch file as well.
Below is the entire setup and a screenshot of a message transaction. 
 
 
The CAT control light comes on when the transceiver is under remote control. 
 
The screen on the PC showing CAT commands being executed. In the first the commandcat modesel am is being executed. This sets the mode to 
AM. In the second the command cat vfomr vfoa followed by cat vfomr vfob is sent. This command swaps between the two variable 
frequency oscillators in the transceiver. The frequency switches to 10MHz and then back to 7MHz. 
 
 
The command structure for controlling the transceiver is fairly simple. The following is an example of
the transaction across the serial bus for the command that would be entered as cat fset 1425000. 
Protocol: 4800-1-8-2-N
Ex:   FSET 1425000  (14.25000)
            
            |01|42|50|00|FSET ... becomes...  CMD Block = 0x00|0x50|0x42|0x01|0x08
                                                          LSD                  MSD
Transaction:
SI ------|0x00|0x50|0x42|0x01|0x08|--------------------------|0x??|xx|xx|xx|xx|------------------
                 command                                             ACK
SO --------------------------------|0x00|0x50|0x42|0x01|0x08|------------------|SB|0x01|42|50|00|
                                             echo                                  5-byte Status(5-86 is poss.)
(5ms gaps between SO and SI's.)
 
 
The following image is a screenshot of cat fset 009690, setting the frequency to 9.69MHz. 
 
Yaesu provides all of the information in the manual that allows you
to build code to control the transceiver. As you can see in the example
above.
First a command is sent, the transceiver then echoes this back,
acknowledge is sent back to the transceiver, then transceiver then
processes the command,
then the transceiver sends back a variable length status. In the status
SB is the leading status byte which is interpreted as follows. 
 
Status Byte(SB)
BIT
7   CAT         1 = ON
6   CLAR        1 = ON
5   MR          1 = ON
4   VFO A/B     1 = VFO B
3   SPLIT       1 = ON
2   Tx Inhib    1 = ON
1   H/G         1 = G
0   PTT         1 = TX
 
 
The following is the list of commands that are possible, I kept with
the syntax used by Yaesu. In other words CATSW in there list is sent
out as
cat catsw on by the program. 
 
                                COMMANDS
       (Hex)MSD (BCD)  LSD
Instr   CMD D1  D2  D3  D4      Remarks                                               Status Size
-------------------------------------------------------------------------------------------------
CATSW   00  P1  XX  XX  XX      p1	value:	OO=ON. 01=OFF		                           86
CHECK   01  xx  xx  xx  xx      No op:	return status Only		                           86
UP10Hz  02  xx  xx  xx  xx      Step frequency UP 10 Hz		                                5
DN10Hz  03  xx  xx  xx  xx      Step frequencv down 10 Hz	                            	5
PRGUP   04  p1  p2  xx  xx      p1 & p2   *                                                 5
PRGDN   05  p1  p2  xx  xx      p1 & p2   *                                                 5
BANDUP  06  xx  xx  xx  xx      Step UP one Band**			                            	5
BANDDN  07  xx  xx  xx  xx      Step down one Band**		                                5
FSET    08  p1  p2  p3  p4      Frequency Set	(see EXAMPLE)	                            5
VFOMR	09	p1  xx  xx  xx		VFO/Memory Select:	p1	value:	00=VFO A,01 =VFO B, 02=MR   5
MEMSEL	0A	p1	xx	xx	xx	    p1	value = memorv no.(0 -9)                            	8
MODESEL	0A	p1	xx	xx	xx      p1	value: 10h=LSB,	11h=USB,12h=CW.13h=AM 14h=FM,15h=FSK    8
HGSEL	0A	p1	xx	xx	xx	    p1	value:	20h=HAM		21h=GEN		                       26
SPLITOG 0A 30h	xx	xx	xx      Toggles SPLIT on/off                          	    	   26
CLARTOG	0A 40h	xx	xx	xx	    Toggles Clarifier on/off	                               26
MTOV	0A 50h	xx	xx	xx	    Memory to VFO			                            	   26
VTOM	0A 60h	xx	xx	xx	    VFO to Memory				                               86
SWAP	0A 70h	xx	xx	xx	    Swap VFO and Memory			                               	5
ACLR	0A 80h	xx	xx	xx	    Turn off SPLIT. CLAR. OFFSET                            	5
TONESET	0C	p1	p2	p3	xx	    p1,p2 = Tone Freq(BCD) *** p3=00 for Low-Q  01 for Hi-Q 	5
ACK	    0b	xx	xx	xx	xx	    Required after each Code	                            no echo
-------------------------------------------------------------------------------------------------
xx = any value: byte will be echoed, but will not affect command function.
* 00 00 to 99 99 representing 0 to 99.99 kHz (BCD)
.
** Band'steps determined by current Ham/Gen selection: Ham bands, or 0.5
MHz. 
*** 06 70 to 25 03 representing 67.0 to 250.3 Hz (BCD). See Tone
Table 3 for list of valid tone frequencies.
 
 
 
Figure 2, the typos in this are not mine. The OCR from the bed scanner had trouble with reading this out of the FT767 manual. 
Byte	Contents						Rer.
No.						Table
1	Status Flaas .			1
2-5	Oneratina Freauencv (BCD)			2
6	Selected CTCSS Tone			3
7	Selected Mode			4
8	Selected Memorv Channel No.	(0- 9)	
9-12	Clarifier Freauencv (BCD)			2
13	Clarifier CTCSS Tone*			3
14	Clarifier Mode			4
15-18	VFO A FreQuencv (BCD)			2
19	VFO A CTCSS Tone*			3
20	VFO A Mode						4
21-24	VFO B Freauencv (BCD)..			2
25	VFO B CTCSS Tone*			3
26	VFO B Mode						4
27-30	Memorv Channel	0 Freahencv (BCD)	2
31	Memorv Channel	0 CTCSS Tone*		3
32	Memorv Channel 0 Mode			4
33-38	Memorv Ch 1	(same format as 27-32)**
39-44	Memorv Ch 2	(same format as 27-32)**
45-50	Memorv Ch 3	(same format as 27-32)**
51-56	Memorv Ch 4	(same format as 27-32)**
57-62	Memorv Ch 5	(same format as 27-32)**
63-6s..	Memorv Ch 6	(same format as 27-32)**
69-74	Memorv Ch 7	(same format as 27-32)**
75-80	Memorv Ch 8	(same format as 27-32)**
R1-RF;	Mpmnru ('10	Q
 
 
The following screenshot is a status dump that occurs when cat catsw on is sent. 
 
Debug mode- The CAT control program provides a debug mode for both the CAT.exe control program and the cattest.exe simulator program. When
either program is called with the /d argument, debugging output is provided. This is mostly for the development of the program, in the case of
the CAT program itself it can be used to troubleshoot the serial connection to and from the transceiver.
 The following are a few screenshots of the CAT control program ran
with debug output The first is setting the frequency in debug mode, the
second is setting the modulation type to USB( upper side band) and the
third is a tweak the frequency up 10 Hz command.
 
  
 By setting the frequency to 012345 which translates into 12.34500
MHz it is obvious from the debug data what is going on. The command for
FSET is
8, the 10's and 100's Hertz are set to 0. So the command out is 0|45|23|1|8, CAT always sends things out 'backwards' and each byte sent out is a
type of BCD-HEX format that goes as high as 99. The transceiver echoes back 0|45|23|1|8 to the CAT program. The CAT program reechoes the frequency
and 0xb which is the ack upon which the transceiver changes the frequency to 12.34500. Then the transceiver sends out a 5 byte status to the
CAT program.
The status of 0|45|23|1|80.
The status contains the frequency and 0x80 which is a bit map of flags,
in this case with bit 7 set. Looking at the
table below the status tells that CAT is ON, in control of the radio,
VFO is A H/G(HAM/GENERAL COVERAGE) is set to H (HAM) and PTT
 
Status Byte(SB)
BIT
7   CAT         1 = ON
6   CLAR        1 = ON
5   MR          1 = ON
4   VFO A/B     1 = VFO B
3   SPLIT       1 = ON
2   Tx Inhib    1 = ON
1   H/G         1 = G
0   PTT         1 = TX
 
 
  
  
Back to Top
  
Software Portfolio 
I am keeping a list of software that I have written for reference and for anyone that is interesting in more detail. 
Software Portfolio
Back to Top
  
  
  
 
 
Original Build Date:12-2-2000  
Last updated 3-15-2010
 
 
 |