MrPLC Member
  • Content count

  • Joined

  • Last visited

Community Reputation

0 Neutral

About OriolFM

  • Rank

Profile Information

  • Country Taiwan
  1. Calling a Timer in ST code.

    Thanks to your example, I figured out a simpler way to handle it. Because I'm using a state machine, I do setup a trigger (in the example, CONV_STARTUP_TRIGGER) which is TRUE when I enter the relevant state (in this case, the startup procedure) and FALSE when I'm outside it. CONV_STARTUP_TIMEOUT(IN:=CONV_STARTUP_TRIGGER, PT:=TIME_CONV_STARTUP); The timer (CONV_STARTUP_TIMEOUT) is a TON which, when the trigger becomes active (when I enter the state, the trigger goes from FALSE to TRUE), the output (CONV_STARTUP_TIMEOUT.Q) becomes FALSE for the specified time (TIME_CONV_STARTUP) and then becomes TRUE until the timer is activated again (by raising flank).
  2. Add time

    ADD_TIME or ADD_TIME_E would be my guess.
  3. Calling a Timer in ST code.

    Dear all, In a state machine I have certain states which need to have a timer to handle timeout errors, that is, if the FSM remains too long in a certain state without getting the conditions to transition to another one, it will produce an error. My current code is using a TOF with an input variable that will be triggered upon entering the state, I call the function block, and then turn the signal off so it starts counting: TRIG_STOP_TIMEOUT := TRUE; TTO_GLOBAL_CYCLE_STOP(IN:= TRIG_STOP_TIMEOUT ,PT:= T#15s ,Q=> ERR_GLOBAL_STOP_TIMEOUT ,ET=> CLK_GLOBAL_CYCLE_STOP ); // TOF TRIG_STOP_TIMEOUT := FALSE; For some reason, the counter does not work. I don't know if I should trigger the signal on in one scan and off on the next. I thought about using the system 1s clock as a trigger (SM412) but the description of the TOF function block states whenever the input is ON, the output will be true, and the timer will only start counting once the input is low. The other thing I thought about was to use the TOF_E instead, with the clock as a trigger, and just set the enable signal when I'm in the state, but I'm not sure it'd work correctly, either. Any suggestions?
  4. I suggest you to use integers to track the current and next states. I would also do the variables volatile. If there is an error, you can just send the machine to whatever standby state you have. If there is a power cut, the machine can initialize the state machine to whatever integer you want on the first scan (even with ladder, you can achieve that with a function block). Personally, I have a special initialization state that is triggered after the machine powers up and that loads the hardware configuration. In this way, I do not rely on persistent variables that could be lost if there is a power cut and the battery in the PLC is depleted.
  5. Recover machine after power up

    I'm quite new to PLC programming, but I have been hardwiring state machines for years. Now I'm programming one in Mitsubishi PLCs, and this has been my approach:  Split the machine in simple interconnected modules for a better error handling and simpler state diagrams.  Have a global state machine for the whole automation that handles general errors, but have each module handling its own errors internally.  Non-critical modules may have errors that allow the rest of the machine to keep running, and can be solved during execution.  Critical module errors send the global state machine into error state. On the first scan, I reset all the machine module states into an "init" state. there, I send each module into manual mode or standby depending on the key setting. Some PLCs have special programs that are executed when the machine powers up, before the main scan. If yours is one of these, you can use that. If not, Crossbow's suggestion of having a non-persistant flag that is set to true on the first scan can work well.  The machine can't self-start after a power cut, so it will wait for the operator to press the start button.  When the start button is pressed, the global state goes into the "startup" state.  Modules which require a startup procedure will execute it at this point (for instance, conveyors will run for 3 seconds to see if there's any material on them). The ones which do not require startup have a blank state where nothing happens.  After startup, each module checks the current situation with the sensors, and will jump into the state that matches the situation.  When all the modules are out of startup, the machine goes into "run" state, with every module picking up in the correct spot in the state diagram. This method has two main advantages: First, you do not depend on persistent variables that can be deleted if there's a power cut and the internal battery of the PLC (if any) is depleted. Second, if something has changed (the operator takes a workpiece out of the machine to prevent it from falling, and so on) the machine will proceed with the program at the right execution point, instead of following the steps and generating errors because a workpiece is missing, for instance. hope this helps.
  6. CASE statement doubts

    Yes, I did try the manual. I've also tried the PDFs for the GX Works 3 manual, the Structured Text Manual, the FX5 program design manual, and the FX5 application manuals. Every place where they reference the <value> in a case statement, they don't specify if it can be a constant. A variable doesn't work because it is an expression and not a value, so I guess internally it's treating constants as expressions and not as values. The program works if I just type the integer for the constant value. There was also another problem I figured out, which is that I can't use an unsigned word as an integer, the GX Works 3 will assume it's a 16-bit array instead, so it will give me a type mismatch error. After changing my variables to signed words, I had no more problems calling functions that require integer parameters, but still I couldn't use the constants in the CASE statement. It's a pity, because the code is much more readable by using integer constants with significative names instead of just integer values.  
  7. CASE statement doubts

    Hello all, I'm quite new to PLC programming, but having learnt digital electronics and programming in PASCAL and C in the 90s, I'm trying to implement a Finite State Machine within an FX5u PLC to control an industrial automation. If it was something for myself that wouldn't require flexibility, I hard-wired it using logic gates, a counter, and latches for inputs and outputs, done several Karnaugh diagrams to simplify the circuit, and so on. If it did require flexibility and it was for a hobby, I'd probably gone for an Arduino or a simple program running in a raspberry pi. However, and since it's for work, I have to use the tools that my fellow co-workers use. Now, in my company they use mostly Mitsubishi PLCs, but they tend to program everything in ladder and using huge, complex programs which are a pain to trace and debug, with a very slow execution time. They also tend to program in iterative steps, but they rely on a clean initial condition (meaning: if there is an error or a power cut, the operator of the machine must empty the material from the automation, home the robot, even reset all the cylinders to their initial positions (with a homing program activated from the HMI), and then restart the machine. To prevent that, and make it more user-friendly, I'm thinking to implement a modular finite state machine where the different modules for the machine (material loading ports, doors, conveyors, robot) are all interlocked together. Having a background in PASCAL programming, it seems like going with ST language will be easier for me to get started in PLC programming. To begin, I've declared a series of global variables for each module, called STATE_<module-name>_CURRENT and STATE_<module-name>_NEXT, all of them set as unsigned int words, so they can store an integer value and I can use them with a CASE statement. Now, for clarity, I was planning on using global constants in those CASE statements. So, if I declare the constant ST_MACHINE_INIT as unsigned int word with value 0, typing ST_MACHINE_INIT should be the same as typing 0 in the CASE statement, and if ST_MACHINE_MANUAL_MODE is declared as a constant with a value of 1, it should be the same as typing 1, right? at least, in PASCAL (upon which the ST language seems to be based) would work like that. I have checked several manuals from Mitsubishi, but I didn't find anything in regard to that. They only say: CASE <variable> OF <value1>: <statement1>; <value2>: <statement2>; END_CASE; However, I've noticed that when I use a constant as value1 (declared as global labels with an unsigned integer value, same as the variables), GX Works 3 is giving me syntax errors after OF and after the statements (represented as ~). CASE <variable> OF~ <value1>: <statement1>;~ <value2>: <statement2>;~ END_CASE; If I replace the constant by the integer value, the syntax error goes away. It seems, then, that GX Works is not accepting constants as values. Is that the case? I prefer to use constants or variables with a fixed, known value instead of just typing the integers for code clarity and because they allow for posterior modifications easily. Does anyone have experience in this? Thanks.