Author Topic: Editing/Changing HMI, a large number  (Read 12298 times)

cdenk

  • Full Member
  • Posts: 161
  • newbie
    • View Profile
Editing/Changing HMI, a large number
« on: July 03, 2010, 12:10:46 PM »
This is with a T100MD + MD-HMI420

I would like to display a large number, maximum 999,999 on the display and am looking for a nice way to handle changing that number with the key pad. Since the DM[]'s only count to 65,xxx I need to break the number up to to DM[]'s

I have previously handled time and date by using a counter to keep track of which item is being edited. Then I use the KEY_1 to increment that counter. KEY_2 decrements the item, KEY_3 increments the item, and "Enter" saves the items. Some of these items are not real time, but date/time for an action, and are stored as DM[]'s. This works well.

For the large number, I plan to use 2 DM[]'s, one for the LSB 4 digits (thousands and less), and the other DM[] for 10 and 100 thousands. When the LSB one gets to 9,999, it would rollover to 0, and increment the other one.

For the changing or editing part:
1: Load all the pairs of digits into 3 counters , one for 10's and units, one for 100's and 1000's, and one for the 10,000's and 100,000's
2: A 4th counter (I have plenty unused available) would keep track of which counter is being changed. On the HMI, the edited digits would flash.
The actual editing routine uses subscripts, so you don't have lots of code, and handles under/overflow by incrementing the appropriate DM[] digit.
3: The 3 digit counters get loaded back into the 2 DM[]'s when "Enter" is pressed.

Looking for suggestions on an easier way. At this moment, just these thoughts are all that has been done. :)

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Editing/Changing HMI, a large number
« Reply #1 on: July 03, 2010, 11:51:37 PM »
cdenk,

I have taken two approaches to data entry using the same setup (T100MD+ and HMI 420):
  • I prototyped up a version using a rotary encoder that directly incremented/decremented a COUNTER.  This is equivalent to what you are describing (substitute and UP DOWN switch for a rotary switch).  This worked pretty well for numeric values with a small range  (0..23 hours).  It was a pain for bigger ranges (0..999) required spinning the knob for a couple minutes.  So I went on to the next option...
  • I'm have a running system based on the HMI 420 numeric keypad.  The user enters the target data one digit at a time.  The RED ARROW key is used to delete the most recent digit.  The GREEN ARROW key is used as "ENTER".
Unfortunately, the second approach is not "dead-bang" simple.  

The basic idea is that user is "secretly" editing an ASCII string.  The LCD is updated after each input.  New entrys appear on the RIGHT of the display field and old numbers slide to the LEFT (this is equivalent to the dispaly on a cheap calculator).

The use of an ASCII string made the TBASIC code simple and the ASCII string made updating the HMI LCD easy.
 
When the user presses the "ENTER" button, then I convert the string back to a numeric value(s) and check for validity.  If the value is useless, I abuse the user and put the value(s) back to either what it was before he tried to change it or some other safe default.

The actual code is pretty straight forward BASIC, but the problem is to make all of this happen without hanging the PLC up in custom functions waiting for the user to get done composing a new entry.

The complications come with keeping track of what to do with each user key press.  I use a COUNTER to build a state machine that manages the the user interface and a bunch of RELAYS to track the current input field type. Some of my inputs are in "hh:mm" format for time values, other inputs are in "xxx.x" format for temperatures, "xx.x" for pH values ans some as "xxx" for loop or repeat counts.  The use of these RELAYS allows me to reuse the custom functions for similar inputs. The reuse of code saves a lot of program space and a mountain of debug.

Let me know if you are interested in this approach. I can pull the code out of one of my projects to make something that you can run in the TRiLog simulator or real hardware...

Gary D.


support

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3174
    • View Profile
    • Internet Programmable PLCs
Re:Editing/Changing HMI, a large number
« Reply #2 on: July 04, 2010, 12:13:05 AM »
As per Gary's suggestion, using the keypad inputs on the MD-HMI to enter a value would be the most straightforward way to enter a large number.

