flashlights

Send me an IM for my paypal account.

I will quote this one at 100USD.

Flashing lights.

Turn the light on, wait, turn it off.

repeat.

Send funds for complete prog.
 
Send me an IM for my paypal account.

I will quote this one at 100USD.

Flashing lights.

Turn the light on, wait, turn it off.

repeat.

Send funds for complete prog.

Hell, I'm an AB guy but I'll get it done for you with my minimal Siemens experience and I'll even undercut dahnuguy by $25 USD.:D
 
Siemens actually provides a simple all-in-one solution for this problem.

Just buy a brand new S7 416-3F PLC and wait 'till friday 13th. Around 3.30 pm all the lights on the plc (SF, BF, RUN, STOP, etc.) will start flashing automaticly. This happened to us twice. Sadly enough the priority of the flashing lights routine is so high that execution of the user program is halted. For us this means we're waiting for a new PLC, but if flashing lights is all you're after this just might do the trick.

There is a slight possiblity that Siemens has removed the flashing light routines in the latest firmware, in that case please downgrade your firmare. You can find intstructions here. (Just follow the instructions for upgrading but use an older firmware version).
 
How many times do you want them to flash?

If it's just once then connecting 110VAC to a group of 24VDC inputs might do the job.

If it's twice or more then that takes a bit more thinking.

Ken
 
Code:
FUNCTION_BLOCK "Running_Lights_2"
TITLE =
VERSION : 0.1


VAR_INPUT
  Direction : BOOL ;    //0:Run Left   1: Run Right
  Pulse : BOOL ;        //Pulse for next step
  Init : BOOL ;         //First initialisation
END_VAR
VAR_OUTPUT
  Word_out_1 : WORD ;    
  Word_out_2 : WORD ;    
END_VAR
VAR
  Internal_Direction : BOOL ;    
  Internal_Counter : INT ;    
END_VAR
VAR_TEMP
  Dword_Pointer : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      A     #Init;                // If initialisation
      JC    INIT;                  // then jump to initialisation

      AN    #Pulse;                // If no pulse at input
      BEC   ;                      // then terminate this block

      L     P##Word_out_1;         // Load the adress of the output
      T     #Dword_Pointer;        // And store it as a pointer

      L     #Internal_Counter;     // The internal direction is
      L     1;                     // inverted if the direction input
      A     #Internal_Direction;   // is true.
      X     #Direction;            // If the combined direction is true
      JC    UP;                    // than 1 will be added to the counter
      -I    ;                      // otherwise 1 will be subtracted
      JC    COMM; 
UP:   +I    ; 

COMM: JM    ToLe;                  // Negative --> Top Left Transition
      L     32; 
      ==I   ; 
      JC    BoRi;                  // 32 --> Bottom Right Transition 
      TAK   ;                      // Toggle accumulators
      L     16; 
      ==I   ;                      // Internal Direction = True
      A     #Internal_Direction;   // and
      JC    BoLe;                  // 16 --> Bottom Left Transition
      TAK   ; 
      L     15; 
      ==I   ;                      // Internal Direction = False
      AN    #Internal_Direction;   // and
      JC    ToRi;                  // 15 --> Top Right Transtion
      TAK   ; 
      JU    NOTR;                  // No Transition

ToLe: L     16;                    // [Top Left Transition]
      JU    SWDR;                  // Internal_Counter = 16
BoRi: L     15;                    // [Bottom Right Transition]
      JU    SWDR;                  // Internal_Counter = 15
BoLe: L     31;                    // [Bottom_Left Transition]
      JU    SWDR;                  // Internal_Counter = 31
ToRi: L     0;                     // [Top_Right Transition]

SWDR: AN    #Internal_Direction;   // Invert the
      =     #Internal_Direction;   // Internal_Direction

