Precise output timing

Haku

Senior Member
I've been tasked with building a camera flash delay box with configurable timing and am unsure at this point if it's just for delaying a single flash, or more likely delaying more than one, each with different timings.

The hardware I can do ok, but my Picaxe-fu is a little rusty, and I have about 2 weeks to build the thing from near scratch.

This is a rough (typed out but untested and needs refining) draft of how I see the main trigger code going:
Code:
do while shutter_input=0
loop
pause flashpause1
high flash1
pause flashpause2
high flash2
pause flashpause3
high flash3
pause flashpause4
high flash4
wait 1
low flash1,flash2,flash3
The flashpause variables will obviously be pre-calculated to be in relation to the previous pause times.

Since this is all about timings and I want it to be as precise as possible, will the time it takes to execute the wait & high commands have any noticable impact on the millisecond timing of the flash triggering at 32mhz on an M2? Or should I go with an X2 chip running at 64mhz?
 

oracacle

Senior Member
what resolution? What accuracy do you need?

if you use an X2 @64mhz then you could use the timer

Code:
[color=Navy]#picaxe [/color][color=Black]20x2[/color]
[color=Blue]setfreq m64
      let [/color][color=Purple]timer [/color][color=DarkCyan]= [/color][color=Navy]0
      
      [/color][color=Blue]do
      loop while [/color][color=Black]shutter_input [/color][color=DarkCyan]= [/color][color=Navy]0  [/color][color=Green]'wait for user input

      [/color][color=Blue]settimer [/color][color=Navy]65286                [/color][color=Green]'settimer for 1ms increments
      
      [/color][color=Blue]do                            [/color][color=Green]'hold here until time is correct
      [/color][color=Blue]loop while [/color][color=Purple]timer [/color][color=DarkCyan]< [/color][color=Black]interval_1
      [/color][color=Blue]high [/color][color=Black]flash1
      
      [/color][color=Blue]do
      loop while [/color][color=Purple]timer [/color][color=DarkCyan]< [/color][color=Black]interval_2
      [/color][color=Blue]high [/color][color=Black]flash2[/color]
I have recently found that the closer you get to the 65536 value for timer 1 pre-set the less accurate it is. Having the loop exit at the end is also faster than having it at the beginning due to the way the code will be compiled.
@64mhz each minor tick is 4us. The other bonus to running at higher clock speeds is the execution timer of every command is less meaning less chance of something being missed.

Also
 

hippy

Technical Support
Staff member
All commands will have some overhead but at higher speeds those will be reduced. The time taken for any command may be compensated by adjusting preceding and following pause times.

One thing to bear in mind is that timing of PICAXE instructions is memory location dependent. So going from "PAUSEUS 15" to "PAUSEUS 16" may sometimes cause more of a change than expected. In some circumstances it may actually reduce the period between commands surrounding the PAUSEUS rather than increase it.

Position dependent issues may be mitigated against by always specifying "PAUSEUS w0" or similar, and adjusting the value set in 'w0', putting the time sensitive code at the start of the program with the setting of time constants later in the code, using GOTO to jump round the time sensitive code to the start of program ...

Code:
Goto MainProgram

TimeSensitive:
  High LED
  PauseUs w0
  Low LED
  Return

MainProgram:
  Do
    w0 = 15
    Gosub TimeSensitive
    w0 = 16
    Gosub TimeSensitive
  Loop
 

Haku

Senior Member
oracacle, I believe I'll only need the timing to be in milliseconds from what I've read about other projects involving flash delays, and the accuracy as best as possible without going into any overly complicated coding.

Thanks for the bit of code involving the timer, I looked in the manual about the timer variable and tested it in the Picaxe simulator but the results didn't seem right. Most of my Picaxes are M / M2 variants so haven't used timer yet, but I do currently have an old 28x2-5v (18F2520) I can begin preliminary testing with before getting a 3.3v Picaxe for the main build.