You can avoid entering a long wait loop for user to complete his entry by using ladder program to scan the keys and only take actions when a key is pressed. An example program can be found on your "TRiLOGI\TL6\usr\samples\HMI\HMI17TO32.PC6". You can simulate the program and press any key on the keypad to create a string that represent the input number. You can take as long as you like to enter that number and the CPU will continue to run other parts of the program without being held up in a long loop.
« Last Edit: July 04, 2010, 12:30:20 AM by support »
Email: support@triplc.com
Tel: 1-877-TRI-PLCS

cdenk

  • Full Member
  • Posts: 161
  • newbie
    • View Profile
Re:Editing/Changing HMI, a large number
« Reply #3 on: July 04, 2010, 07:09:00 AM »
I seem to like Support's approach to changing the changing to a string, and editing the string. Going to try using counters as indexes (I have 2 of those long numbers to handle) to the individual digits of each number, I should be able to change the discrete digits of the strings, and then change it back to the numbers for other programing to handle the switch closure incrementing. MID$ can be used to select the digit from the string.

Another approach would be to use support's approach, but use all numbers and don't get into strings. Has the advantage that you are changing the real number. But I thing you would have to break the number into individual DM[]'s for each digit and then load back to the operational number. As I'm writing, is getting to sound more difficult. :~)

Guess the next step is to start laying out storage locations, and try to implement some indexing scheme.

Thanks again for the replies.

Gary on your rotary encoder: Try operating on 2 digits as a time. How many steps per revolution? I'm guessing around 25, if so that would be a maximum of 2 turns to get to the nearest far  :~) number.  Kind of like that idea. I would physically be able to mount an encoder by the HMI. :)

garysdickinson

  • Hero Member
  • Posts: 502
  • Old PLC Coder
    • View Profile
Re:Editing/Changing HMI, a large number
« Reply #4 on: July 04, 2010, 03:08:13 PM »
cdenk,

On the rotary encoder, it had 32 steps per rev.  2 digit numbers took a little over 6 spins.  The encoder is not a perfect match for the T100MD+ as these PLCs don't support the decode mode required to get all 32 steps.  Ladder logic was not fast enough to track the transitions when the encoder was moved rapidly.  I used interrupt routines to interface to the encoder.

On the HMI keypad input I took an approach where the parameter to be edited was converted to a string, edited as a string and converted only back to a number for storage/use.

As an example for a time of day field:
  • This field was stored in DM[_x] as a scaled integer.  8:31 was stored as 831 ( multiply the hours by 100 and then add in the minutes).
  • To edit this field, I convert the scaled integer back into a text string using the STR$(DM[_x],4) function.  The resulting sting was " 831".  Note the leading space, the length of the string must always be constant at 4 for my time fields.
  • The custom function that updates the LCD display inserts a ":" as it write to the display.  The ":" never appears in the string.
  • If the user enters a digit, 0..9, the old string is shifted to the left and the new digit is appended onto the right end of the string.  If the string started as "0831" and the user presses the "9" key the string will become "8319".
  • The delete key causes the number to be shifted to the right.  If the string is now "8319", pressing the delete key gets you "0831"
  • Pressing the ENTER key, gets the field validated and converted back into a integer for storage in DM[_x].

The approach seems convoluted, but its works well with TBASIC and I used the same editing function for all of my input fields.

This is the input handler shared by all of the numeric fields:

' Edits X$
'
' X$ is updated, X is set to 1 to indicate that input is complete
'
DM[3900] = INPUT[3]  ' Get data from input #33-48

IF TESTBIT(DM[3900],10)
  ' <Del> key has been pressed
  '
  X$ = "0"+MID$(X$,1,LEN(X$)-1)
  X = 0 ' More Input to come
  RETURN
ENDIF

IF TESTBIT(DM[3900],11)
  ' <Enter> key has been pressed. Input is complete
  '
  X = 1 ' Done with input
  RETURN
ENDIF

' OK it must be a Number key that was pressed
' Figure out which one it was...
'
FOR Z = 0 to 10
  IF TESTBIT(DM[3900],Z)
    X$ = MID$(X$,2,LEN(X$)-1)+STR$(Z)
    X = 0 ' More Input to come
    RETURN
  ENDIF
NEXT


Good luck,

Gary D