Author Topic: Fine tuning some timing  (Read 16578 times)

jbrandall

  • Newbie
  • Posts: 19
  • farmer boy
    • View Profile
Fine tuning some timing
« on: March 31, 2015, 06:42:43 PM »
I seem to have overload my FMD with too much to do and not enough time to get it done, so I am going to pair it with a Nano which will handle to most time sensitive routine with little to output.  However, the Nano will generate some numbers that the FMD will need.  So is it better for the Nano to write to the FMD or is it better to have the FMD read the Nano? (via MODBUS)  Using the Nano to write, I can control when it does so,  not true with a read by the FMD.  Does the 'writing' get done before the ladder cycle completes or after all the outputs have been set?

On a related subject; I am reading 64 variables from the FMD every 300 ms (via Host Link Protocol).  Is this affecting the ladder logic execution or are the communication functions separate from the main processor?  

I know I'm splitting hairs, but I'm getting some really strange results that can't all be blamed on 'noise'.  Thank you for any guidance anyone can provide.

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3174
    • View Profile
    • Internet Programmable PLCs
Re:Fine tuning some timing
« Reply #1 on: April 01, 2015, 02:52:46 PM »
I would suggest letting the Nano writes to the FMD. The write is asynchronous which can happen anywhere during a ladder logic program execution. So if the FMD demands that the data can only be changed after a ladder scan, then let the Nano writes to a region of DM not directly used by the FMD for decision making, and the FMD can then at the time of its choosing, read these DM and copy them to another set of DM that it uses for its logic operation. In other words these DMs that Nano-10 writes to serves as "mailboxes". That way it will preserve the data that FMD uses during its logic scan and only use the new data at the end of the logic scan.

There is only a single core processor in the FMD and Nano-10 so the communication is handled by the same processor core. If you load the processor with a lot of communication overhead it can affect its program execution time. However, reading 64 variables every 300ms doesn't sound like a lot of data if the data are grouped and can be read in a few hostlink commands.