hippy, I knew the commands don't all take the same time to execute but didn't know that two commands with different fixed settings could take different times to execute. It seems that a Picaxe at 64mhz will be enough as it appears the commands take so little time relative to the microsecond timing of the flash that it shouldn't really be much of an issue.


Off to a good start, but still have to bury my head in rotary encoder code and direct LCD control code, both of which I can lift from past programs I've written, although I may have to reacquaint myself with bubble sorting if they want more than just one flash delay.
 

Haku

Senior Member
Turns out it's just a single flash delay which makes things a whole lot easier, but there could be the need for a multiple delay box in the future, which will be an interesting challenge if it arises.

The rotary encoder I have turned out to be ridiculously easy to read, when 'at rest' both outputs are high, turning the dial left causes one output to drop first then the other, and opposite for turning right, then once it moves round to the next resting notch both outputs go high.

I've ordered a couple of 20x2's as the 20m2 @32mhz I've been testing just doesn't cut it when you want to turn the dial fast with the parallel wired LCD updating at the same time.

Now I've only got to build it and finish coding and make sure it has good accuracy, in a week, the deadline shrunk. I can do it :)
 

Haku

Senior Member
oracacle, that bit of code you posted, after a tiny modification and using the calibfreq command to fine tune the 20x2's speed, I'm getting near perfect millisecond delay results :)

The only oscilloscope I have is the one I bought from the Picaxe store which I haven't used much, I was wondering how I'd use it to accurately measure the 20x2's output, but then I remembered my Metrix MTX3283 multimeter has a really good HZ measuring function that can display results as accurate as microseconds in 3 decimal places how long the signal stays high & how long it stays low. Then I looped the delay function & read the output with the multimeter.
 

Peter M

Senior Member
I gather if that code by oracle works and is accurate, that no additional time is added for the scanning of a new program download? is that done like an interrupt? or does one need to add a disconnect statement at the beginning?
 

AllyCat

Senior Member
Hi,

AFAIK the download pin is simply polled, but that may consume only a few microseconds (or less) as part of the overall system housekeeping. Polling is potentially faster than all the overhead of an interrupt with its call, return and other stack operations. A DISCONNECT might not actually save any time at all, because the polling routine may still need to "visit" the section of code, even if it then decides not to test the pin.

But all this will happen at the PIC's "native" 1us (at 4 MHz clock) instruction cycle speed, it's the Basic Interpreter which "wastes" nearly all the time, 400 us for a simple instruction and many milliseconds for some of the more complex lines of code (including the apparently simple RETURN).

Also, bear in mind that the internal clock "resonator" in M2s is only an integrated R-C oscillator, so it will rarely achieve better than about 0.1% accuracy over any moderate period of time. That's 1 ms for each second of run time, of course. Another factor to consider is timing "jitter", which can't be avoided if the program-writer has no control over the operating-system interrupts.

Cheers, Alan.
 

oracacle

Senior Member
oracacle, that bit of code you posted, after a tiny modification and using the calibfreq command to fine tune the 20x2's speed, I'm getting near perfect millisecond delay results :)

The only oscilloscope I have is the one I bought from the Picaxe store which I haven't used much, I was wondering how I'd use it to accurately measure the 20x2's output, but then I remembered my Metrix MTX3283 multimeter has a really good HZ measuring function that can display results as accurate as microseconds in 3 decimal places how long the signal stays high & how long it stays low. Then I looped the delay function & read the output with the multimeter.
IIRC that little scope isn't quite manly enough to get accurate down at that time interval.
Hippy posted a high accuracy timer a few years back based around a 20x2. I later built an actual timer unit around it with 2 SR latches. I'll see if I can find them a minute

Hippys timer
http://www.picaxeforum.co.uk/showthread.php?14517-High-Accuracy-Timer

My timer based on hippys timer
http://www.picaxeforum.co.uk/showthread.php?28067-High-accuracy-timer&highlight=nano
 

womai

