MickeyBob

MrPLC Member
  • Content count

    29
  • Joined

  • Last visited

Posts posted by MickeyBob


  1. I downloaded your code but can't open the project. I get "The CPU of the specified project is not supported by this version. Specify a project corresponding to the CPU." What am I doing wrong? I'm a newbie with GX-Developer so be kind. :)

  2. I guess at this point the only question I have is with regard to the MI command. It sounds like this command really isn't necessary for reading/writing registers. At this point, learning more about the MI command would only satisfy my personal curiosity. If you have found some more information on it, I would like to look at it. Thanks for the help and for being a sounding board!

  3. Ok, I think I have a little better handle on the QQMR and QQIR commands. I'll try to lay it out without confusing me and you When specifying items for the registered I/O table, you specify the area (e.g., HR, WR, DM, etc.), the word address (e.g., 0-9999 for DM), and a bit. For a typical register (all registers except a timer or counter), you can specify a bit from 00 to 15 as you would expect. You can also specify a bit of "CH", which, I surmise, stands for "channel". In this case, the word value is registered (e.g., "@00QQMRDM 0000CH" registers the word value of DM0000). If you use the QQIR command to read a bit, it comes back as a '1' or '0'. If you read a word, it comes back in four hexadecimal digits. But, timers and counters are different. You can specify any two digit number for the bit. No matter what bit you specify, it registers the status bit of the timer/counter. If you specify a bit of "CH" for a timer or counter, both the PV and status bit of the timer/counter are registered (e.g., "@00QQMRTIM 0000CH" registers both the status bit and PV for T0). If you use the QQIR command to read a timer/count "CH" bit, you get back 5 hexadecimal digits. The first digit is either '1' or '0' and corresponds to the timer/counter's status bit. The remaining four digits are the PV word value. Hope I didn't muddy the water further...
    1 person likes this

  4. Here some more info... I've gotten the QQMR and QQIR commands to work, sorta. I can properly register and read individual bits. For example, the command "@00QQMRHR 000000,HR 000001" registers H0.0 and H0.1. Then when I execute "@00QQIR", the current values are returned as "0,1", assuming that H0.0 is reset and H0.1 is set. However, I haven't figured out how to read word data yet. The format of the QQMR command as shown on page 95 of W342-E1-1 makes reference to the "word data designation" (just below the first line of the command format). I don't understand from this reference how to register a whole word. I also haven't figured out how to read timer/counter PVs and SVs. I have found out from experimentation that I can specify up to 3 bits for a timer/counter (i.e., "@QQMRTIM 000000,TIM 000001,TIM 000002" returns "0,0,0") but don't know to what these map. Trying to read a fourth bit generates a error code 14. Thanks again.

  5. Maybe, I'm confusing you with the term "I/O table". I'm using it in the same sense (I think) as the reference manual, that is, a collection of registers (DM, TIM, EM, IR, etc) that is registered with the CPU using the QQMR command. (which seems to me to be consistent with your last comment) Then, when the QQIR command is issued, the CPU returns the values of the "registered" registers in a comma separated format. I suspect you're thinking of the "I/O table" as the actual PLC I/O configuration table...maybe? Am I understanding this correctly or am I in left-field? Thanks

  6. I had a case of fat fingers or a brain burp (more likely). I meant the MI command instead of the MM command. I have both a hard copy and an electronic copy of the communications manual that I have been referencing but was having trouble putting these particular commands into prospective. I really wasn't sure what a "registered I/O table" meant. Your explanation helped a lot. So if my understanding is correct, I would need to issue the QQMR command to "preregister" the I/O table, the MI command to "correct" or "generate" the I/O table (i.e., have the CPU populate the I/O table with actual values), and then the QQIR command to read the I/O values. To get updates on the same data at a later time, all I would need to do is issue the MI and QQIR commands. Is this correct? Thanks for the help!

  7. I'm implementing a serial HostLink protocol in the open source language Python and have completed just about everything but the MM, QQMR, and QQIR commands. I don't really have a good understanding of what these commands do, what they are used for, and how to use them. Can anyone help me understand these better. Any help will be greatly appreciated. Thanks, MickeyBob P.S. If any one is interested in beta testing my implementation, please let me know.

  8. I have a question about specifying the unit number within a host link (i.e., C-mode) command. According to the manual W342-E1-06 (Communication Command Reference Manual), the unit number is specified in BCD. I'm unsure as to what this really means. Does it simply mean that, for example, unit 15 is specified by the two ASCII characters "1" and "5" (e.g., "@15TSABC07\13") or is it more complicated (e.g., the BCD binary equivalent for decimal 15 is specified in hexadecimal)? Any clarification on this would be greatly appreciated. Thanks, MickeyBob

  9. Rock, Here's a PDF with some figures and a graph that may help clarify your confusion. It gives some concrete examples of how the system works. Let me know if you have any questions. MickeyBob Encoder_Scaling.pdf

  10. I need help figuring out how best to update I/O from a timed interrupt on a CJ1M-CPU21. I have an application where the majority of the time the interrupt is disabled. It is enabled when the value on an analog input exceeds a threshold and is disabled again when the input exceeds a second threshold. I want to refresh the same input value used to enable the interrupt from within the interrupt with the IORF(097) instruction. However, when I enable the interrupt, I immediately get the "Interrupt Task Error Flag" which, according to the Instruction Reference Manual (W340-E3-04), indicates that "IORF(097) was executed in an interrupt task without disabling Special I/O cyclic refreshing." The manual goes on to further say "If cyclic refreshing with the Special I/O Unit isn’t disabled, IORF(097) might be executed during cyclic refreshing resulting in a non-fatal Duplicate Refresh Error and turning ON the Interrupt Task Error Flag (A40213)" I suppose I could disable normal (i.e., cyclic) updating of the input from the setting dialog in CX-Programmer but this would make the input value unavailable when the timed interrupt is disabled. I don't want the interrupt enabled all the time because of the processing overhead. To overcome this problem, I could institute another interrupt that is enabled all the time and it only updates the input. Is this the right way to do this? What are the alternatives? According to the manual, the error is non-fatal. Does this mean the I/O update collision occurred but it didn't really harm/affect the input value? When the error occurs, the error LED on the CPU is turned on and it remains on. Is there a way to reset the error flag in code? Assuming the collision doesn't really mess up the input value, is there a way to "mask" the error? I'll appreciate any insight you guys can provide. Thanks, MickeyBob

  11. Yeah, I thought about that. Call me anal but I hate mixing integers with floats eventhough they are binaryly (new word) the same. I believed I tried other floating-point literals and some worked and other didn't. I can't recall off the top of my head which floats literals worked and which didn't. Thanks for the feedback. MickeyBob

  12. I need to do a rather long mathmatical calculation. Is there an instruction that allows multiple mathmatical operations to be done in a single shot? Or do you have to do each operation separately, storing intermediate results in working registers? Tx, MickeyBob

  13. I've tried to use the *F(456) instruction with floating-point values directly and with symbols to initialize a DM register but CX-Programmer won't accept either. I also tried it with +F(454) but get the same basic results. Attached is a screen shot of my rung. The first operand is a symbol, defined as a number and has literal value '0.0'. CX-Programmer generates an "ERROR: Operand 1 Invalid IEEE Floating Point format at rung 1(6, 1)" Any insights would be greatly appreciated. Tx, MickeyBob

  14. Tx guys. Those are just the ticket! The symbol works very well. It even eliminates the need to write the floating-point value to the DM register in my case. Tx for the quick responses. MickeyBob

  15. Since you guys are so disappointed, let me ask another question then.... I want to initialize a DM register with a floating-point number at powerup/restart. How do I put a floating-point literal into a DM register? Can't seem to use some version of the MOV instruction. I've thought about using the binary to floating point conversion instruction [i.e., FLT (452)]. More general question, how do you enter a floating-point literal as an operand? Tx, MickeyBob

  16. How do you compare two floating point numbers? I've tried all the versions of the symbol comparison instructions and none seem to work. Either there is another way to do it or I'm doing something wrong in my code. Tx, MickeyBob

  17. Sleepy, Thanks for gettting back to me. If I understand you correctly, the choice of D29000 was some what arbitrary after you took into consideration what other locations were allocated and/or mapped. Regarding #0801, I've looked thru the documentation I have (W394-E1-03, W393-E3-04, & W395-E1-02) and can't find any details on the significance of the control word except that 0 and 1 compute the sine and cosine of a value. Where in the documentation have you found the details for the APR control word? Thanks again, MickeyBob

  18. Jay, Thanks for the followup. I was originally using the peripheral port because I only had that cable available. Then the light bulb went off and I retrieved my standard serial cable. I also had to do a little juggling with gender-benders to get it hooked up. Once I successfully made the connection, my demo program easily found the COM parameters that worked. I've since been able to bump the baud rate to 115200 and it works fine. I've kept switch 5 off so that the PLC setup for the port would be active. I have a few different manuals that I've been digging into. Which is the appropriate one for finding the most relevant info re: port configuration for the CJ1M-CPU21? Tx, MickeyBob

  19. I was finally successful in getting the activex dll to talk to the CJ1M. I hooked a standard serial cable up to the RS-232C/Hostlink port. The communications parameters that worked were 9600, E, 7, 1. The documentation (i.e., CJ1 Programmable Controllers Operations Manual) is inconsistent with this. The following is copied verbatum from the manual: PortMon indicated that the dll generated an error whenever it attempted to configure the port with 2 stop bits. Also, according to the manual, when dip switch 4 is OFF, and dip switch 5 is ON, the CPU should auto-detect the communications parameters on the respective port. I tried setting switch 5 ON and could never get the activex dll to connect. I'll continue to play with the port settings to see if I can use a faster baud rate. Tx again, MickeyBob