KEJR Posted December 28, 2010 Share Posted December 28, 2010 Hello, I would like the ability to clear the contents of all IO boards in the system upon program start (in a C program). Is there anything provided for this, or is it as simple as doing a clear of memory for all possible cards in the "io" address space? Since am trying to provide this as a library call across various machines I don't want to assign M variables and "manually" clear each byte one by one. Assigning 0s to io space would only work if potential IO cards would respond to this in a safe way. We would do any "non default" initialization of the IO cards after they are cleared. Any ideas? Thank you, KEJR Link to comment Share on other sites More sharing options...
Sina.Sattari Posted January 3, 2011 Share Posted January 3, 2011 KEJR, PMAC will automatically set all the IO to default value (0) upon startup and $$$. You don't have to do this manually. Writing zeros to all IO memory locations can cause unresponsive/malfunctioning cards/gates. Regards, Link to comment Share on other sites More sharing options...
KEJR Posted January 4, 2011 Author Share Posted January 4, 2011 Thanks Sina, This is exactly what I was looking for. I am familiar with $$$ from the turbo processors, but it is sometimes odd translating that to PPMAC since it is such a different animal. Doing a global reset at program start is something we will definitely want to do. KEJR Link to comment Share on other sites More sharing options...
KEJR Posted January 4, 2011 Author Share Posted January 4, 2011 After reading the manual about "$$$" and doing a test this is definitely not what we want. This command reloads the project from flash memory in addition to resetting everything. In addition the "$$$" seems to lose some connections with the IDE. I at least lost connection with the unsolicited messages window. I'd hate to lose my testing code just to reset all of my output cards. Is there a command to just initialize the IO cards (in a generic sense)? Thanks, KEJR Link to comment Share on other sites More sharing options...
Sina.Sattari Posted January 4, 2011 Share Posted January 4, 2011 There is no single function to reset all the outputs. What outputs do you want to reset? Please list all of them. Link to comment Share on other sites More sharing options...
KEJR Posted January 4, 2011 Author Share Posted January 4, 2011 I want to reset output cards generically. The 24In/Out and the 48 bit output cards are the ones we have used in the past and are likely to use again. For now it looks like we will be stuck defining Ptr vars for 8 bit access and resetting all of them manually in a startup script. Its not horrible but something our machine programmers will have to do that we don't currently have to do on other systems (PLCs, robots, etc). I was hoping for something that would be generic such that my C library could zero the IO memory at all possible base addresses, or have a way to query which IO boards were installed (similar to how PCI boards are done) and initialize only the output cards. For a machine with one or two cards its not a big deal, but if you have 3-5 cards that is a lot of inline coding that is quite redundant and prone to cut/paste mistakes. Any ideas? Thank you, KEJR Link to comment Share on other sites More sharing options...
Omron Forums Support Posted January 5, 2011 Share Posted January 5, 2011 Assuming you're using ACC-68E (24 IN/24 OUT), ACC-67E (48-bit OUT), ACC-65E (24 IN/24 OUT), or ACC-14E (48-bit Input/Output), there is a way to automatically detect and set all outputs to zero at power-up using a C PLC. You cannot do this with ACC-11E, because it is an old card and does not have the hardware Power PMAC requires in order to automatically detect it. Following is an example startup CPLC0 to accomplish this: [code] #include #include #include #define CPLC_Number 0 // - User Input #define ACC68E_ASSY_NO 603595 // Assembly number for ACC-68E #define ACC67E_ASSY_NO 603577 // Assembly number for ACC-67E #define ACC65E_ASSY_NO 603575 // Assembly number for ACC-65E #define ACC14E_ASSY_NO 603474 // Assembly number for ACC-14E // Functions to Use for I/O Card Identification // int OffsetCardIO[MAX_GATEIO]; ///< Offset for GateIO[index] from the "piom" ptr // int OffsetCardIOCid[MAX_GATEIO]; // PartData CardIOPartData[MAX_GATEIO]; ///< Gate IO Part Data (VID, CID, OPT) // #define MAX_GATEIO 16 void user_plcc() { unsigned int index = 0,ctr = 0; volatile unsigned int *ioptr; for (index = 0; index < 16; index++) // Cycle through all possible I/O cards { // Check which cards are installed and determine whether they are digital output I/O cards if(pshm->CardIOPartData[index].Num == ACC68E_ASSY_NO || pshm->CardIOPartData[index].Num == ACC67E_ASSY_NO || pshm->CardIOPartData[index].Num == ACC65E_ASSY_NO || pshm->CardIOPartData[index].Num == ACC14E_ASSY_NO) { // If this is an output card, set the whole card to zero ioptr = piom + pshm->OffsetCardIO[index]/4; // Point to card's base address for(ctr = 0; ctr < 6; ctr++) // Cycle through all I/O points on this card { *ioptr = 0; // Set all outputs to zero ioptr++; // Increment to next I/O point } } } pshm->UserAlgo.BgCplc[CPLC_Number] = 0; // Disable this CPLC (run once) return; } [/code] Please note that this example writes zeros indiscriminately to the card's memory addresses; i.e., in some cases, it may be writing zeros to inputs. However, if your control word is set up correctly, this should not affect your inputs whatsoever. This is just a general, all-encompassing example, but you should write something more specifically tailored to your machine. Also note that the algorithm just looks for all cards that can [i]potentially[/i] possess digital outputs. If, for example, the ACC-14E is actually set up to be all inputs, because it is [i]capable[/i] of having outputs, the algorithm will write zeros to its memory addresses anyways. Please note that this CPLC example does not consider ACC-59E. Since this is an analog DAC output card, it functions differently than the aforementioned 4 cards, so the initialization is not so simple. You must know whether you have configured jumper J3 for each ACC-59E (pins 1-2 for bipolar outputs, 2-3 for unipolar outputs). If the DACs are set to bipolar, you must write 2047 to each output point; if unipolar, write 0 to each output point. If you need help writing C code to do this, I have extensive examples - just let me know if you need this and I would be happy to help. They are rather long, so I do not want to post them unless needed. Link to comment Share on other sites More sharing options...
KEJR Posted January 6, 2011 Author Share Posted January 6, 2011 We are using the older IO cards. We use all sinking drivers (company wide) and from what it says on the website the newer cards are all sourcing. I'm checking with our distributor to see if these might be available. The Website doesn't list the old 48 bit input and output cards which is disturbing unless I find an equivalent replacement with sinking IO. I'm using these assembly numbers: 603307-101 (24IN/Out Sinking 24VDC) 603283-100 (48 bit input card 24VDC) 603299-101 (48 bit sinking Output card 24VDC) Thanks for the help though. If I get into the newer cards this information will help. KEJR Link to comment Share on other sites More sharing options...
Sina.Sattari Posted January 6, 2011 Share Posted January 6, 2011 KEJR, The cards that you have mentioned are older cards with no identification chips. Although you can still use them with Power PMAC, there is no official support for them, hence you have to use pointers to access the IO points and they won't be detected by the CPU automatically (since there is no ID chip). However, we do have replacement boards for these and here is the equivalent of these boards with same functionality. ACC-11E (603307) (24IN/OUT 24VDC sinking or sourcing outputs depending on the driver chip selected, sinking or sourcing input depending on wiring) is replaced by ACC-65E (24IN/OUT 12-24VDC sourcing output, sinking or sourcing input depending on wiring) or ACC-68E (24IN/OUT 12-24VDC sinking output, sinking or sourcing input depending on wiring) ACC-9E (603283) (48 Opto 48-bit input card 24VDC) is replaced by ACC-66E (UR Protected OPTO 48-Bit Input Board 12-24 VDC) ACC-10E (603299) (48 bit sinking Output card 24VDC) is replaced by ACC-67E (UR Protected OPTO 48-Bit Output Board 12-24VDC) Regards, Link to comment Share on other sites More sharing options...
Omron Forums Support Posted January 7, 2011 Share Posted January 7, 2011 I just want to clarify something that may not have been clear formerly. Even though the older cards (ACC-11E, ACC-10E, and ACC-9E) do not have automatic detection hardware, you can still clear their outputs at startup using C. It is a little more difficult, however. You need to know which base addresses the I/O cards occupy. The base addresses correspond to which jumper settings (or SW1 if a newer card) are used on the I/O card; for example, E1-E4, shown on page 15 of the ACC-11E manual's pdf, set the base address for ACC-11E. Each card's manual will describe how to set the jumpers or SW1 setting for various base addresses. I have attached a document correlating these Turbo base addresses (those shown in the ACC-11E manual, for example) to the Power I/O base address offsets needed for Power PMAC. To point to the cards, just add piom (pointer to I/O memory) to the value given in the "Power PMAC I/O Base Address Offset" column of the attached document, divided by 4, and point thereto using a volatile unsigned int pointer. Below is an example of how to clear an ACC-11E in a CPLC (CPLC #1) assuming that the ACC-11E is at offset $A00000 (Turbo base address of $78C00, with jumper E1 in place): [code] #include #include #include #define CPLC_Number 1 // Number of this CPLC - User Input #define ACC11E_BaseAddressOffset 0xA00000 // Corresponds to E1 installed on ACC-11E, Turbo base address of $78C00 void user_plcc() { unsigned int ctr; volatile unsigned int *ioptr; ioptr = piom + ACC11E_BaseAddressOffset/4; // Point to card's base address for(ctr = 0; ctr < 6; ctr++) // Cycle through all I/O points on this card { *ioptr = 0; // Set all outputs to zero ioptr++; // Increment to next I/O point } pshm->UserAlgo.BgCplc[CPLC_Number] = 0; // Disable this CPLC (run once) return; } [/code] An alternate, all-encompassing method is to just scan through every single possible I/O card address indiscriminately and set all I/O points equal to zero, regardless of the type of card or even whether a card is installed at that address at all. Depending on your application, this could be dangerous. However, if your desire is simply to set all I/O points possible to zero, and this is safe in your application, you can use this example: [code] #include #include #include #define CPLC_Number 2 // Number of this CPLC - User Input void user_plcc() { unsigned int index, ctr; volatile unsigned int *ioptr; for(index = 0; index < MAX_GATEIO; index++) { ioptr = piom + pshm->OffsetCardIO[index]/4; for(ctr = 0; ctr < 6; ctr++) // Cycle through all I/O points on this card { *ioptr = 0; // Set all outputs to zero ioptr++; // Increment to next I/O point } } pshm->UserAlgo.BgCplc[CPLC_Number] = 0; return; } [/code] Link to comment Share on other sites More sharing options...
KEJR Posted January 10, 2011 Author Share Posted January 10, 2011 Thanks Charles, I had been thinking originally of doing exactly what you suggested but I was cautioned against it because it could have undesired results. What I have been thinking of in light of all this information is to do a smart detection of the cards, and if there is not a card detected at a certain address just go ahead and assume it is an older card and clear its registers. I have to do more testing but I don't see how clearing an input register would be a problem as it should get overwritten by the status of the real input words. I thought I tested this even without setting the control word and it worked OK. I think I'll need more testing. Thank you, KEJR Link to comment Share on other sites More sharing options...
Recommended Posts