the best way to code a clock method?
varnon
Posts: 184
Hey guys.
So I've been working on some code to make it easy for myself and my colleagues to conduct experiments. I've been using it for about six months and its working pretty well. Now it's time for me to proofread, fix up some things and seeing how well it works for my colleagues. One big thing we need for experiments is something to keep track of time. I would like to do this in software so that no one has to worry about finding the right RTC or other part.
This is the code I have been using. Another method launches this on a new cog where it runs forever.
The value "clock" is incremented every millisecond, and is referred to by other code. The clock should run for something like 24 days before it resets. I've tested it up to 7 hours and it is still perfectly accurate. Probably no one will ever have the clock run for more than an hour, but I like to have the option.
Here is the code:
My questions:
First, I don't really get signed longs in spin.
Is there a way to use a long in an unsigned form (0 to 4,294,967,296) instead of the signed form (- 2,147,483,648 to +2,147,483,648) ? It honestly wouldn't really matter anyway, nobody is going to run the thing for more than a few hours, but it would still be nice to use the full potential for the long. (My apologies if I am completely misunderstanding signed vs unsigned.)
Second, Is there a better way to set this up in general?
I've thought about it a bit, and I've been using it for six months... but I have to wonder if there a whole cog is really needed for this. Again, I don't think anyone will ever need all 8 cogs, but if there is a better way I would like to consider it.
Any thoughts are much appreciated.
So I've been working on some code to make it easy for myself and my colleagues to conduct experiments. I've been using it for about six months and its working pretty well. Now it's time for me to proofread, fix up some things and seeing how well it works for my colleagues. One big thing we need for experiments is something to keep track of time. I would like to do this in software so that no one has to worry about finding the right RTC or other part.
This is the code I have been using. Another method launches this on a new cog where it runs forever.
The value "clock" is incremented every millisecond, and is referred to by other code. The clock should run for something like 24 days before it resets. I've tested it up to 7 hours and it is still perfectly accurate. Probably no one will ever have the clock run for more than an hour, but I like to have the option.
Here is the code:
PRI ExpClock | systime systime:=cnt ' Finds current value of system counter repeat waitcnt(systime += clkfreq/1000) ' Waits one millisecond. A synchonized pause. clock:=clock+1 ' After a millisecond passes, add 1 to the clock if clock>2147483000 ' If the clock needs reseting clock:=0 ' Reset the clock
My questions:
First, I don't really get signed longs in spin.
Is there a way to use a long in an unsigned form (0 to 4,294,967,296) instead of the signed form (- 2,147,483,648 to +2,147,483,648) ? It honestly wouldn't really matter anyway, nobody is going to run the thing for more than a few hours, but it would still be nice to use the full potential for the long. (My apologies if I am completely misunderstanding signed vs unsigned.)
Second, Is there a better way to set this up in general?
I've thought about it a bit, and I've been using it for six months... but I have to wonder if there a whole cog is really needed for this. Again, I don't think anyone will ever need all 8 cogs, but if there is a better way I would like to consider it.
Any thoughts are much appreciated.
Comments
You cannot use half a cog - but you could get this cog to do more, if you want.
The WAIT line represent spare processing resource, so provided you can 'still get it done' inside the 1ms budget here, you can add something else to do in this under-used COG.
Like jmg said, you can do more in this cog.
Maybe move the division operation outside the repeat loop (clkfreq/1000)
to provide more available time inside it?
IF there is something else to do there?
Like break it down into seconds, hours, etc.
It certainly looks like a good starting point for a soft clock.
Cluso, I knew somebody would have an alternate idea. I really appreciate it. I use an SD card driver anyway, so it would be a great way to save a cog.
For what ever reason my method is more accurate, especially when polling the time repeatedly at smaller intervals. MW-rawb_spi starts producing weird results if you poll in the order of every 10 milliseconds. Although I probably won't need super high accuracy, I think it is worth sacrificing a cog.
Thanks for the thoughts.
If you have a free pin you can do it also with the two counters. One counter outputs a frequency of 1 kHz at a pin, the other counts the positive edges at the same pin and increments therfore every 1 ms. You can use one of the EEPROM pins (P28) for that, if you don't have other I2C devices connected at P28, P29.
Andy
If you have a cog that's under used already you could have a method to check if a certain interval has passed.
Here's my soft clock method.
"oneSecond" had been previously defined as clkfreq. If you could use a smaller interval of time if you could call this method frequently enough.
This method is from my 7-segment clock project, so there's additional code in the method to display the time.
The main aspect of this method is the contition check "if cnt - previousTime > interval". This lets the cog do other tasks instead of spending most of its time waiting with "waitcnt".
I'm pretty sure parts of the above method have been copied from some other source.
Edit: I realize I've never left my clock running more than a few hours at a time. I just found (and fixed) a bug with the way it was keeping track of hours. I'm not sure if there are other bugs in the code. The main point if the above code is to illustrate the way to check for the passage of a set interval of time.
-Phil