Van

MrPLC Member
  • Content count

    33
  • Joined

  • Last visited

Community Reputation

0 Neutral

About Van

  • Rank
    Sparky

Contact Methods

  • Website URL http://www.StokesIndustries.com

Profile Information

  • Country United States
  1. In CX-Programer, RIGHT-CLICK on the program section and there is an option to view it in mnemonic.
  2. A big thanks to everyone for their help. I wrote a test application and used the PLC simulator (CXL-Programmer 7.2) to try and understand just what was actually happening. I didn't just want to know WHAT DIFU does but HOW it actually worked. My suspicions were correct. Using Multiple DIFUs for the same memory address is detrimental. Although it doesn't say it in the manual, in reality you should only use DIFU once per memory address. This may be common knowledge to you PLC folk. Attached are two little application I wrote. DIFU_TEST_GOOD - shows a typical application using a DIFUs with each having it's own memory address. DIFU_TEST_BAD - shows an application using two DIFUs using the same memory location (W0.00). Note RUNG 2. If you run DIFU_TEST_BAD in the simulator the PLC simulator behaves unpredictably (exactly what is happening in my real PLC). I noticed a couple of scenarios happening: 1) Stepping through the code (SET W0.00 ON) you will notice that in just the same scan DIFU will change states twice. If W0.00 is ON, W0.01 will go ON in RUNG 1 however, in RUNG 2 if W0.02 is OFF, W0.01 will go OFF. 2) OR; Stepping through the code (SET W0.00 ON) you will notice that the DIFU in RUNG 1 does nothing to W0.01. If in RUNG 2: 2A) W0.02 is ON, W0.01 will go ON. 2B) W0.02 is OFF, W0.01 will stay OFF. It would appear that a DIFU instruction is always evaluated at every occurrence irregardless of the logic in front of the instruction. In other words, every DIFU instruction is processed using some logic similar to the following: IF DIFU = TRUE THEN DIFU = FALSE ELSE IF LOGIC=TRUE THEN DIFU = TRUE Also note. The DIFU'd bit changes state at a every scan. For a DIFU, a scan appears to be a loop FROM the DIFU location back to the DIFU. Again, that may be common knowledge to you PLC folk but in the PLC programmers manual I read, a scan was defined to be from TOP of PLC code to BOTTOM of PLC code. That made it confusing to me. DIFU_TEST_BAD.cxp DIFU_TEST_GOOD.cxp
  3. It's up to the programmer. The programmer can do it: 1) at the top of every loop (scan) 2) at the bottom of every loop (scan) 3) at the next pass of the function/command/method that is responsible for the bit. Could be in the middle of the loop. This is why I ask the question: At what point does the signal actually rise and fall. If I DIFU a bit in the middle of the curent scan, is the bit ON for the rest of the current scan or, does he bit remain off until the start of the NEXT scan?
  4. I would like to better understand the above statement: BEGIN SCAN ONE *** TASK A *** RUNG 1: IF AA then Do Stuff (<---- AA False) RUNG 2: Do Stuff *** TASK A *** *** TASK B *** RUNG 1: IF BB then DIFU AA (<--- BB is TRUE this scan so AA goes from False to True) RUNG 2: Do Stuff *** TASK B *** *** TASK C *** RUNG 1: IF AA then Do Stuff (<---- Is AA True of False?) RUNG 2: Do Stuff *** TASK C *** END SCAN ONE BEGIN SCAN TWO *** TASK A *** RUNG 1: IF AA then Do Stuff (<---- Is AA True or False?) RUNG 2: Do Stuff *** TASK A *** *** TASK B *** RUNG 1: IF BB then DIFU AA (<--- Is this where AA is reset to false again? (BB is FALSE this scan) ) RUNG 2: Do Stuff *** TASK B *** *** TASK C *** RUNG 1: IF AA then Do Stuff (<---- Is AA True or False?) RUNG 2: Do Stuff *** TASK C *** END SCAN TWO
  5. Equipment: CJ1M-CPU12 I have mentioned before that I am a PC programmer learning how to program PLCs so please keep this in mind. I think like a PC programmer. I read about DIFU (and DIFD) and thought this was the neatest tool. So, I used it all over my programs. However, I starting to think this is also part of my problem. I suspect DIFU is a two-edged sword. My program behaves irrationally. It sometimes works and sometimes doesn't. I can't figure it out. I am using the DIFU for the same bit in multiple rungs of a task and in multiple tasks. I suspect this might be my problem. I just realized that, although only one task/rung may execute the DIFU instruction on the bit - I don't know when the bit truly gets set and reset. Is the bit reset when the same DIFU that flipped the bit is encountered on the next scan? Or is the bit reset on the very next encounter of a DIFU instruction? Or is the bit reset at the very end of the current scan or the beginning of the next scan? Am I guaranteed that the bit will survive a complete scan before it's reset (i.e. every rung of every task will have access to the high signal?)? If so, then What is a complete scan to DIFU? Also, does it matter where DIFU you is in the program? Can I DIFU on TASK 30 and TASK 2 still get the signal? Here is an example of logic in pseudo code: BEGIN SCAN **** TASK A **** RUNG 1: if BIT-AA then DO STUFF RUNG 2: if BIT-A then DIFU BIT-ZZ **** TASK A **** **** TASK B **** RUNG 1: if BIT-BA then DO STUFF RUNG 2: if BIT-B then DIFU BIT-ZZ RUNG 3: if BIT-BB then DIFU BIT-AA **** TASK B **** **** TASK ZZ **** RUNG 1: IF BIT-ZZ then DO STUFF RUNG 2: IF BIT-ZA then DIFU BIT-AA RUNG 3: IF BIT-ZB then DIFU BIT-BA **** TASK ZZ **** END SCAN Is the above logic valid for DIFU? I suspect that there is something wrong with my logic here.
  6. I have two PLCS: CJ1M-CPU12-ETN (built in Ethernet) and a CJ1M-CPU11 + CJ1W-ETN21 According to the manual, the ethernet modules are the same (ENT21). The version codes are the same (V1.4). I have configured both Ethernet modules (CPU built-in and the CJ1W) with the same UNIT NO so that our PLC code is portable between both units. However, the socket TCP function block code DOES work on the CPU11 + CJ1W-ENT21 but will NOT work on the CJ1M-CPU12-ETN. Am I missing something?
  7. Equipment: CJ1M-CPU12 ETN (ETN21) Using the CPU's ENT21 and the CPU's RS232 I have programmed three tasks: 1. XMT - Transmit data to my FUJI inverters via RS232. 2. RCV - Receive data from my FUJI inverters via RS232. 3. NET - Network send/recv via ETN21. If I enable the NETWORK task, the RCV task will no longer receive RS232 traffic. However, if I disable the NETWORK task, the RCV task works just fine. I have poured over and over and over my Symbols and memory assignments to make sure nothing is stepping on one another. I have run the Validate Symbols, etc. I went back to the manuals to find if I could not use both I/O devices at the same time. I can't seem to find anything mentioned like that (nor did I expect too). I am at a loss as to why that when the NETWORK is enabled (using Omron TCP function blocks OPEN, CLOSE, SEND, and RECV) the RS232 WILL TRANSMIT data but WILL NOT RECEIVE data. I know data is being sent back (used a sniffer and I can see it) and, like I said, if I disable the NETWORK task it works fine. Anyone have any idea why this is occurring?
  8. OK, I found it. My Bad. I was looking in the wrong manual. The Ethernet Units Construction of Applications (not Networks) section 6-6 has my answer.
  9. Equipment: CJ1M-CPU12 with CJ1W-ENT21 I have successfully programmed the PLC to accept a TCP socket connection (Passive TCP) and write data to and from the PC. However, I noticed that when I disconnect the TCP port (simulating a closed/lost connection) the PLC keeps the port open and will not accept another connection. I want to monitor for a lost or closed connection so I can reset (close and reopen) the port. I know that I need to do this but I can't seem to trap the lost connection. There doesn't seem to be any documentation on lost connectivity. How do I trap for a lost or closed TCP socket connection?
  10. Is there a way to add entries to the PLCs error log? I dont' see an instruction in the help that appears to permit this.
  11. More TKON - Interrupt Tasks

    What you have described is exactly what is happening. I will look into "subroutines". Thank you.
  12. Equipment: Omron CJ1M-CPU11 I read the programming manual and the instruction manual. Either the manual is missing something (doubt it) or I am overlooking something obvious (more likely)... I am attempting to use an interrupt task as a subroutine/function to be called from the main code (cyclical tasks) to populate memory space. According to the manual, when an interrupt task is called (via. TKON) from a cyclical task the execution is immediate: branches at TKON; executes the interrupt task; returns to the TKON interrupt point. I see this working however if I make multiple calls to my interrupt task from the same cyclical task (but separate rungs) in the same pass only the last called TKON is executed (i.e. last condition set for the TKON routeine to work from). I can see this by monitoring the memory space the interrupt task is writing too (a circular buffer). There should be TWO buffer (memory) writes but only the last call is writing to the buffer memory space. The PLC appears to be acting as if the changes to the memory space have not been committed at the end of the interrupt task. That is, only the last "push to stack" is being executed. Now, If I disable either rung it works properly. I did see this little blurb in the instruction manual: Immediate Refreshing Specification Not supported. I have a sneaky suspension I am about to learn what this really means. Do I have to wait for the cycle to finish before making the next TKON call? pseudo code: === BEGIN PASS === *** Cyclical Task 00 START -- SECTION 01 BEGIN RUNG 1: Set Data for TKON RUNG 2: CONDITION TRUE--->TKON(8011) RUNG 3: Set Data for TKON RUNG 4: CONDITION TRUE--->TKON(8011) -- SECTION 01 END *** Cyclical Task 00 END === END PASS === *** Interrupt Task 8011 START (do stuff here) *** Interrupt Task 8011 END
  13. @Sergei Troizky: You were right, there was nothing truly wrong with the math when viewed in decimal. Thank you for that hint. I did find that I was using the wrong indirect addressing operand. I was using "*" and should have been using "@". That made the difference and now it's working. I have two PLCs: development and production. Dev: is a CJ1M CPU11 Prod: is a CJ1M CPU12 The difference, from what I was told, is addressable space. The CPU12 has more memory than the CPU11. But don't take my word for it. I'm not an expert. I'm only repeating what the Omron dealer told me.
  14. Thank you. I will double check my view (i.e. HEX vs DEC). I am using a CJ1M - CPU11 (and CPU12).
  15. OK. I'm having trouble understanding how to properly perform the math to do Indirect Addressing. Here is my setup: I have allocate some memory space to use as a circular buffer: D5900-D5999. Each buffer segment size is nine (9) continuous words. I have a FOR/NEXT loop that loops through each buffer segment and evaluates the first element (word) of each buffer segment to see if that buffer segment is available for use. For right now, there are only nine buffer segments. I am having trouble doing the multiplication and addition. I keep coming up with invalid memory addresses like 596A (i.e. HEX addresses) instead of it properly rolling over after 9 to next memory word location. In the FOR/NEXT I increment a multiplier starting at zero (0). I then take that multiplier and multiply it by nine (9) (the buffer segment size) and then add it to the starting memory location (D5900). Once I establish the base, I then attempt to create the remaining eight (8) element addresses by adding one (1) to the previous memory address. 0 (multiplier) X 9 (buffer segment size) = 0 (memory offset) 5900 (base memory address) + 0 (memory offset) = 5900 (first buffer element (word) ) 5900 + 1 = 5901 (second buffer element (word) ) 5901 + 1 = 5902 (third buffer element (word) ) ... and so forth to nine (5909). now, ZERO works great, however I have a problem when I want to use a multiplier greater than zero (0). Here is the mnemonic code: ' Circular Buffer.\nLocate an available memory space. FOR(512) XMT_SF_QUEUE_SIZE ' Check for invalid state. LDNOT XMT_SF BREAK(514) ' Increment Data Buffer Offset. LD XMT_SF ++(590) XMT_SF_DB_ADDR_MULT ' Compute and set memory offsets.\nThis is for use with indirect addressing. LD XMT_SF *(420) XMT_SF_DB_ADDR_MULT XMIT_SF_DB_SIZE XMT_SF_DB_ADDR_OFFSET +(400) XMT_SF_DB_ADDR_OFFSET XMT_SF_DB_BASE_MEM XMT_SF_DB_ADDR_STATE +(400) XMT_SF_DB_ADDR_STATE &1 XMT_SF_DB_ADDR_W01 +(400) XMT_SF_DB_ADDR_W01 &1 XMT_SF_DB_ADDR_W02 +(400) XMT_SF_DB_ADDR_W02 &1 XMT_SF_DB_ADDR_W03 +(400) XMT_SF_DB_ADDR_W03 &1 XMT_SF_DB_ADDR_W04 +(400) XMT_SF_DB_ADDR_W04 &1 XMT_SF_DB_ADDR_W05 +(400) XMT_SF_DB_ADDR_W05 &1 XMT_SF_DB_ADDR_W06 +(400) XMT_SF_DB_ADDR_W06 &1 XMT_SF_DB_ADDR_W07 +(400) XMT_SF_DB_ADDR_W07 &1 XMT_SF_DB_ADDR_CS ' Is this buffer (memory) space available for use? LD XMT_SF LD=(300) *XMT_SF_DB_ADDR_STATE XMT_SF_DB_STATE_AVAIL OR=(300) *XMT_SF_DB_ADDR_STATE #0000 ANDLD SET XMT_SF_DB_AVAIL BREAK(514) NEXT(513) LD XMT_SF ANDNOT XMT_SF_DB_AVAIL MOV(021) EC_XMT_SF_DB_FULL XMT_SF_ERROR_CODE Where am I going wrong?