Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - garysdickinson

Pages: 1 ... 10 11 [12] 13 14 ... 34
166
Technical support / Re:Display issues
« on: February 19, 2017, 02:49:21 PM »
I think that i-TRiLOGI is trying to give you a hint.  Sort of like the old joke, "Death, is nature's way to telling you to slow down".

There are real world limits on how complex a line of ladder logic you can construct.  You have exceeded what the ladder logic editor can handle.  You are lucky that you have gotten a hint.  I'd suggest that you simplify your ladder logic and break up the logic into simpler bits.

In regards to the flashing in simulation/on-line monitoring...  The simulator is attempting to highlight the contacts that are active.  If your logic is changing rapidly the simulator will be very busy rewriting the screen.

I have run the PLC tools on many different computers and would not describe the behavior as a strobe effect on any of them.  Most of my computers were picked to support 3d CAD CAM programs and Photoshop so the graphics hardware may be a bit more powerful than that in your laptop.  I assume that you are using the most up-to-date drivers for your video hardware, the most up-to-date version of Java and the latest version of i-TRiLOGI.

Good Luck,

Gary D*ckinson

167
Technical support / Re:Creating a FIFO
« on: February 16, 2017, 05:09:27 PM »
Lorne, I can't debug your program because you did not send it to me.

In your sample code you "went wrong" by removing the call the "DequeueMsg" in the "EnqueueMsg" custom function.  The entire purpose of the call the DequeueMsg was to handle the case where the FIFO is full of messages and you need to enqueue another message.  In order to make room for the new message, the call to DequeueMsg removed the oldest message from the FIFO.  You MUST put the code back.  This code was critical to maintaining the 3 numberic variables that manage the
FIFO.  BUT this is not why the code is not working in your environment.

I can't tell you why the FIFO_Cnt value stored in DM[1702] is not changing without having your entire PLC program. But my guess is that the EnqueueMsg is not getting called.  I suggest that you add a breakpoint into the CF that you wrote to handle RELAY 146 and add a breakpoint in the EnqueueMsg and use on-line monitoring to look at the code running on real hardware.

I assume that you picked up the Init CF from my test code and added it to your code to ensure that the FIFO is properly initialized.

In regards to how do you "read the stored messages", you call the DequeueMsg CF and each call to this function will return the oldest message in B$ (you changed it to E$ in your version). Once all of the messages have been read, subsequent calls to DequeuMsg will return "" in B$.  The FIFO is now empty.

It is possible to write a non-destructive method to peak at the messages without removing them from the FIFO.

Best regards,

Gary D*ckinson







168
Technical support / Re:Creating a FIFO
« on: February 15, 2017, 12:33:56 PM »
Lorne - I've attached a PLC program to this message that demonstrates a simple FIFO mechanism for storing string messages in non-volatile memory.

I would suggest that you play with this program using the i-TRiLOGI simulator until you can understand how it works.

I use the #Define mechanism exhaustively to create readable names for variables.  So the first thing that you need to do is open one of the custom functions and open the #Define table.

#   #Define Name   Value
1   ENQ_Offset      DM[1]
2   DEQ_Offset      DM[2]
3   FIFO_Cnt         DM[3]
4   FIFO_Size         5
5   FIFO_StartAddr   1

You will note that use 3, 16-bit integer variables to manage the FIFO. ENQ_Offset is used when a message is added, enqueued, to determine where in non-volatile memory to write the data.
DEQ_Offset is used when a message is removed, dequeued, to determine where in non-volatile memory to retrieve the data.
FIFO_Cnt is the current number of message stored in the FIFO

The FIFO_Size define determines the FIFO size in the count of messages.  For my test code, it is 5.  Adjust as needed
FIFO_StartAddr is the starting address in non-volatile memory. For my test code the starting address is 1.  Adjust as needed.

