Time values in minutes and storing values in arrays
tuffstuff
Posts: 24
I ran into two issues recently - storing constants larger than 32 bits and how to monitor time in units of minutes. Both of these are related due to my method of monitoring time in minutes. I'm sure there is a better way to do this. Here is what I wrote to get time units in minutes:
My clkfreq*60 = 50,5032,704 instead of 48,000,000,000. How do I monitor time in minutes when my cycle count is larger than 32 bits?
Which brings me to the next issue I am having concerning storing a large hex string. I received the error: "Constant exceeds 32 bits". A friend of mine was saying that I need to be storing the long hex value as an array of segments (this works well for midi, which is what my project is centered around). This makes sense and in fact may be what I need to store the clock cycle count necessary for a minutes time.
I had no luck finding info on storing numbers larger than 32 bits, except in the assembly section of the manual, and I'm staying away from that for now. Also nothing about arrays either.
Any pointers (pun intended) would be useful.
Thanks,
clkfreq * 60 + cnt
My clkfreq*60 = 50,5032,704 instead of 48,000,000,000. How do I monitor time in minutes when my cycle count is larger than 32 bits?
Which brings me to the next issue I am having concerning storing a large hex string. I received the error: "Constant exceeds 32 bits". A friend of mine was saying that I need to be storing the long hex value as an array of segments (this works well for midi, which is what my project is centered around). This makes sense and in fact may be what I need to store the clock cycle count necessary for a minutes time.
I had no luck finding info on storing numbers larger than 32 bits, except in the assembly section of the manual, and I'm staying away from that for now. Also nothing about arrays either.
Any pointers (pun intended) would be useful.
Thanks,
Comments
Most programs I've seen that counts clock pulses tends to count up to seconds only, and keep track of those.
For example
This code will print the "beat" to the terminal every beat for 120 bpm. It seems like for timing, you are suggesting I work in smaller units. Instead of beats per minute, maybe just beats per quarter minute. To get 77 bpm, I'd have to write something like:
I realize too that I probably should be storing these values in another data type other than integers.
This is a good workaround, but I'm still stuck with the issue of how to store values larger than 32bits, and how to store long series of values as a single variable like an array.
I would suggest you setup a separate cog that handles the milliseconds timing for you, and allows you to start, stop, and reset it -- that way, the cognew delay is never an issue.
Here's how you might write a background timer. It uses pointers to state and timing variables so that you can have more than one instance running.
Except I would need to start using float math now, correct, or maybe there is a library already written for this?
Using another cog for the timing is a good idea too.
I believe so, and the same clock module can be used for recording and playback.
While I can play my guitar reasonalby well, I'm not a musician. It seems to me that you don't want to use BPM as the measuring stick -- better to use very small, yet manageable unit; like milliseconds. At 120 BPM you have 500ms per beat; but that's for quarter notes, right? Eighth notes, then, would be 250ms apart, 16th notes, 125, 32nd notes 62.5. If you need even more resolution you might do 1/10th of a millisecond but I can imagine you'd need more.
By knowing what speed you recorded at, you could make playback faster or slower with simple math. If I may, I think you're making this way too hard.
This is bogus as bpm/60_000 would resolve to 0, and what you really want is (clkfreq / 1000) * (60_000 / bpm). The first timer calculates ticks per millisecond, the second is the number of milliseconds per beat. And the most important point is that you NEVER want to use cnt in a waitcnt like this that is critical. You really want a synchronized loop. You can find this in the manual and see how I do it in my timer code. A synchronized loop accounts for the other work you do in between an maintains accurate timing (so long as you loop code is less than your loop delay).
Again, it seems that there is no need using BPM for the recording process, other than knowing what it is/was so that playback can be accurately adjusted. The playback delay would be ticks_per_ms * recorded_bpm / playback_bpm.
Finally, in any timing sensitive application you should pre-calculate time values and offsets where you can.
When you say this, an example might be calculating...
cycles_per_ms = 80,000,000/1000 = 80,000
...and then using following code, continuing the example for playback delay:
So here the processor isn't spending time calculating the cycles per ms value, we just hardcode it in. Is this what you mean by pre-calculating time values?
Well, sorry, somebody gave you bad code -- if you want the loop timing to be constant (as you do). When reading the cnt register in your waitcnt expression you are not accounting for the (potentially variable) code timing of the rest of the loop. The only way to get what you want is to use a syncrhonize loop:
This structure ensures that your loop runs for the duration specified by delaytix -- no matter what else is happening in the loop. And by pre-calculating the value of delaytix you leave the maximum amount of time available for the loop.
Finally, while we tend to run at 80MHz that is not always the case. I have the following at the top of all of my programs; this allows me to have constants (faster than using variables) for my timing elements, and if I want to change the crystal (some of my projects us 6.25MHz) or PLL settings, the compiler takes care of the dirty work.