Intelligent pause constants

Jeremy Leach

Senior Member
Coming back to using PICAXEs after a very long break, I'm just wondering why the Pause command couldn't be given 'intelligent' constants representing the 'actual' time delay after clock speed has been taken into account.

For instance Pause P_1000 where P_1000 is a reserved word meaning 'Pause for 1000 milliseconds'.
The compiler in the editor could translate this reserved word into an adjusted millisecond value before sending the program to the PICAXE.

I expect there could probably be clever tricks done as things stand by defining calculated constants based on the actual values of 'm4' etc, but this would be cleaner.

Admittedly there would have to be a whole array of pause reserved words, but it could be at least the typical ones used for typical scenarios (for instance writing to LCD or OLED, writing to external EEPROM etc). However it would eliminate the need to edit the pause statements in code when the clock frequency is changed. Much the same as the SERIN t4800_8 reserved words I imagine must operate etc.

An even better option would be to have a new command, called something like PauseReal, which would have one parameter representing the 'real' time you want to pause taking clock frequency into account.
 

techElder

Well-known member
Jeremy, I rarely place a fixed number anywhere in my code. Constants are always defined in SYMBOL statements (in a separate INCLUDE file for me.)

Code:
' for PAUSE milliseconds
symbol ONESECOND = 4000 ; @32MHz
symbol HALFSECOND = 2000 ; @32MHz
symbol QTRSECOND = 1000 ; @32MHz
symbol TENTHSECOND = 400 ; @32MHz
symbol FOURHUNDRETHSECOND = 10 ; @32MHz

PAUSE QTRSECOND
You could easily develop some math in there so you only have to change one constant if you change frequency. I think that would be too much trouble.
 

Jeremy Leach

Senior Member
Yep I do the same Tex and don't hard-code numbers if I can help it. I was just thinking it would be nice for a bit of intelligence in the software in order to not have to define symbols. I'd imagine it might be relatively easy to get the compiler to work out the real values needed, knowing the frequency setting in the code. However having said that, the clock frequency isn't defined at a program editor file level so it might not be that easy afterall.
 

AllyCat

Senior Member
Hi Jeremy,

Welcome back!

IMHO there are already rather too many "reserved" words (some not even documented) and I don't think the editor is all that "clever"; something like "FVR1024" is simply a value that is thrown directly at the appropriate SFR, Also, a directive such as PAUSE_10000 (10 seconds), could hit an overflow problem if the clock were increased to 32 MHz.

However having said that, the clock frequency isn't defined at a program editor file level so it might not be that easy afterall.
Yes indeed, bear in mind that setfreq b1 is perfectly acceptable to the compiler (yes, I have used it), but the actual frequency may be known only at run-time.

Cheers, Alan.
 

Jeremy Leach

Senior Member
Hi Alan, thanks. I take your point about setfreq so maybe this isn't a good idea afterall :). I was thinking along the lines of 'anything to reduce the scope for human error' when changing the clock frequency. It's easy to forget to change the detail when making big changes like the processor frequency even if there are symbols defined for different things. So derive as much as possible.
 

Jeremy Leach

Senior Member
I've actually achieved what I wanted by effectively creating two new commands in this little block of code :
Code:
[FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff][FONT=Courier New][SIZE=2][COLOR=#0000ff]Symbol RAM_CurrentClockFreq = 28

Test:
 'Set the internal clock frequency to M2. 
 b0 = M2
 Gosub SetFreq2
 
 'Pause 1000 ms
 w0 =1000
 Gosub PauseReal
End

SetFreq2:
 'INPUT PARAMETER: b0 = desired frequency (M2 etc)
 SetFreq b0
 Poke RAM_CurrentClockFreq,b0
Return

PauseReal:
 'Assuming 4MHz default picaxe
 'INPUT PARAMETER: w0 = desired 'real' pause in milliseconds
 Peek RAM_CurrentClockFreq,b2
 Select Case b2
  Case M1
   w0 = w0 / 4
  Case M2
   w0 = w0 / 2
  Case M4
   w0 = w0
  Case M8
   w0 = w0 * 2
  Case M16
   w0 = w0 * 4
  Case M32
   w0 = w0 * 8
 End Select
 Pause W0
Return
[/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT][/COLOR][/SIZE][/FONT]
It's not the most compact code and there doesn't seem to be any tricks with the reserved words and their underlying constant values.

The way it works is:
1. Instead of using the PICAXE command SetFeq, you use the SetFreq2 routine instead, as per example.
2. Instead of using the PICAXE Pause command you use the PauseReal routine instead, as per example.

The fundamental difference being that this method will allow pauses to be defined in 'real' millisecond durations, regardless of the clock frequency. Obviously the code itself introduces a certain delay so I'm not saying it's fantastic although it could be helpful for longer pauses !
 

Buzby

Senior Member
As an aside, is there a way for a piece of code to determine what the current clock frequency is ?
 

AllyCat

Senior Member
Hi Buzby,

You can probably do a PEEKSFR OSCON,... which I believe is $39 for M2 chips. Then use a LOOKDOWN and LOOKUP to return the frequency digits (or do a little maths).

A sertxd(#m1," ",#m2," ",#m4," ",#m8," ",#m16," ",#m32) in the simulator gives a clue with the result 90 98 106 114 122 242 which basically increments by 8 (the 3 LSBs are used for other functions) with the last value switching in the 4x PLL (i.e. 242 = 114 + 128) and '2' selects the internal oscillator.

Cheers, Alan.
 

Technical

Technical Support
Staff member
Although the chip can, at runtime, determine certain internal speeds, it cannot do this at compile time to insert different constants (for the reasons above).

However it cannot ever work with external speeds (as these are defined by the physical resonator type connected), which neither compile time or runtime can determine.
 
Top