NOTR: T     #Internal_Counter;     // Store the new Internal_Counter
      L     #Dword_Pointer;        // Add it to the pointer
      +I    ; 
      T     #Dword_Pointer;         // And store the new pointer

      L     0; // Clear all bits
      T     #Word_out_1;            // In both ouput words
      T     #Word_out_2; 
      SET   ;                       // Set the bit identified
      =     DIX [#Dword_Pointer];   // by the pointer
      BE    ;                       // Block end

INIT: L     0; 
      T     #Internal_Counter;      // Reset Internal_Counter
      SET   ; 
      =     #Internal_Direction;    // Set Internal_Direction forward

END_FUNCTION_BLOCK

DATA_BLOCK "DB_Running_Lights_2"
TITLE =
VERSION : 0.0

"Running_Lights_2"
BEGIN
   Direction := FALSE; 
   Pulse := FALSE; 
   Init := FALSE; 
   Word_out_1 := W#16#0; 
   Word_out_2 := W#16#0; 
   Internal_Direction := FALSE; 
   Internal_Counter := 0; 
END_DATA_BLOCK
It actually does exactly the same as:

Code:
FUNCTION_BLOCK "Running_Lights"
TITLE =Running lights
VERSION : 0.1


VAR_INPUT
  Direction : BOOL ;    //1:Run Left   0: Run Right
  Pulse : BOOL ;    //Pulse for next step
  Init : BOOL ;    //First initialisation
END_VAR
VAR_OUTPUT
  Word_out_1 : WORD ;    
  Word_out_2 : WORD ;    
END_VAR
VAR
  Now_Shifting_Word_1 : BOOL ;    
  Now_Shifting_Word_2 : BOOL ;    
  Shift_Word_1 : WORD ;    
  Shift_Word_2 : WORD ;    
END_VAR
VAR_TEMP
  Overflow_Occured : BOOL ;    
  Word_All_Zeros : WORD ;    
  Word_MostSignificantBit : WORD ;    
  Word_LeastSignificantBit : WORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Define constants

      L     2#0; // 0000_0000_0000_0000
      T     #Word_All_Zeros; 

      L     2#1; // 0000_0000_0000_0001
      T     #Word_LeastSignificantBit; 

      L     2#1000000000000000; // 1000_0000_0000_0000
      T     #Word_MostSignificantBit; 
NETWORK
TITLE =Initialisation

      O     #Init; 
      O     ; 
      A(    ; 
      L     #Word_out_1; 
      L     #Word_All_Zeros; 
      ==I   ; 
      )     ; 
      A(    ; 
      L     #Word_out_2; 
      L     #Word_All_Zeros; 
      ==I   ; 
      )     ; 
      O     ; 
      A(    ; 
      X     #Now_Shifting_Word_1; 
      X     #Now_Shifting_Word_2; 
      )     ; 
      NOT   ; 
      =     L      8.0; 
      A     L      8.0; 
      JNB   _001; 
      L     #Word_LeastSignificantBit; 
      T     #Shift_Word_1; 
_001: NOP   0; 
      A     L      8.0; 
      JNB   _002; 
      L     #Word_All_Zeros; 
      T     #Shift_Word_2; 
_002: NOP   0; 
      A     L      8.0; 
      BLD   102; 
      S     #Now_Shifting_Word_1; 
      A     L      8.0; 
      BLD   102; 
      R     #Now_Shifting_Word_2; 
NETWORK
TITLE =Shift word 1 left or right

      A     #Pulse; 
      A     #Now_Shifting_Word_1; 
      =     L      8.0; 
      A     L      8.0; 
      A     #Direction; 
      JNB   _003; 
      L     1; 
      L     #Shift_Word_1; 
      SLW   ; 
      T     #Shift_Word_1; 
_003: NOP   0; 
      A     L      8.0; 
      AN    #Direction; 
      JNB   _005; 
      L     1; 
      L     #Shift_Word_1; 
      SRW   ; 
      T     #Shift_Word_1; 
_005: NOP   0; 
NETWORK
TITLE =Shift word 2 left or right

      A     #Pulse; 
      A     #Now_Shifting_Word_2; 
      =     L      8.0; 
      A     L      8.0; 
      A     #Direction; 
      JNB   _006; 
      L     1; 
      L     #Shift_Word_2; 
      SRW   ; 
      T     #Shift_Word_2; 
_006: NOP   0; 
      A     L      8.0; 
      AN    #Direction; 
      JNB   _007; 
      L     1; 
      L     #Shift_Word_2; 
      SLW   ; 
      T     #Shift_Word_2; 
_007: NOP   0; 
NETWORK
TITLE =Overflow occurred

      A     >0; 
      A     #Pulse; 
      =     #Overflow_Occured; 
NETWORK
TITLE =Overflow occurred when shifting Word 1 Left

      A     #Overflow_Occured; 
      A     #Now_Shifting_Word_1; 
      A     #Direction; 
      =     L      8.0; 
      A     L      8.0; 
      JNB   _009; 
      L     #Word_All_Zeros; 
      T     #Shift_Word_1; 
_009: NOP   0; 
      A     L      8.0; 
      JNB   _00a; 
      L     #Word_MostSignificantBit; 
      T     #Shift_Word_2; 
_00a: NOP   0; 
NETWORK
TITLE =Overflow occurred when shifting Word 1 Right

      A     #Overflow_Occured; 
      A     #Now_Shifting_Word_1; 
      AN    #Direction; 
      =     L      8.0; 
      A     L      8.0; 
      JNB   _00b; 
      L     #Word_All_Zeros; 
      T     #Shift_Word_1; 
_00b: NOP   0; 
      A     L      8.0; 
      JNB   _00f; 
      L     #Word_LeastSignificantBit; 
      T     #Shift_Word_2; 
_00f: NOP   0; 
NETWORK
TITLE =Overflow occurred when shifting Word 2 Left

      A     #Overflow_Occured; 
      A     #Now_Shifting_Word_2; 
      A     #Direction; 
      =     L      8.0; 
      A     L      8.0; 
      JNB   _014; 
      L     #Word_LeastSignificantBit; 
      T     #Shift_Word_1; 
_014: NOP   0; 
      A     L      8.0; 
      JNB   _015; 
      L     #Word_All_Zeros; 
      T     #Shift_Word_2; 
_015: NOP   0; 
NETWORK
TITLE =Overflow occurred when shifting Word 2 Right

      A     #Overflow_Occured; 
      A     #Now_Shifting_Word_2; 
      AN    #Direction; 
      =     L      8.0; 
      A     L      8.0; 
      JNB   _016; 
      L     #Word_MostSignificantBit; 
      T     #Shift_Word_1; 
_016: NOP   0; 
      A     L      8.0; 
      JNB   _017; 
      L     #Word_All_Zeros; 
      T     #Shift_Word_2; 
_017: NOP   0; 
NETWORK
TITLE =Overflow occured -> Next pulse shift other word

      A     #Overflow_Occured; 
      =     L      8.0; 
      X     L      8.0; 
      X     #Now_Shifting_Word_1; 
      =     #Now_Shifting_Word_1; 
      X     L      8.0; 
      X     #Now_Shifting_Word_2; 
      =     #Now_Shifting_Word_2; 
NETWORK
TITLE =Write Ouput Word 1

      L     #Shift_Word_1; 
      CAW   ; 
      T     #Word_out_1; 

NETWORK
TITLE =Write Ouput Word 2

      L     #Shift_Word_2; 
      CAW   ; 
      T     #Word_out_2; 

END_FUNCTION_BLOCK

DATA_BLOCK "DB_Running_Lights"
TITLE =
VERSION : 0.0

"Running_Lights"
BEGIN
   Direction := FALSE; 
   Pulse := FALSE; 
   Init := FALSE; 
   Word_out_1 := W#16#0; 
   Word_out_2 := W#16#0; 
   Now_Shifting_Word_1 := FALSE; 
   Now_Shifting_Word_2 := FALSE; 
   Shift_Word_1 := W#16#0; 
   Shift_Word_2 := W#16#0; 
END_DATA_BLOCK
 
Last edited:
How many times do you want them to flash?

If it's just once then connecting 110VAC to a group of 24VDC inputs might do the job.

If it's twice or more then that takes a bit more thinking.

Ken

Well thats better than reading the comics right there.
 
Call a Function from OB32 set up for one second with the following code.

AN Q1.7
= Q1.7

Output 1.7 will be on for a second, off for a second and so on whilst the PLC runs.

I do exactly this to provide a watchdog output from the PLC. The output is either monitored by another PLC or by a low cost module usually used to detect stoppage or belt broken for a conveyor.
 
Call a Function from OB32 set up for one second with the following code.

AN Q1.7
= Q1.7

Output 1.7 will be on for a second, off for a second and so on whilst the PLC runs.

I do exactly this to provide a watchdog output from the PLC. The output is either monitored by another PLC or by a low cost module usually used to detect stoppage or belt broken for a conveyor.

If you used the PLC clock bits you wouldn't need any code :)
 
Back
Top Bottom