Senior Member
That little scope (a low-cost variant of my DPScope SE) is actually quite accurate with regards to timing, since it relies on a quartz crystal as a reference. You can use the automated measurements which the software offers, which gives an accuracy for pulse width and period (or frequency) measurements of a fraction of one sample interval (it uses linear interpolation). Make sure a full period occupies as much as possible of the acquired record (approx. 200 points) for maximum resolution, that way you should get maybe 0.1% accuracy of your timing numbers. Of course not a bad idea to double-check with your multimeter.
 

Haku

Senior Member
The photography guys were really pleased with the flash delay box, but something showed up that the box can't deal with because I''d used all the IO ports of the 20x2, so I'm building them a new box but using a 28x2.

One small question I hope someone knows the answer to, on the 28x2 if I use the command "pinsA = %00001111" will that affect any other pins besides A0-A3?
 

hippy

Technical Support
Staff member
on the 28x2 if I use the command "pinsA = %00001111" will that affect any other pins besides A0-A3?
Yes. "Let pinsX=" affects all pins on a port. Use "Let pinX.Y=" to just set one pin on a port.

On the 28X2 the only other A.x pin is Serial Out (A.4) so it might not matter.
 

Haku

Senior Member
Thanks hippy, that's just the information I was after.

I'd seen in the pdf manual that there was only A.0 to A.3 on the 28x2 but then saw in the editor the diagram showed the Serial Out was also A.4, which I won't be using during operation so I can go ahead and use "Let pinsA=" to set more than one output at the same time rather than individual "Let pinA.x=" commands.
 

oracacle

Senior Member
Before you get too far into this re-design, is it possible that the 28x2 may run out of inputs too.
personally I would have a chat with the guys and make sure that more aren't going to be needed. Another thought on that, is could to be wise/possible to chain more then one box together? ie plug the last flash output into the input of the next box essentially making the entire thing infinitely expandable - just a thought seeing as it in the development stage and could easily be added now with to no extra time and cost

Glad to hear the box was well received.
 

Haku

Senior Member
Thanks for the concerns, oracacle, I designed the original 16 simultaneous camera trigger box and the flash delay box so they are chainable due to how their input and outputs are wired; p-channel mosfets on the inputs which are pulled high with a 10k resistor and activated when pulled to ground, and the outputs are through opto couplers to completely isolate them from the cameras & flash unit(s). The isolation was a definite requirement as the 16-shutter output box is presently connected to cameras worth thousands.

For the mark 2 flash delay box I'm building I only need one more IO pin than the 20x2 could offer so will have spare IO pins if future modifications are necessary.
 
Last edited:

Haku

Senior Member
I've finished the circuitboard and it's all working nicely, except one small problem I didn't anticipate, the calibfreq command doesn't appear to be working on the 28x2 with an external 16mhz crystal to run it at 64mhz.

I thought the crystal simply multiplied the speed of the internal clock by 4, so the calibfreq command would still work on the internal resonator?

I've got 4 28x2's (I found some Picaxes I'd forgotten about :) ), two of the old PIC18F2520 5v versions and two of the current PIC18F25K22 versions, and none of them can be tuned with calibfreq.


edit: I've sorted the timing issue. By adjusting the settimer value for the 1ms increments it has enabled me to fine tune the timer variable, very very nicely :)
 
Last edited:

westaust55

Moderator
Looking at the programming details for the CALIBFREQ command:
http://www.picaxe.com/BASIC-Commands/Advanced-PICAXE-Configuration/calibfreq/

It is only intended to work with the internal resonator.

When you use an external resonator, that frequency is in effect multiplied by 4 to generate the internal clock frequency.

As you are using the external resonator with SETFREQ EM64 the internal resonator as adjusted by the CALIBFREQ command is not being used so you will not see any change.
 

Haku

Senior Member
Thanks westaust55, I looked in the picaxe manual 2 pdf and it didn't mention calibfreq's relationship with an external resonator.

As I'm using the timer variable to make events happen down to the millisecond, changing the settimer variable fixed things, and apparently more accurately than the calibfreq command can.
 
Top