PDA

View Full Version : A REALLY accurate clock.



Charles Linquis
- 26th September 2011, 04:15
Need to know the time - accurately for your next project?

The code below allows your PIC to log into a network timeserver and it (eventually) writes the time to a Dallas RTC (code not supplied).
The PIC checks the NET TIME every power-up and thereafter every 4 hours. If it doesn't make connection, it tries an alternate time server. If THAT doesn't work (after retries) it gives up and tries again 4 hours later. A Lantronix XPort handles the connection to the net.

The PIC normally reads the time from the Dallas RTC. The clock is self-setting and self-correcting, as long as you have a network connection.

And all of you using 16F chips, time to upgrade! This sub requires LONGS.

;-----------------------------------------------------------------------------------------------------------------------------------------------
Net Time' is the number of seconds since Jan 1 1900

This sub accomodates for leap years, GMT offsets and Daylight Savings Time.

The sub assumes you are in the present century, so it takes a shortcut by pre-subtracting the number of seconds from Jan 1 1900 to
Jan 1 2009.

It should be self-explanatory.
;----------------------------------------------------------------------------------------------------------------------

Hoffset is the hours offset from GMT
Sign = "1" or "2" depending on whether you are earlier or later than GMT
DST = 1 if you are in Daylight Savings Time (Another part of the PGM changes that value when appropriate).




GETNETTIME:
NETRETRYCOUNT = 0

GETNETTIME2:

HSEROUT [13,10,"TIMESERVER ",#TSIP1,".",#TSIP2,".",#TSIP3,".",#TSIP4,13,10]
PAUSE 100

THEADER[0] = $2 ' STX
THEADER[1] = TSIP1 ' DESTINATION IP
THEADER[2] = TSIP2
THEADER[3] = TSIP3
THEADER[4] = TSIP4

THEADER[5] = 0 ; DESTINATION PORT HIGHBYTE
THEADER[6] = 123 ; DESTINATION PORT LOWBYTE

LRC1 = 0
LRC2 = 0

For X = 1 to 6
LRC1 = LRC1 ^ THeader[x]
next X

THEADER[7] = LRC1
THEADER[8] = 0
THEADER[9] = 48 'Data Length lowbyte

;Send the header
HSEROUT [13,10]
For X = 0 to 9
HSEROUT2 [THeader[X]]
Next X

LRC2 = LRC2 ^ THeader[8]
LRC2 = LRC2 ^ THeader[9]

;Send the data
HSEROUT2 [$1B]
LRC2 = LRC2 ^ $1B
For X = 0 To 46
HSEROUT2 [0]
LRC2 = LRC2 ^ 0
NEXT X

;Send the Checksum (LRC)

HSEROUT2 [LRC2]
getresponse:
HSERIN2 1000,NoResponse,[Wait($2)]
hserin2 200,NoResponse,[SKIP 41,TimeNow.Byte3,TimeNow.Byte2,TimeNow.Byte1,TimeN ow.Byte0]

READ 851,HOFFSET

IF sign = "1" then
if DST = 1 and HOffset = 0 THEN
Sign = "2"
GOTO OtherSide
ENDIF

TimeNow = Timenow - ((HOffset - DST) * 3600)
ENDIF

OtherSide:
IF Sign = "2" THEN

TimeNow = TimeNow + ((Hoffset + DST) * 3600)
ENDIF

SINCEJAN2009 = TIMENOW - 3439756800 ; 3439756800 is the #of sec from Jan1 1900 to Jan1 2009

RUNNINGSECONDS = SINCEjAN2009
YR = 2009

GETYEAR:

LEAP = (YR//4) ; = 0 if leap year

if LEAP = 0 then
SecondsInYear = 31622400 ;366*60*60**24

ELSE
SecondsInYear = 31536000 ;365*60*60*24

endif

If RunningSeconds > SecondsInYear Then
RunningSeconds = RunningSeconds - SecondsInyear
YR = YR + 1
GOTO GetYear
ENDIF

Mo = 1 ; Start with Month = 1


GETMONTH:
IF LEAP > 0 THEN
lookup2 MO,[0,2678400,2419200,2678400,2592000,2678400,2592000, 2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth
ELSE
LOOKUP2 MO,[0,2678400,2505600,2678400,2592000,2678400,2592000, 2678400,2678400,2592000,2678400,2592000,2678400],SecondsInMonth
ENDIF

If RunningSeconds >= SecondsInMonth THEN
RunningSeconds = RunningSeconds - SecondsInMonth

MO = MO + 1
GOTO GETMONTH
ENDIF
FINDDAYS:

DA = RUNNINGSECONDS/86400
RUNNINGSECONDS = RUNNINGSECONDS//86400

HR = RUNNINGSECONDS/3600
RUNNINGSECONDS = RUNNINGSECONDS//3600

MN = RUNNINGSECONDS/60
RUNNINGSECONDS = RUNNINGSECONDS//60
SC = RUNNINGSECONDS

Da = Da + 1
HSEROUT [13,10,13,10,DEC2 HR,":",DEC2 MN,":",DEC2 SC," ",DEC2 MO,"/",DEC2 DA,"/",#YR,13,10]

Return

amgen
- 26th September 2011, 04:36
Cool stuff,
did you keep a few vars to hold "last update" or last update time ?
And, wouldn't it be convienent to have a time server to give;
simple to read bytes........ yr,month,day-of-week, month day,hr,min,sec,AM/PM .......8 specific bytes in some order,
The request could be like .........Give Simple uP Time for EST (eastern standard time) and the server could do all calculations.

Don

lester
- 26th September 2011, 05:57
Promoted to an article in the WIKI - Code Examples section (http://www.picbasic.co.uk/forum/content.php?r=451-A-REALLY-accurate-clock.)

Charles Linquis
- 26th September 2011, 06:31
I have a LOT of other variables. Most of my 18F8723's chips are 98% full (~10K lines of code). For a lot of reasons, I can't post the whole thing here.

Believe it or not, I also have a complete SNMP V2 agent running in PBP!

dhouston
- 26th September 2011, 13:24
Do you have an SMTP routine with authentication that you could post?

Charles Linquis
- 27th September 2011, 02:38
I have an SMTP routine, but I have posted enough stuff lately that I have to "back off". I do owe my employer a lot, and I have to respect the property that is rightfully theirs.

dhouston
- 5th October 2011, 19:05
Here's a link to some SMTP with Authentication (http://www.codeproject.com/KB/IP/smtpauthlogin.aspx) code that those with the need can translate to PBP.

Charles Linquis
- 5th October 2011, 19:28
Dave,

I have a complete SNMP (V2) agent in PBP as well. Three different encoding schemes in every packet!

cncmachineguy
- 5th October 2011, 21:14
But Charles, is that part of the "not allowed to post" code?

Charles Linquis
- 5th October 2011, 23:07
Unfortunately, yes. I shouldn't have even mentioned it. I'm pretty proud of it, though!:)

cncmachineguy
- 6th October 2011, 01:04
Well it does at least prove it can be done, so for that you get a point. :) but wait- you started picking on the 16f guys again, so I must subtract half a point. So you are still half good- LOL

Charles Linquis
- 6th October 2011, 03:25
I'm actually slowly rewriting my SNMP routines to take advantage of ArrayRead and ArrayWrite. They simplify things a bit, and it also makes the code more understandable and maintainable.
And I'm not really picking on people who use 16F chips. It isn't their fault that they are misinformed.

Byte_Butcher
- 6th October 2011, 17:43
And I'm not really picking on people who use 16F chips. It isn't their fault that they are misinformed.

We're not necessarily misinformed... we just have a lot of old stock to burn up still. :p

Mike, K8LH
- 6th October 2011, 23:15
And I'm not really picking on people who use 16F chips. It isn't their fault that they are misinformed.
May I ask what you mean by 'misinformed', please?

Charles Linquis
- 6th October 2011, 23:34
It is just my continuous jab at those who continue to use 16F parts. There are not many times when a 16F part is the best for an application. 18F parts have advantages in speed, code efficiency, better peripherals, if you run out of program space, there are (usually) larger parts in the same family that you can easily move to.
They can deal with large arrays and you can use LONG integers with PBP.

And, they generally cost no more than their "little brothers".

Mike, K8LH
- 7th October 2011, 00:48
I understand what you're saying and I agree (generally) with your premises but you shouldn't dismiss or exclude the 12F and 16F "enhanced" midrange devices. They're pretty potent with a 32-MHz clock, linear RAM address mapping, an interesting assortment of peripherals (some not found on 'legacy' 18F devices), and an excellent price/performance ratio. In fact, I can think of one case where the new FVR (fixed voltage reference) module is found on some 18F "K" series devices and on some 12F/16F "enhanced" devices, but the "K" series devices can't use the FVR output as the ADC +vref input as can be done on the 12F/16F "enhanced" devices.

Charles Linquis
- 7th October 2011, 02:58
Noted. Those parts have some really nice features, and I do use the 12F parts from time to time for such menial tasks as 555 replacements, but I am still amazed at the huge number of people using 16F parts. In many cases, the solutions would be easier if they simply switched to an 18F part. The reluctance to change baffles me.

Mike, K8LH
- 7th October 2011, 03:29
In many cases, the solutions would be easier if they simply switched to an 18F part.
May I ask, in what context? Are you talking about easier with respect to programming in PBP which may lack some features on the 16F parts?

Charles Linquis
- 7th October 2011, 06:51
The 18Fs have more/better peripherals, allow for LONGs and big arrays and almost all run at 40Mhz. They also allow for near seamless upgrades when your needs exceed 32K of FLASH.

Mike, K8LH
- 7th October 2011, 08:04
Charles, please forgive me for pressing. I've got a Philosophy class this semester and I guess I'm trying to frame your comment into premises and conclusion.

I certainly wouldn't argue that the 18F' parts have "more" of just about everything (flash, RAM, clock speed, peripherals, etc.). I'm just not sure how you would quantify "in many cases", and, unless PBP is missing capabilities or features for 16F targets compared to 18F targets, I'm not sure how writing programs might be "easier" for one or the other. I've got LONG data types for 12F, 16F, and 18F targets with the BoostC compiler I'm using. Is that not the case with PBP?

Charles Linquis
- 7th October 2011, 14:53
PBP does not support LONGs in 16F chips.

sougata
- 9th October 2011, 10:11
Hi Everybody,

Couldn't resist commenting. Microchip is actually trying to bridge the gap between the 18Fs and 16Fs with the inclusion of features already in the 18Fs.

I believe with the acquisition of Hi-Tech they would finally settle down the 8 bit tool chain into the Hi-Tech compiler stable. So need for a C optimized chip is obvious and thus the grown up 16Fs (enhanced mid range).

Since I started up with the 18Fs I always prefer them cause you got plenty of headroom to blow up your application into the next level. Interestingly the new exciting features are not available on the 18s or very limited, seems 16Fs would not stand the competition with the 18Fs.

Here are some interesting features introduced on the new 16Fs
CWG (Complementary Waveform Generator)
NCO (Numerically Controlled Oscillator)
CLC (Configurable Logic Cell)
DSM (Data Signal Modulator)
SetReset Latch
Comparator with Hysteresis
Fixed Voltage Reference 1.024/4.096
5 Bit DAC
Multiple number Enhanced PWM with some features like PWM steering.
Charles, I am seriously thinking of using the 16Fs as a co-processor and still fiddling around the idea of developing the co-processor in C (better support perhaps with the newer libraries like mTouch) with SPI connectivity doing specific hardware tasks relieving the main processor (obviously an 18F) to do more. Think of the possibilities.

Charles Linquis
- 10th October 2011, 03:44
Those new features in the 16Fs are certainly neat!

And regarding your idea:I could use a good floating point co-processor! I think you could do other neat things as well.


I have done something similar for my own use. I always use all the pins on the processor, I guess I keep adding peripherals until all the pins are used. In any case, someone always wanted something else - something that my circuit didn't have.

I needed an "intelligent peripheral" that would do all sorts of different things, so I started with an 8F2321's (in I2C mode). I defined a command set that will take a '2321 and let you configure virtually anything 'on the fly'. It allows you to:

Set up all the TRIS registers
Write to any pin
Read any pin
Set up any A/D channels
Read pins (as analog or digital) once, or continuously (in a continuous loop).
Polls all digital pins on a timer interrupt (1 or 5ms rate)
Latches INT0 (It captures the transition so I don't miss it)
Can become an I2C master on certain events (INT0, for example), so that the other PIC can respond almost immediately.

This '2321 then becomes a part of a new board layout. I add the peripherals (level shifters, voltage dividers, thermocouple amps, etc) and connect it to the main '8723 with 4 wires (SDA,SCL,Vdd and GND). The '2321 is always programmed with the same code and the main PIC configures it on power
up. The '2321 has a default configuration (also modifiable) that it loads from EEPROM on startup.

This arrangement works well for me - especially since I can (field) bootload the main chip (8723), but not the peripheral ('2321), so having a part that I can
- under command, change the way it works has been invaluable. I have added features simply by telling the customer to add a wire to a pin on the board and
then emailing him the hex file that processes it.

I can't sell my part. But I think there is a need for something similar (with even more features). Do it!

sougata
- 10th October 2011, 09:31
Hi,

Still can't ignore the sub-dollar pricing (10K) for the newer 16F parts !!!!

circuitpro
- 16th January 2012, 18:41
Hello Charles,
I know that you have extensive experience with XPORT, so would like to ask you a question. Is 115200 the maximum baud rate when using this device? What is the fastest baud rate possible using PBP in general, either ethernet or RS422/485? I have a note here that I saw reference to 5 Mbaud RS422 in a forum post, but can't find any such thing. Maybe that was just a good dream?

Thanks very much,
Len