There are 2 RELAYs that you can use in both ladder logic and in custom functions to determine the current FIFO status:
    [*]MsgFifoEmpty - set when FIFO is empty and holds no messages
    [*]MsgFifoFull - set when the FIFO is full and if a new message is equeued then the oldest message in the FIFO will be lost
    [/list]
    This is the entire custom function to enqueue a string in the FIFO:
    Code: [Select]
    ' EnqueueMsg - function to enqueue an array of 40 character messages into the Message FIFO
    '
    '
    ' On entry A$ holds the string to enqueue
    '  This FIFO uses the SAVE_EEP$ statement to store data in the non-volatile memory.
    '  The message length is limited to 40 characters
    '
    '  On exit: The A$ will be written to the FIFO  
    '         The FIFO_FULL and FIFO_EMPTY RELAYS may be affected.
    '         The DM[] variables ENQ_Offset, DEQ_Offset and FIFO_CNT may be updated.
    '         If the FIFO is full then the B$ variable will be written with
    '             the oldest message in the FIFO to make room for the new message


    '  If the FIFO is FULL, then discard oldest message in the FIFO
    '
    IF TestIO(MsgFifoFull)
       ' the FIFO is full, but Lorne is OK with overwriting old messages
       '  so we will discard the oldest to make room for the newest message.
       '  This action overwrite the value of B$
       '
       Call DequeueMsg
    ENDIF

    SAVE_EEP$ A$,FIFO_StartAddr + ENQ_Offset   ' write one entry into the FIFO      

    ' Update FIFO index, counter and flags
    '
    ENQ_Offset = (ENQ_Offset + 1) MOD FIFO_Size
    FIFO_Cnt = FIFO_Cnt + 1

    IF FIFO_Cnt = FIFO_Size
       SetIO MsgFifoFull         ' the FIFO is full and cannot accept more data
    ENDIF

    ClrIO MsgFifoEmpty            ' FIFO cannot be empty

    This is the entire custom function to enqueue a string in the FIFO:
    Code: [Select]
    ' DequeueMsg - function to dequeue String data from the String FIFO
    '
    '  On exit:
    '          B$ will hold the oldest string in the FIFO.
    '         The FIFO_FULL and FIFO_EMPTY RELAYS may be affected.
    '         The DM[] variables ENQ_Offset, DEQ_Offset and FIFO_CNT may be updated.


    '  Return message from FIFO in B$
    '
    IF TestIO(MsgFifoEmpty)
       ' the FIFO is empty and there were no values to remove from the FIFO
       ' Just return a NULL String
       '
       B$ = ""
    ELSE
       ' the FIFO was not empty, so return oldest message in B$]
       '
       B$ = LOAD_EEP$(FIFO_StartAddr + DEQ_Offset)

       ' Update index, FIFO count and flags
       '
       DEQ_Offset = (DEQ_Offset + 1) MOD FIFO_Size
       FIFO_Cnt = FIFO_Cnt - 1

       IF FIFO_Cnt = 0
          SetIO MsgFifoEmpty   ' the FIFO is empty and there is no more data to remove
       ENDIF

       ClrIO MsgFifoFull         ' FIFO cannot be full

    ENDIF

    This approach may seem like lot of work, but it actually takes very few lines of code and executes very rapidly.  This is classic computer science done without the help of modern computer languages.

    Best regards,

    Gary D*ckinson

    169
    Technical support / Re:Creating a FIFO
    « on: February 15, 2017, 08:12:47 AM »
    Lorne,

    I have a test code for a FIFO that handles string data using the non-volatile memory and the LOAD_EEP$ and SAVE_EEP$ mechanism. The code dates back to 2012 and I was using it for a Nano-10 / GSM MODEM project.

    However, this test code is solving a much more complex problem than you have and I would like to simplify the code down to what you need. So give me a day or so to edit out all of the useless stuff.

    Gary D.

    170
    Technical support / Re:Number being forced into DM[1036]
    « on: February 14, 2017, 04:35:10 PM »
    9080 sounds like the port number used in the IP address of the PLC.  This may be from some experiment that you are using with the GET_IPAddr statement that will build an array in DM that represents the IP address including the port number of 9080 in 5 ascending DM[] registers.

    Gary D*ckinson

    171
    Technical support / Re:Creating a FIFO
    « on: February 14, 2017, 04:25:17 PM »
    Lorne,

    I need to ask some questions about your usage of a FIFO. I assume that you are aware that a FIFO is some sort of data structure used to store and retrieve strings on a "First In, First Out" basis.
     
    I understand that you want to store a string whenever RELAY 46 goes active.  This would be the "First In" part of the system.

    Questions:
    • Under what conditions do you want to remove the string data from your FIFO?  I am asking about the "First Out" part of the system.
    • How many messages do you need to store in your FIFO?  The Fx2424 has several ways to store string data:
      • A$..Z$  Only 26 strings, but 70-charaters in length.
      • non-volatile memory using LOAD_EEP$/SAVE_EEP$.  You can have up to 300 40-character strings on the Fx2424.
      • extended file system that can store well over 1,000,000 bytes of string data. Strings length can be variable.
      • DM[] memory if you want to pack and unpack the strings.
      • non-volatile memory using LOAD_EEP/SAVE_EEP  if you want to pack and unpack the strings.
    • How many characters long is the longest string that you need to store?
    • How many different strings will you store? Is each string unique?
    I'll make no attempt to answer the questions posed about the program snippet that you supplied as it is the slowest possible way to build a FIFO in TBASIC and it does not handle text strings.  If you can answer my questions, I can show you code that will actually do what you need.

    Best regards,

    Gary D*ckinson

    172
    Technical support / Re:FMD88 D/A#3 and D/A#4
    « on: February 13, 2017, 08:36:59 AM »
    Excellent on 10/12 bit behavior on older PLCS.  

    I used an external 16-bit  ADC on my T100MD projects after testing the PLC's DAC cabibilities and determining that 10-bits was not quite enough. I'd forgotten that fact.

    The analog ground and 5V reference wiring has a high probablity of giving you odd ADC values.

    Good hunting,

    Gary D


    173
    Technical support / Re:FMD88 D/A#3 and D/A#4
    « on: February 11, 2017, 05:13:57 PM »
    Please be aware that the ADC on the FMD/Fx/Nano PLCs is a 12-bit ADC.  The older T100MD had a 10-bit ADC.

    If your ADC readings with the FMD are about 4x too high, the then differences in the ADC circuitry are the root cause. You will need to modify the CF that read the ADCs to accommodate the extra 2 bits of resolution.  You could just divide the new readings by 4 and then just use the old code from that point forward.

    As I am sure you have noticed, the DB15 connector is wired a bit differently between the generations of PLCs.  If your analog circuitry is dependent on ground reference or 5V ADC reference voltages you have a good chance of being wrong with your old cable.  There is a only one pin for each signal on the FMD vs. 3 pins for each on the T100MD88.

    TRI has a PDF on differences between the old T100MD and the FMD boards here:

    http://www.triplc.com/documents/FMD1616-10_Upgrade_Notes.pdf

    The other differences have to do with the amount of DM memory and non volatile memory.  There is less of each on the newer FMD boards. If this poses a problem, the add-on RTC-FRAM module is what I use to get back these resources.

    Best regards,

    Gary D*ckinson

    174
    Thanks.  I like algorithm questions.

    I was surprised that my sample code for jbryant87 resulted in unintentional Unicode characters.  So I offered him a second version that forced the argument, n, in CHR$(n) to be in the range of 0..255 (8-bit).  This fixed his problem but bothered me as to why I needed to do this.

    I came up with 2 competing theories:
    • You guys had secretly added UTF-8 support to TBASIC.  Modified CHR$(n) to accept 16-bit arguments and convert them to multiple UTF-8 bytes.  Modified ASC(A$,i) and MID$ to recognize UTF-8 encoded characters and reconstruct the 16-bit values.  And, were too modest to mention all of these improvements.
    • The simulator was handling strings differently then real hardware.
    I was getting so excited about the first theory and ignored the fact that the 2nd theory was much more plausible.

    Gary D.

    175
    The simulator's handling of CHR$(n) does not match the PLC's behavior.

    The simulator accepts 16-bit values for n and can create strings that appear to be an array of 16-bit values.

    As an example:

    A$ = CHR$(&H4548)

    Creates a string that is 1 character in length and this only character has a value of &H4548 when run with the simulator.

    When run on a PLC this same code creates a string that is 1 character in length and this character has a value of &H48.

    I vote that the PLC's handling is correct.

    I suspect that the Java library that you are using supports Unicode in some general way (localization) and that the java code that is close to CHR$() will accept 16-bit Unicode values.

    I think that you should mask off and only use the least significant 8 bits of the "n" argument to CHR$(n).  This would make the simulator behavior match the PLC.

    I don't care that the simulator implements strings as arrays of 16-bit integers rather than 8-bit integers as the PLC does.  This difference is not important and only shows up because of the implementation of CHR$(n) is flawed.

    Gary D*ckinson

    176
    Technical support / Re:DM TO ASCII
    « on: February 05, 2017, 01:39:08 PM »
    Thanks.

    I like algorithms.  Glad I could help

    Gary D*ckinson

    177
    Technical support / Re:DM TO ASCII
    « on: February 04, 2017, 02:44:47 PM »
    I'm sorry, I am away from my computer.  I think the issue is with the chr$ function.  In my sample code it looked at all 16 bits of dm[116] and treated it as a Unicode character rather than looking at the lower 8 bits of dm[116].  This got you the chinese charater.  The chr$ then correctly isolated the most significant byte of dm[116] and converted it to an "E".  "E" is absolutely correct for the value of in dm[116].

    Code: [Select]
    a$ = ""
    for i = 116 to 125
        a = dm[i] & &hff          ' isolate lsb  in a
        If a = 0
            Exit
        Endif
        a$ = a$ + chr$(a)
        a = (dm[i] / 256) & &hff   ' isolate msb in a
        if a = 0
            exit   ' end of string encountered
        endif
        a$ = a$ + chr$(a)
    next

    Sorry for not remembering that chr$ handles Unicode.  Remember that the "A" in ASCII is for "American" and I am still working with 7-bit ASCII.  I just used your example, "A$=CHR$(DM[116])" and made the assumption that this code would actually return only the lower 8-bits of the value in DM[116] and assign it to the string, A$.  Sorry for assuming.

    The values you provided should build a string of "HELLO".  Be aware that your sample is not a 20 character string because the msb of DM[118] is 0x00 this is a non-printable ASCII character and perhaps you should use this value as an hint that you have reached the end of string.

    Gary D*ckinson

    178
    Technical support / Re:DM TO ASCII
    « on: February 04, 2017, 12:37:49 PM »
    You could try something like this to build a string from packed 16 bit data in DM[]:

    Code: [Select]
    a$ = ""
    for i = 116 to 125
        a = dm[i]
        a$ = a$ + chr$(a)       ' least significant byte
        a = (a / 256) & &hff    ' shift right 8 bits
        a$ = a$ + chr$(a)       ' most significant byte
    next

    On your Modbus question.  No.  Modbus does not have a defined  mechanism to transfer strings. The String variables are not accessible by Modbus.  So packing/unpacking strings into DM and transfering the data as multiple 16 bit registers is what you must do.

    Gary D*ckinson

    179
    Technical support / Re:FP403MR with FX2424
    « on: January 27, 2017, 05:44:46 PM »
    Lorne,

    I am a certified old guy.  I retired 17 years ago.

    The fP4030mr is a real product made by an Indian company named Renu Electronics.  Other than getting a custom driver software written for the FP4030 to work with the PLC's native protocol, I don't suspect that TRI has done anything to the HMI.

    I have not used the fp4030.  Other than the problems with getting it working, how do you like it?  The price excellent.  

    My first TRI product used a 4x20 LCD and a bunch of switches that TRI sells.  All of the code was written on the PLC side and the effort to write the user interface in ladder logic and custom functions was about 10x more than the actual code that ran the clients system.  I still use the 4x20 LCDs with the PLCs mostly for debug and status, but not as an end user interface.

    I have used the 4.3 and 7" Weintek HMI's with the PLCs and have found that the combination is amazingly powerful.  If you get the models that support Ethernet, you can remotely run the HMI from anywhere in the world. They, also, support data logging to a USB stick.

    The Wientek programming seems real simple, just drag stuff onto a screen and poof you have a user interface!  As soon as you need something else, the Wientek gets real complicated and it has been a long learning curve.

    Best regards,

    Gary D*ckinson


    180
    Technical support / Re:FP403MR with FX2424
    « on: January 27, 2017, 11:07:26 AM »
    Lorne,

    Welcome to the wild world on PLCs!  

    Zero is a pretty new idea.  It dates back to about 773 AD. Until then if you had nothing to sell you didn't need to count it.  If you had stuff to sell you could inventory it by counting 1,2,3...

    Old computer languages like BASIC and FORTRAN considered 1 as the index of the first item in an array.  Most modern computer languages think that 0 is the index of the first item (or you can specify the starting index). Starting with 0 simplifies the math for the computer but would confuse people born before 773 AD.

    TRI's PLCs tend to use 1 or +1 for lots of stuff.  There isn't a right or wrong to this, it just is what it is.  At least they are consistent.

    I consider the MP4030 to be the "odd man" in this combo.  Their use of 8-bit byes versus 16-bit words for data transfer is very uncommon in PLC/industrial control circles.  It's been a long time since I have run into this sort of behavior.

    It would have been nice if TRI had written more useful documentation for the MP4030 and the use of TRI native host communication protocol, but they didn't.

    Good luck,

    Gary D*ckinson



    Pages: 1 ... 10 11 [12] 13 14 ... 34