If you can, try to group these 64 variables into small groups so that you can use a hostlink command that can handle multiple data words (check the User's Manual - 16.40 Using OMRON Host Link Commands). E.g. if these are 64 adjacent DMs you can read 64 DMs using two hostlink commands (read 32 DMs per command) which can reduce the communication overhead significantly.
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

jbrandall

  • Newbie
  • Posts: 19
  • farmer boy
    • View Profile
Re:Fine tuning some timing
« Reply #2 on: April 02, 2015, 04:55:10 PM »
Thank you!  I wired everything up and it seems to work - much better than previously - with one minor problem.  I am trying to determine the speed of a crank arm that rotates about 90 rpm+/-.  A proximity sensors senses the passing of the arm and I use the following to calculate the speed:

REM  do strokes per minute
IF PULSEPERIOD (2)<400000 OR PULSEPERIOD (2)>2000000
THEN strokes_per_minute=0 REM crank stopped
ELSE strokes_per_minute=60000000/PULSEPERIOD (2) REM calc strokes per minute
ENDIF

This works and with very little load on the FMD will show the speed with 3 rpm's.  As I ask the FMD to do more (additional functions with some outputs) the speed range widens to maybe a 5 rpm range.  Adding more functions and a PWM output the speed range widens more and becomes somewhat erratic.  I have tried running the above calculation both at every second, and every scan and see little difference.  Any thoughts?  A better way to do it?  My concern is that I use the calculated speed to determine the PWM output, so random variance input causes random output.  

Again any thoughts/idea are muchly appreciated.

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Fine tuning some timing
« Reply #3 on: April 02, 2015, 09:07:08 PM »
I'd suggest a simple change to your code: call the PULSEPERIOD() function only once in your custom function.  I assume that "strokes_per_minute" is actually some 32bit variable such as DM32[101].  If, not, the this code will fail.


strokes_per_minute = PulsePeriod(2)
If strokes_per_minute < 400000 OR strokes_per_minute > 2000000
    strokes_per_minute = 0      ' Crank stopped
else
     strokes_per_minute = 60000000/strokes_per_minute
endif
[/font][/color]

If this doesn't help, then you might want to make a measurement once a second and perform a running average over the last 4 samples. This may help to mask the jitter in the measurement.

I'm very concerned with your problems with "overloading the FMD with too much work". My standard bunch of questions:

Exactly how much time does your custom functions eat up?  
Do all of your custom functions execute on each ladder logic scan?  
Does any of your custom functions use the DELAY statement?
Does any of your custom functions poll for some sort of response?
Does any of your custom function use a time wasting loop of code?

Gary d
 
« Last Edit: April 02, 2015, 09:11:01 PM by garysdickinson »

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Fine tuning some timing
« Reply #4 on: April 03, 2015, 12:44:06 PM »
A couple more ideas.

I have used both the pulseperiod() and pulse frequency() functions. I have noticed that the pulseperiod() function tends to return valves that are more noisy then pulsefrequency().

You application runs too slowly, 1.5 Hz, so Pulsefrequency is not useful.  If your system uses a geared down motor and if you could sense the motor RPM then pulsefrequency() might give you more stable results.

Since you have loaded down the FMD to the point that things don't work, you might consider using the leading edge of your sensor's output pulse to call an interrupt function to measure the stroke period.

The interrupt function can use the status(21) function to measure the time between interrupts.  Status(21) returns a value in the units of 0.1 us.  Please take notice that the value returned by the function will be interpreted by TBASIC as a signed 32 bit integer. The actual value is an unsigned 32 bit integer.  You must be careful with the boundaries when successive values change sign. And you must be careful when successive values are both negative.  

Be very careful with the variables used by your interrupt function. You should ensure that the variables changed by the interrupt function are not used by any of your other custom functions.  Just a word to the wise.

The use of interrupt function and status(21) is probably your best shot at getting an accurate measurement with the present state of your PLC code.

Gary d
« Last Edit: April 03, 2015, 01:15:56 PM by garysdickinson »

jbrandall

  • Newbie
  • Posts: 19
  • farmer boy
    • View Profile
Re:Fine tuning some timing
« Reply #5 on: April 03, 2015, 06:08:21 PM »
Thanks Gary!  Because I still live in the 16 bit world I had to use one of the 26 (A to Z) 32 bit variables, but your suggestion helped a lot.  Then I averaged just 2 readings taken each second.  The most it wobbles now is 1 rpm and not often at that.  Good enough for me...

REM  do strokes per minute
temp1=PULSEPERIOD (2)
IF temp1<400000 OR temp1>2000000
THEN strokes_per_minute=0 REM crank stopped
ELSE strokes_per_minute=(strokes_per_minute+(60000000/temp1))/2 REM calc strokes per minute
ENDIF

In your second post you show a method using the interrupt feature.  The reason I moved to using the high speed counter and the PMON was that a friend that designs circuit boards told me to avoid using interrupts because of the overhead interrupting, pushing the stack, etc, and etc (of which I understand almost zero).  He said that built in counters are much better because they run independently of the other commands.  Not sure if this is true or not, but when I did use them, I got much more stable and accurate data (hence the added Nano).  The speed monitoring was the last hurdle (almost).  Now I'm wondering where I should put the above code; where it get done every scan or where it gets done every second.  Every second sounds like an interrupt, whereas every scan would just happen in the 'normal' course of things.

Further to your fist post:
Exactly how much time does your custom functions eat up?  
  I don't know...  It depends on what conditions it finds as it goes.
Do all of your custom functions execute on each ladder logic scan?  
  No - only the every scan routine which is short. Most are proximity sensor   triggered, some timer triggered.
Does any of your custom functions use the DELAY statement?
  Only the 1st scan - to hold a light on for 4 seconds.
Does any of your custom functions poll for some sort of response?
  Not that I know of. Mostly math.
Does any of your custom function use a time wasting loop of code?
  No.

It's just that a lot has to happen when the the crank reaches top dead center - reading, calculations, and responses (outputs). And it's just before top dead center that the Nano has to do it's counting - between 0 and 10 pulses, but fast.  The high speed counter on the FMD is counting pulses from a flow meter - nicely now!

Today's quirk is that when I turn on a PWM output, an analog input that I convert to 60 (pounds) jumps to 61!?  Probably not significant and I probably won't spend much time chasing it - it's just that I wish I understood more...

All of your responses help me learn  - Thanks
John

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Fine tuning some timing
« Reply #6 on: April 03, 2015, 10:58:42 PM »
John,

If 90 RPM (strokes per minute) is your target speed, and your system generates one pulse per revolution, the the time between pulses is 0.667 seconds.

There is no reason to attempt to measure your system RPM more often than once every 0.667 seconds.  I'd check the pulse frequency no more often than once Per second. If you call PULSEPERIOD() at a faster rate, say once every 0.1 second, then one of two things must happen:

1. The pulseperiod() function locks up the custom function for a minimum of 0.666 seconds waiting for two consecutive pulses from your sensor.  

     OR

2. Pulseperiod() returns the same value as the previous call.  No new information received! Useless information for the purpose of changing a PWM OUTPUT.

I have not tested the behavior of this function to figure out exactly how it behaves.

In either case it makes no sense to check the speed more often then rate that your transducer sends pulses to the PMON system.  You are either wasting CPU cycles or fooling yourself that you have measured something REAL.

If you are doing some sort of speed control, especially if you are using a PID computation, you should make your measurements and the output adjustments on a consistent time interval.  In your case, once a second is about as often as your system will allow.  It's your system is slows to respond to Input changes, you may want to slow down the measurement/adjustment rate to something that makes sense for your system.

 I'm a big proponent of measuring stuff to determine how much time your custom functions take to execute.  I use the status(21) function at the beginning and end of custom functions as part of my debug. I have found many surprising things this way. Plus, if you ever get the urge to "optimize" your code, it makes the most sense to fix the stuff that wastes the most tine, first.

Another simple thing that you can do is drive a PLC OUTPUT from the 1 second clk signal.  Watch the LED (better yet hook it to a logic analyzer or an ossicoloscope). If you can "see" that this output is anything other that a nice even pulse every second, then you may have a serious problem with your custom function usage and coding.

Gary d
« Last Edit: April 03, 2015, 11:12:26 PM by garysdickinson »

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3174
    • View Profile
    • Internet Programmable PLCs
Re:Fine tuning some timing
« Reply #7 on: April 06, 2015, 11:42:03 AM »
Gary
------

Thanks a lot for the helpful suggestions.  A couple of things that we would like to clarify:

1) PULSEPERIOD and PULSEFREQUENCY functions - these DO NOT lock up the CPU for the full cycle of incoming pulses. What it measures is the captured time between two successive logical rising edge (logic 0 to logic 1) of incoming pulses

