Sign in to follow this  
Followers 0
MuttsNutts

IR words

32 posts in this topic

Question: I have a scenario where I use maths to calculate a CIO address and then pass it to a IR. I may get a result of 3200 and I want to pass this to an IR to use elsewhere by calling a subroutine. I do this because I have several blocks of CIO data I wish to manipluate (rather like a set of records) and I can call one subroutine by pointing to the start of the particular block I wish to manipulate at that moment in time. What I have tried so far: I store the result (which is 3200) in a DM word, say, DM20000. I have tried storing the result (3200) in CIO 4000. I use a [MOVR D20000 IR2] in the case of the result being stored in DM20000, and I have tried [MOVR 4000 IR2] in the case of the result being stored in CIO 4000. The subroutine dereferences the IR by using ,IR or +22,IR (if I want the 22nd word from the start of the pointer) but it seems that I end up reading/writing data to DM3200 which is not what I want. I want to read/write data to CIO 3200. Note: I have tried @ options but the MOVR instruction doesn't like it. So, any ideas on how to calculate CIO addresses and use Index Registers to point to this data... or perhaps a different approach? Many thanks, (The) Mutts Nuts

Share this post


Link to post
Share on other sites
Check out this document on Indirect Addressing in Omron PLC's. Looking at your examples, I do not see the "*" symbol, which you would use to indirectly address in BCD. I just looked up the MOVR intruction and learned a little for myself. I had no idea what Index Registers were until now. I think it is very confusing for us 'old school' Omron guys to label the memory area 'IR' as this is the old 'CIO' area. In any case, the tutorial above covers various methods of of indirect addressing including the method you are attempting. Edited by IO_Rack

Share this post


