Sign in to follow this  
Followers 0
Bobodopalus

Flip flop in structured text

20 posts in this topic

Hi all

i've been trying to make a simple timer in structured text which is turned on and off by a single input, all instances of flip flops i have found seem to be 2 input. any help or examples would be appreciated

example of programs;

Pulse signal received, start timer

Pulse signal received stop timer

Share this post


Link to post
Share on other sites

What happens when the timer times out? 

A simple flip flop to toggle a bit in ST 

pulse:=input AND NOT temp
temp:=input
IF pulse THEN
	output:= NOT output;
END_IF

 

Share this post


Link to post
Share on other sites

ah great, at the end of the timer it it subtracts from the total time to display time it takes for a cycle

Share this post


Link to post
Share on other sites

Posted (edited)

does this look right? im gonna go test with it now but i find it really hard to monitor ST and see the problem

head_go_pls = input pulse

timer_start = start timer

timer_snap = move the current time so that its stored

pulse:= Head_go_pls AND NOT flip_flop_bit;
flip_flop_bit:= Head_go_pls;
IF pulse THEN
    Timer_snap:= Cycle_timer.PV;
    Timer_start:= NOT Timer_start;
END_IF;

TIMHX(Timer_start, Cycle_timer,500);
Cycle_time_bin:= (500-Timer_snap);
Cycle_time_real:= one_minute/Cycle_time_bin;
Cans_per_min:= Cycle_time_real*Index_amount;

Edited by Bobodopalus

Share this post


Link to post
Share on other sites

hmm i think ive made an error there in stopping the timer, not sure of the best solution

 

Share this post


Link to post
Share on other sites

Do you want the cycle time between every input pulse or every second input pulse?

Starting and stopping the timer using a flip flop will only be able to capture every second pulse.

Share this post


Link to post
Share on other sites

every second pulse is fine, our machines complete a cycle in around 2 seconds, we only need to know roughly how fast its operating and it doesnt need immediate updates

Share this post


Link to post
Share on other sites

Cycle time between pulses in seconds.

Timer_SP:= 2000; (* Timer setpoint *)
pulse:= input AND NOT oneshot;	(*generate pulse on rising edge of input*)
oneshot:=input;
IF pulse THEN
	IF Timer_Start AND NOT timer1.CF THEN (*Calculate cycle time only if timer has not timed out*)
		inst_cycle_time_sec:= UINT_TO_REAL(Timer_SP-timer1.PV)/100.0; (*instantaneous cycle time in seconds*)
	END_IF;
	Timer_Start:= NOT Timer_Start; (* toggle timer every pulse*)
END_IF;
TIMHX(Timer_Start,timer1,Timer_SP);

 

Share this post


Link to post
Share on other sites

If you want every cycle you can change the code to this:

Timer_SP:= 200; (* Timer setpoint *)
TIMHX(TRUE,timer1,Timer_SP);
pulse:= input AND NOT oneshot;	(*generate pulse on rising edge of input*)
oneshot:=input;
IF pulse THEN
	IF NOT timer1.CF THEN (*Calculate cycle time only if timer has not timed out*)
		inst_cycle_time_sec:= UINT_TO_REAL(Timer_SP-timer1.PV)/100.0; (*instantaneous cycle time in seconds*)
	ELSE
			inst_cycle_time_sec:=0.0;
	END_IF;
	timer1.PV:= Timer_SP;
END_IF;

 

Share this post


Link to post
Share on other sites

thanks alot, i'll have a go with this a bit later

Share this post


Link to post
Share on other sites

im having issues with the site today.

here are the errors im having

timer 1 being timer type is incorrect?

invalid instruction i have no idea what this refers to

(i cant seem to upload or add a link for the screenshot)

Edited by Bobodopalus

Share this post


Link to post
Share on other sites

 

the site was down, maybe not everything is working as it should. i noticed the same issue.

detecting edge is basically the same regardless of programming language.
you create another variable of same type and create copy
input is a boolean so any other boolean would be fine to keep copy of the value
then we use the fact that copy is always slightly delayed. if we compare copy with original before value is saved to a copy, we can detect change... 
for boolean signal that would be either rising or falling edge. key is that copy need to be retained...

so pseudo code to detect rising edge is:

; first do a comparison...
IF (X0==TRUE) AND (M0==FALSE) THEN
  ; rising edge detected
