05-01-2020 10:58 AM
I don't have any definitive answers, just my own speculative ideas in the 2nd msg of that linked thread. I'm pretty sure now that the "initial delay" value itself cannot be changed on-the-fly with the task in run state. But it also appears that the *functionality* one would want from making such a change is available by choosing to change "low ticks" on-the-fly instead (while also setting "enable initial delay on retrigger" to False).
If you bump up to a 10k pulses per rev encoder, here are the 2 things to consider:
1. The counter tasks that depend on the encoder signal. Here you should be in good shape. The counter circuitry is spec'ed to handle pulse trains up into 10's of MHz.
2. The Analog Input task, *IF* it uses the encoder signal as an external sample clock. At 10k cycles per rev from the encoder and a max AI sample rate of 250 kHz, you can only support up to 25 revs/sec or 1500 RPM. I'd think you need to support higher engine speeds than that, so you may be better off sticking with your lower resolution encoder. Again, *if* you use the encoder signal as a sample clock to get samples that are equi-distant in rotation angle rather than equi-distant in time.
-Kevin P
05-08-2020 01:41 PM
Ok great, well definitely seems like a new shaft encoder is a potential option, but to save the time and cost of that I still hope to get the code set up if possible.
I have a 1000ppr shaft encoder and have been trying to test some code (I have attached the code I wrote- initially looking good until I realised I was only able to acquire an output signal the first time the counts exceeded the desired count number, despite refreshing the count). I have added a retrigger function inspired by the code you initially sent, but this now means that the pulse is generated when the Z impulse arrives, not as soon as the case structure is true. Effectively I want things to operate in reverse i.e. just refresh when the z impulse comes in, but wait until the case structure is true before sending the signal.
As you can tell I am fairly new to this and just trying to do things step by step- feel I am close but hopefully if I can find a way to solve this I should have something I can test in practice.
Please let me know what you think when you can.
Thanks a lot
05-08-2020 03:40 PM
So honestly, that latest code is a step in the wrong direction. It's still trying to rely on software-timed polling and control functions which will definitely *not* be precisely repeatable at engine speeds I expect you need to support.
Please, go back and try to start working from the code I posted in msg #7. And also, carefully re-read the description and explanation I gave in msgs #7 and #13. Finally note that based on what I observed in the experiments I mentioned and linked to in msg #17, I would now either set "EnableInitDelayOnRetrigger" to False, or else not try to set it at all.
That's going to be a much better approach because it puts all the timing relationships into the hardware and it will be repeatable down to 10's of nanosec.
Remember, the helper counter is meant to offset the triggering location for the output counter. It's triggered by the TDC pulse and the offset is defined in terms of encoder edges ("Ticks" in DAQmx terms). The helper essentially offsets the TDC pulse over to the specific angular position where you want to generate your fixed-time output pulse.
The output counter is then triggered by the helper's output pulse, and its pulse width is defined in terms of time.
-Kevin P
05-12-2020 06:52 AM
Yes, I see what you mean. I added a wait until done and abort function inside the case structure in my code and it solved the previous issue I had. That said, the loop doesn't seem to be able to always register the count number I want for the injection timing when the encoder pulses are coming in at a fast rate (not sure if that was what you had in mind when you say it wouldn't be repeatable).
I understand the overall concept of what is happening in the code in msg7- you're using the helper counter to produce the digital edge that the output pulse uses as its trigger. I am having issues with a few things:
- The application throws up errors with the retrigger function (as you had earlier suggested it might)- I have removed this for now
- The encoder I have now is connected to PFI0-2 with A-0, B-1, Z-2. The helper counter should (I assume) therefore be ctr0 but for some reason it doesn't allow me to choose this option, only analogue channels. Encoder channel A presumably will be PFI0 for the A input (and the trigger for the helper is PFI2 for the Z).
- What is the reason for low ticks/time and delay time being the same and high ticks being 2? I know you said in a previous message that's just what you normally do- I had initially thought that would mean you essentially double the delay time you actually want, but then I assume that the high time occurs first?
- After taking the retrigger function out, I had some errors with resources already in use, which went away when I split the error wires, but I imagine that will cause issues if the tasks aren't synced properly. This means I have 2 separate stop and clear tasks though..
Thanks a lot.
05-12-2020 09:00 AM - edited 05-12-2020 09:00 AM
Update:
- I understand the rationale behind the initial delay and low ticks being the same (providing the enable delay on retrigger function is set to false), and remember you saying that you could change low ticks on the fly- would that mean you don't actually need the initial delay function if you simply use low ticks to change on the fly?
- Did you say that you can change high time during a run. I managed to sort out the channel selection but am still having issues with an error regarding resources already in use (Error 89137). I am using counter 1 for the pulse output so I am not sure why it is producing an error; I have attached the code again.
05-12-2020 09:11 AM
A lot of good info and questions, I think it'll be most clear if I reply inline. My responses are in red.
- The application throws up errors with the retrigger function (as you had earlier suggested it might)- I have removed this for nowDo you mean the "EnableInitialDelayOnRetrigger" property? Yes, go ahead and remove that. It'll be necessary if you're at home with an M-series 62xx device, and my experiments suggest that you won't need it at work for the X-series 63xx device either.
- The encoder I have now is connected to PFI0-2 with A-0, B-1, Z-2. The helper counter should (I assume) therefore be ctr0 but for some reason it doesn't allow me to choose this option, only analogue channels. Encoder channel A presumably will be PFI0 for the A input (and the trigger for the helper is PFI2 for the Z).
Right-click the constant or control that (presently) only allows selection of analog channels. Choose "I/O Name Filtering..." from the popup menu. That'll give you a dialog that presents some fairly self-explanatory options you can configure so that you can choose a counter channel.
Your pin descriptions make sense to me. Ch Z acts as the trigger signal for the helper counter, Ch A acts as the "source of ticks" for the helper counter.
- What is the reason for low ticks/time and delay time being the same and high ticks being 2? I know you said in a previous message that's just what you normally do- I had initially thought that would mean you essentially double the delay time you actually want, but then I assume that the high time occurs first?
The very first pulse is defined by "initial delay" time/ticks in idle state followed by high time/ticks in active pulse state. Subsequent pulses are defined by "low time/ticks" in idle state followed by high time/ticks in active pulse state.
My habit of setting initial delay and low time/ticks to the same value helps me get consistent timing for *all* pulses in the pulse train, which is almost always what I want.
High ticks are set to 2 because that's the minimum legal value for pulse parameters. I want the minimum because the full pulse period must pass before the counter can re-arm for the next trigger. Keeping the pulse short maximizes my options for where I can place it without missing the next trigger.
- After taking the retrigger function out, I had some errors with resources already in use, which went away when I split the error wires, but I imagine that will cause issues if the tasks aren't synced properly. This means I have 2 separate stop and clear tasks though..
Can you describe the specific error, exactly where it occurred, and post the code that resulted in the error? This should be solvable.
Two separate stop and clears are expected. My posted code only showed the task startup, not the "wait around while running" part or the shutdown. Only the error clusters get merged to enforce sequencing. The tasks remain separate and need to be stopped and cleared separately.
-Kevin P
05-12-2020 01:17 PM
Yes I meant the enable initial delay on retrigger, and good to know that I won't need it for the X series in any case.
The ctr0 is now set for the helper counter terminal so the terminals should all be set correctly now.
I was trying to work out why you use the falling edge of the counter output as the signal for the injection timing- I guess it doesn't make a massive difference since you only have 2 high ticks, but just wanted to know why?
I attached the code in the previous message, but have attached the exact error. I imagine I need to add a control task VI or 2 post-startTask so that it knows when to use certain resources? From the previous code I am aware that even though the Z index is constantly being sent, it doesn't automatically ensure the task starts again, so I know I need a loop in here for the task to keep running every time it received a Z index (and also so that thing can be changed on the fly?) but additions I have made for this have caused more errors so left the code without a loop at this point.
Many Thanks
05-12-2020 01:25 PM
I was still working on my last reply when you posted your followup and am just seeing it now.
- Now that we're removing the property setting for "EnableInitDelayOnRetrigger", the very first pulse after the very first trigger will still be defined by initial delay and high ticks. All subsequent pulses are defined by low ticks and high ticks. So you should still wire the same value to init delay and low ticks when first configuring the task.
- High time (or high ticks) *can* be changed during the run, but it'll probably be best to call DAQmx Write rather than using the property node. There's a quirky behavior where it matters which one of the two pulse timing parameters is written to the property node. One of them takes effect right away, the other seems to get ignored (unless you later write to the first one at which point both take effect).
Instead of trying to remember which parameter "matters" in each case (freq/duty, high/low time, high/low ticks), it's easier to use DAQmx Write where both are required and will both take effect right away. (You don't have to *change* both values for things to take effect, you just have to write to them even if one of the values is always the same.)
- I made a simulated device, ran your code, and saw the same error. Looks like PFI4 is the default output pin already used by ctr0. You can either specify a different output pin for your time-based pulse or you can designate ctr0 as the time-based pulse and ctr1 as the helper. Both methods worked here without error on a simulated USB-6211.
-Kevin P
05-13-2020 10:26 AM
I have changed the output pin as PFI5 since that is the default output for ctr1. I did then receive a warning 200010 (Finite acquisition or generation has been stopped before the requested number of samples were acquired or generated)- this appeared on the stop task related to the helper counter. Not sure why this error occurred, as people online seem to experience this problem with read or timing VIs, but in any case, I put a loop in the middle of the start and stop tasks and that seems to have worked.
So you're saying that setting the high/low ticks/time of the 2 individual write files as controls would enable variation on the fly?
And the initial values you add into the create channel VIs only matter before you make changes to the controls of the write VI?
I added some write VIs within the loop with controls but the output pulse duration timing is still consistently maintained at the conditions initially specified in the create channel VI... I have attached the code.
Many Thanks
05-13-2020 10:32 AM
NB: If I attach the error code to the output of the write file, I receive an error stating "pulse specifications cannot be written to a finite counter output task on this device"