Link to post
Share on other sites
Aha! Much thanks for the "pointer" to the information. It was the [XFER #5 W50 DR0,IR0] that solved the problem for me. Normally you can load a pointer to point to some data and by incrementing or decrementing this pointer data can be manipulated in the word pointed to by the pointer. What I didn't know was that DRx (where x is 0 to 15) can be used as an agrument to the IR operand. IR is useful as once you load it with an address, you can just manipulate pointer to point to somewhere else not only by ,IR2+ (increments by one) but by +18,IR2 (which moves the pointer up 18 places to point to a new location - 18 places higher than the last one) but I hadn't taken the time to learn about DR options. I guess the maximum value that can be stored in DR is 2047 as this is the limit for a constant offset for IR values. Thanks for the help. <enthusiactically selects [File... New...]>

Share this post


Link to post
Share on other sites
Yep, it works with a DRn value beyond +2047 so that means I can calcualte a CIO address (for whatever reason), shove the result (say, 3224) into DR0 and pass this as an offset argument to an Index Register. However, it seems I have to set IR2 to Zero first or it won't work. I can understand why by monitoring IR2... when not loaded with an address it shows 0, but when I give it a bit of [MOVR +0 IR2] then it shows up as C000 so it seems CIO 0000 is stored at physical address Hex C000 in the PLC. Anyways, moving the result (3224) into DR0 and then giving it diesel with a bit of [MOV D32000 DR0,IR2] then I end up moving the value in D32000 into CIO 3224. AB had (...not used AB since PLC5) a nice F300:[offset] facility where "offset" could be F100:20 and this could contain "55" so in actual fact we were moving <whatever> into F300:55. (If memory serves). Adios.

Share this post


Link to post
Share on other sites
Hey there muttsnutts.... I have dabbled using the above IR and DR as you have said, can be confusing to a lot of guys out there though. Well done... sounds like you have experience with programming languages as well from your grasp of the subject. Regards to the AB reference Omron also have a number of other ways to use pointers ie you could use indirect addressing, DIST (distribute), and or COLL (collect) functions as well. Indirect direct addressing is achieved by using an * (asteix) in front of the operand. ie if DM1000 was our pointer and had a value of 200 in it then when used in a function such as MOV *DM1000 D1010 because we used the * the move instruction in this case will move data from DM200 to DM1010. You can increment this pointer with noramal increment/decement instructions and also addition and subtraction instructions.

Share this post


Link to post
Share on other sites
I have just posted a utility in Downloads / Omron / Utilities to convert from Raw PLC addresses to IRs and back the other way. It has an online monitoring tool, but it requires FINSGateway to use online. I still find it quite handy for the conversion aspect.

Share this post


Link to post
Share on other sites
To us "older school" Omron blokes IR is quite a common term. There once was no CIO area only inputs, outputs and IR (internal relays). I found the new IR area confusing at first due to my understanding of the old IR area. Obviously you are a lot younger with Omron PLCs than I.

Share this post


Link to post
Share on other sites
Bob, what would you like us to call them?

Share this post


Link to post
Share on other sites
Actually it reminds me how Omron use to refer to a C20 for example as a PC - (programmable controller)...go figure.... Pretty confusing when you need to find a cable for programming --- which one plugs into the PC, nope that PC..no this PC...

Share this post


Link to post
Share on other sites
Not a problem with IR Jay - it was just a bit confusing when the therminology change to CIO in midstream for the old IRs. Makes sense though.

Share this post


Link to post
Share on other sites
Sleepy, I believe that this was because the term 'PLC' was a registered trade mark of Allen Bradley (please shoot me down in flames if I'm wrong! ), and also at that time, 'PC' was not a common acronym for the computer ( the 'C' ???), which was generally termed as 'IBM PC/AT compatible computer' ! ('IPCATCC' anyone ? ). Best Regards anonymous

Share this post


Link to post
Share on other sites
Hiyo. <----------------------- what a football team, eh? Ahem. Ok, back on topic. Yep, I have used *DMxxxx muchly and it works a treat. Have used COLL (collect) also within a Function Block and by passing in an offset as an argument to the FB, this offset can be used with a COLL instruction to grab some data. My only irk is that within a Function Block, you cannot use the [MOVR] instruction, so if there is a CIO address you want to manipulate, any IR's have to be loaded immediately prior to calling the Function Block. However, I have abandoned FB's somewhat as the be-all and end-all of programming because of their limitations of working as directly with addresses as I'd like. Instead, I am just calling a subroutine with [JSR] like I used to do before. So now I just use a mixture of subroutines and FBs without trying to find every reason under the sun to use FBs. <----------------------- Er, I meant that football team. (If at first you don't succeed, try again) By the way, the "flood control" preventing a repost within 30 secs did make me smile wryly. Now come on guys, don't be all clambouring to post at once... an orderly queue now please On another note (sorry, I do talk a lot) I remember the days of the C28H which I cut my Omron teeth on as well as a CV2000. But as I had to change over to Allen-Bradley I had to relearn Omron PLCs again upon switching back so I have the pleasure of not remembering the IR and CIO issues. (I do remember the "PC" labelling though .... grrrrrr) I give up. (This posting malarkey)

Share this post


Link to post
Share on other sites
Actually Bob, that is what I meant. I just didn't word it correctly.

Share this post


Link to post
Share on other sites
You can use DRs as the offsets from the IRs, and that is how they are intended to be used. Here is an alternative that directly manipulates the IR itself. To calculate and use the address of CIO3200, do the following: Perform your calculation to determine 3200. The result of this must be in HEX or converted to HEX. ie if you are storing the result in DM20000, then DM20000 = 0C80. Also, DM20001 must be 0 because you are going to perform Long Binary math. Now ... MOVR 000 IR0 This loads IR0 with the pointer value to point to CIO 0000. The Value in IR0 is now 0000C000 (HEX). +L IR0 DM20000 IR0 This adds the value in DM20000 and DM20001 (00000C80) to IR0 and stores it back in IR0. After the +L is performed, the value of the pointer itself (IR0) is 0000CC80 (HEX). This points to CIO 3200. This works if you are going to use ,IR in place of a Channel location (ie a DM, CIO, etc.). =============================================================================== If you want to use ,IR0 in place of a bit, and you want to point to 3200.00, then perform the following. MOVR 000.00 IR0 This loads IR0 with the pointer value to point to CIO 0000.00. The Value in IR0 is now 000C0000 (HEX). Note that this is shifted 1 digit to the left of the value in the channel version. Now, since you calculated 3200 as the number of channels to offset from the start of the CIO area, but you are using bits, you must multiply 3200 by 16. Again, all this needs to be in HEX, not BCD. *L #10 D20000 D20002 Multiply your original 3200 (0C80) by 10 Hex (16 bcd) and store in D20002. The result will be 0000C800. +L IR0 DM20002 IR0 This adds the value in DM20002 and DM20003 (000C800) to IR0 and stores it back in IR0. After the +L is performed, the value of the pointer itself (IR0) is 000CC800 (HEX). This points to CIO 3200.00. You can directly manipulate the IRs once they are loaded with MOVR. Use Long Binary math to add and subtract. If you are using the IR as a pointer to channels, then add and subtract the number of CHANNELS that you want to shift. If you are using the IR as a pointer to bits, then add and subtract the number of BITS that you want to shift. Happy IRing.

Share this post


Link to post
Share on other sites
Hey Guys, I have a similar question likemuttsnutts on indirect addressing. So I thaught let me jump in. A brief note on what I'm trying : I am trying to show the values of my I/Os on a single screen on NS12. I have 16 bit lamps connected to a DM word (can change to CIO5000, if need be). My I/Os are scatterd from CIO2000 to CIO2047. (Compobus network!), I want to give the user a facility to scroll through all of them by button. I have the CIO address pointer nicely setup. Upon manipulation of scroll buttons, its giving me exact CIO word address that I need the status of. Now, how can I move/show the VALUE of the CIO word that this pointer is directing? Since @DM points to DM area and CIO doesn's allow @referencing, I'm unable to do it. I tried to use IR the way explained in previous posts, but it actially gives me the address again, I'm looking for the values of those CIO. Any suggestions?

Share this post


Link to post
Share on other sites
[This one is relatively easy (no offense intended). Lets say that your lamp bits on the NS are addressed to DM0000.00 - DM0000.15 (and DMs will work just fine). Perform the following ladder... The MOVR loads IR0 with a pointer to CIO2000 The MOV DR0,IR0 D00000 will move from a location of IR0 (which points to CIO2000) offset by a value of DR0. Your job is to manipulate the value in DR0 from a value of 0000 to 002F HEX. This will represent an offset of 0 to 47 channels. I tried this on an NS8 / CJ1M and it works as shown. P_ON ---------------- MOVR 2000 IR0 | | |--------MOV DR0,IR0 D00000 To manipulate the DR (which is only a single register, just like DM, CIO, etc) use single word signed binary math, or + and - Binary Increment Decrement Instructions.

Share this post


Link to post
Share on other sites
Hi PCMR, Thanks for the post, it is working now. There is specific way you have to move DR, IR which I never used before. And Omron instruction help is very shallow.. One correction though in you post is instead of MOV DR0,IR0 D00000, it should be MOV IR0,DR0 D00000. I have other problem though, when i give value 1, it shows value of word 2002, for 2 it shows 2004, for 3-2006 and so on.. Jumping one. Any clue?

Share this post


Link to post
Share on other sites
I don't know why it seems as though it is jumping by 2. The offset works directly as I described. Are you manipulating the value of the IR at the same time that you are manipulating the value of the DR? When you use DR, leave the value of the IR constant. One thing that you can do facilitate the monitoring of the DR is... If you are adding 1 to both the IR and DR, then the combination of DR0,IR0 would be an offset of 2. I assume that you are doing all the manipulation and data movement in the same PLC task. P_On----------MOV DR0 D200 This will allow you to directly monitor the value in DR0. Just monitor DM200 and it will always have the same value as DR0. You can also monitor the IR in the same fashion. P_On----------MOVL IR0 D200 In this case the value of IR0 will show up as a 2 word wide HEX value, stored in DM200 and DM201. You can then use the IR / DR monitor that I posted in the Download Code section (Omron / Utilites/ IR DR monitor) to show the actual address that the IR is pointing to. And the correct format for using IR and DR together is definitely DR0,IR0. The DR can be replaced by a constant, such as 5,IR0 or -12,IR0. Using the DR allows the offset to be a variable. This holds true for CV, CS1, CJ1, and CP1H processors.

Share this post


Link to post
Share on other sites
Fantastic! Everything OK. PMCR : You are right DR0,IR0 is correct sequence. I had the same way because other way round, the instruction itself rejects it. May be in a hurry I read your post wrongly. Also, I had a MOV left from my previous tries that was changing IR, so you are right, I was changing IR and DR both!. During my tries I observed though that, if DR is 0 and you change IR values, say from 2000 onwards, MOV DR0,IR0 D200 returns the CIO address that is being moved to IR and not the value at that CIO address. Correct me if I'm wrong. The way I'm doing now is, MOVR 0 IR0, and then MOV D240 DR0, where D240 is my pointer to the CIO address want to read. So I read Word by word using MOV DR0,IR0 D200. Thanks for your help PCMR.

Share this post


Link to post
Share on other sites
It sounds like you are well on your way. Even if DR is 0 DR0,IR0 will still return the value that is in the memory location that is being pointed to, not the value of the pointer itself. If you use an IR with a comma before it (,IR0) this is indirect addressing. MOV ,IR0 D200 Most of the time when I am using IR, I don't even use a DR, and just manipulate the IR. You don't need to include a DR in front of the comma. The 2 examples below are functionally the same. MOV ,IR0 D200 or MOV 0,IR0 D200

Share this post


Link to post
Share on other sites
I am depressed! Just when you think you learn something and stand on top of it with an all-conquering flag, along comes someone else with an even better solution and ideas. Good stuff in this thread. Thanks for the feedback and ideas. I was going to give the lot up and go bricklaying (easier life) but sod it, PLCs is where it's at. <grin>

Share this post


Link to post
Share on other sites
In my application I have 200 inputs and 200 outputs aligned one to one. The logic step i used to fire out put with input for perticular time is shown above: where input: 1 is pulse input. I want to get this done 200 times using indirect address... any help...will be really appreciated

Share this post


Link to post
Share on other sites
See attached sample of code. Door_Opening_Example.cxp

Share this post


Link to post
Share on other sites
Amaizing Sparky...Smoking.. Works just great.. And as you said, i am using that for doors. Couple of more question. Can u tell me how will it affect the response time of the PLC?? Does it make any difference if 25-50 timers are running at a time?? Should I use this code at end of the code or in last ledder?? does it matter??

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