ENDIF
; then update copy to be like original  
M0 = X0  


pseudo code to detect falling edge is:

; first do a comparison...
IF (X0==FALSE) AND (M0==TRUE) THEN
  ; falling edge detected
ENDIF
; then update copy to be like original  
M0 = X0  

pseudo code to detect both edges is:

; first do a comparison...
IF X0<>M0 THEN
  ; some edge is detected
ENDIF
; then update copy to be like original  
M0 = X0  


you can use one of the edges (either rising or falling) to toggle some other bit (internal memory or an output)

; first do a comparison...
IF (X0==TRUE) AND (M0==FALSE) THEN
  Y0 = NOT Y0 ; toggle output
ENDIF
; then update copy to be like original  
M0 = X0  

that other bit can be used to enable timer...
 

 

Share this post


Link to post
Share on other sites

sorry this is where my knowledge of plc's really falls apart, in the comment above what does M0 and X0 actually refer to? i really only know the basics of plc's finished uni with very little knowledge and have picked up everything i know since starting this job near the start of the year largely from this website.

and i assume chelton's example should work?

im trying

Timer_SP:= 200; (* Timer setpoint *)
TIMHX(TRUE,timer1,Timer_SP);
pulse:= input AND NOT oneshot;    (*generate pulse on rising edge of input*)
oneshot:=input;
IF pulse THEN
    IF NOT timer1.CF THEN (*Calculate cycle time only if timer has not timed out*)
        inst_cycle_time_sec:= UINT_TO_REAL(Timer_SP-timer1.PV)/100.0; (*instantaneous cycle time in seconds*)
    ELSE
            inst_cycle_time_sec:=0.0;
    END_IF;
    timer1.PV:= Timer_SP;
END_IF;

 

internals:

pulse = bool

oneshot = bool

timer = timer

timer_sp = uint

inst cycle time sec = real

 

but when i compile i get

ERROR: Symbol 'timer1' is the invalid data type(TIMER or COUNTER) in the SFC/ST program.
ERROR: Invalid Instruction

 

whats causing these errors?

 

thanks for all the help both of you

 

also i see images are still not uploadable :(

 

Edited by Bobodopalus

Share this post


Link to post
Share on other sites

timer1 = timer

not

timer = timer

sorry about the formatting. 

Share this post


Link to post
Share on other sites

sorry it is timer1 = timer, i typo'd, can you email it to me if you have made it? or i can send you what i've made if you pm me your email.

 

really missing being able to upload images

Share this post


Link to post
Share on other sites

X0 is some boolean variable such as PLC input. this can be read only variable (such as PLC input)

M0 is another boolean variable that stores last known value of of X0. this need to be a global or at least static variable so it can retain value even after instruction pointer is no longer in the subprogram where the one-shot logic is. this variable needs both read and write access. it you look at M0 over time, it is the same thing like X... just slightly delayed (in case of PLC, that would be one scan or whatever interval is used to execute mentioned code).

Y0 is another boolean variable, much like M0 and if needed it could be a PLC output too.

this is all pretty much the same as posted by chelton. if yo ulook closer you will see that:

X0 = "input"

M0 = "pulse"

 

 

 

Share this post


Link to post
Share on other sites

realised my mistake, the error was caused by me putting the FB onto a test plc i have which is cp1l and not cj2m, cp1l does not use timer type in FB.

so now its working but it seems to be quite inaccurate, but it does seems to be scaled so this can probable be fixed with maths.

im using a TIM block to trigger this now with #40 on the input, the block is activating correctly but for #40 im getting a result of 6 seconds, and for #10 i was getting a result of 1.5 so it seems to be 50% out, im not sure why this is the case.

 

yes after some testing it does seems to be 50% out, i changed the dividing value to 1500 from 1000 and now its accurate, whats causing this difference though?

Edited by Bobodopalus
added testing

Share this post


Link to post
Share on other sites

anyway for this to work on a cp1l?

i am very happy with the program though, thank you very much. i work with CJ2M around 80% of the time and CP1L the rest of the time, im fine with doing the CP1L version differently if needed

Edited by Bobodopalus

Share this post


Link to post
Share on other sites

i found a work around for timers here posted by roze on this forum, still cant link sadly

but that will only work for timers completing i think

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0