2) PULSEFREQUNENCY is computed internally as an inverse to the measured period between two rising edge. So PULSEFREQUENCY should not be any more stable than PULSEPERIOD.  However, since PULSEPERIOD returns a value that is a number of microseconds (default, unless you change it to 0.1us resolution using SETSYSTEM 20,1 command), the number has many significant digits and therefore for a mechanical input such as from a sensor, the value at the lower end would vary a lot.

E.g. if a sensor produces 3.5 Hz out put +/-5% the PULSEPERIOD would return a value between: 272109 to 300752 micro seconds. But PULSEFREQUENCY would return a value of 3 Hz or 4 Hz so it "looks" more stable but it is actually not.

Using PULSEPERIOD allows you to compute the fraction of a Hz by inverting the PULSEPERIOD.

A mechanical device may produce some noise at the transition edge (switch bouncing or jittering)  and if this causes unstable readings some kind of filtering circuit may be needed.

To confirm that the PULSEPERIOD can return a steady value, you can use a PWM output from the same PLC or from another PLC and feed the output to the FMD's PMON or HSC input and you can then read the period and you should be able to see a very stable PULSEPERIOD reading when you observe online.


John,
-------

I am a bit intrigued by the statement:

IF PULSEPERIOD (2)<400000 OR PULSEPERIOD (2)>2000000 THEN
   strokes_per_minute=0 REM crank stopped
ELSE
   ...
ENDIF

Are you using the default 1us measurement of 0.1us measurement?


PULSEPERIOD 400000 == 2.5Hz and PULSEPERIOD 2000000 ==  0.5Hz

It seems like you are only interested in the range of values between 0.5Hz and 2.5Hz.  If your device produces one pulse per revolution it means at 90RPM  there will be 90 pulses per minute or 90/60 = 1.5 pulses per second which is within the range of interest.

But at 0.5pps it is 30 RPM/ Are you ignoring pulses that are < 30rpm? Yet in your post you mentioned measurement of 3 RPM so we are a little bit confused.

In any case, we don't think that at this low frequency pulse inputs you would lose accuracy in the pulse period measurement even if the CPU is very busy with other jobs. The pulse period measurement is handled in the CPU hardware using input capture registers so these are not affected by the CPU work load. Most likely noise or mechanical jitter is the cause of any reading inaccuracy. Also check that the input voltages from the sensor to the PLC falls within the range to activate the input properly. Having a digital storage oscilloscope will be very helpful for trouble-shooting these kind of issues since it let you capture and observe the wave form of signals from the sensor.



« Last Edit: April 06, 2015, 11:46:49 AM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Fine tuning some timing
« Reply #8 on: April 06, 2015, 03:49:49 PM »
Thanks for the clarification on the PMON functions. This will save me a bit of testing.

The reminder that the PulseFrequency() function returns values to the nearest Hz is clearly why it appears more stable.  I am using the PWM ouputs on on PLC to simulate q pulsatile flowmeter for another PLC.  I had forgotten that I evaluated pulse period and pulsefrequncy and kept with pulsefrequency because it was accurate enough for my application.

Thanks,

Gary d

jbrandall

  • Newbie
  • Posts: 19
  • farmer boy
    • View Profile
Re:Fine tuning some timing
« Reply #9 on: April 06, 2015, 06:55:47 PM »
Sorry about the 3 RPM confusion (see my second post).  That was how much I saw my RPM's vary in situation 'A' before I rewrote the code as per Gary's suggestion.  It is better now, but still not rock solid.

In fact I am only interested in speeds of 80 to 95 RPM's as we are using the number generated by the FMD to set a throttle on an engine, and anything below 30 RPM's means the machine is disengaged and coasting towards 0 RPM's.

"To confirm that the PULSEPERIOD can return a steady value, you can use a PWM output from the same PLC or from another PLC and feed the output to the FMD's PMON or HSC input and you can then read the period and you should be able to see a very stable PULSEPERIOD reading when you observe online." -- This line is interesting because at this time of year we are unable to actually test the machine in the field and so I built a simulator of sorts using a couple of spare Nano's.  My (limited) understanding of the PWM output is that it won't go as slow as .5Hz to 2.5Hz.  Am I correct?  If not please show me an example.

I hesitate to post this but the function below is what I use to generate the Nano output using a potentiometer to vary the voltage to ADC(1). (I wrote this a number of years ago and am not sure I understand it now)  It seems to work except for the variation described above as seen by the FMD.

REM set throttle - this runs every Clk:.01s
S=ADC(1)/18
IF S<50 S=50 ENDIF
IF S>200 S=200 ENDIF
T=6000/S
SETLCD 1,1,"Speed = "+STR$(T)
C=C+1
IF C=1 SETIO crank
ELSE CLRIO crank
ENDIF
IF C>S C=0 ENDIF

Thank you again for all the help!

John

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Fine tuning some timing
« Reply #10 on: April 06, 2015, 09:29:25 PM »
John on the PWM OUTPUT the Nano and the FMD series cannot generate a output frequency less than 50 Hz.

The newest Fx series PLCs can generate PWM frequencies from 1 to 50 kHz.  Unfortunately Triangle Research's user manuals for the Fx1616 and Fx2424 are incorrect and indicate that the output range does not go below 50 Hz.

If you dig hard enough on their website you find in a specification tab for the SmartTile Fx product that the PWM frequency is from 1 to 50 kHz.  This is the only place that you will find the correct specifications for PWM. As the SmartTile is the brains of the Fx series PLCs, all of them can go from 1..50 kHz.  This won't help you as you are using the Nano-10.

Your sample code is a convoluted method to generate a low speed pulse train whose period is based on an analog voltage supplied to the ADC(1).  It is not necessary to read the ADC on each call and not necessary to update the LCD on each call.  Your code can be simplified:
 

' Programmable down counter
'
if (C <> 0)
   ' down counter has not reached zero, so just keep going
   '
   ClrIO crank
   C = C - 1
else
   ' counter has reached 0, set OUTPUT
   '  and calculate next pulse period
   '
   SetIO crank   

   C=ADC(1)/18

   ' limit range of down counter to 50..200
   IF C<50
      C=50
   ELIF C>200
      C=200
   ENDIF

   SETLCD 1,1,"Speed = "+STR$(6000/C)
endif   
[/color][/font]

Gary D
« Last Edit: April 06, 2015, 09:33:41 PM by garysdickinson »

support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3174
    • View Profile
    • Internet Programmable PLCs
Re:Fine tuning some timing
« Reply #11 on: April 07, 2015, 12:47:34 AM »
Actually since firmware r79 even Nano-10 and FMD are able to generate PWM pulses with frequency  from 1Hz to 50KHz. I guess the documentation needs some updating on this aspect...

However, the PWM frequency can only be integer. If you want to generate a low frequency output using a Nano-10 to simulate say 1.5Hz you can do so using ladder logic and some timers.

Attached is a simple program that will generate an output pulse of period = 330 x 2 = 660ms or about 1.52Hz. If you transfer this program into the Nano-10 you can use its digital output to generate pulses that you can feed into the FMD for testing.
Email: support@triplc.com
Tel: 1-877-TRI-PLCS