OK, you decided that the Texmate Tiger can do what you need for your application and it looks like you will need to write an app, too. You got the Texmate Development System, the Macro Programming Tutorial, the Registers Supplement, the Code Sheet, the sample macros, the data sheets for your I/O modules, and maybe even some additional stuff (e.g. the Serial Communications Supplement or the Totalizing Supplement). If you print out all of that you end up with a big pile of paper.
But the question remains: How do I start - and how do I get it done quickly?
If you do have the time to work through the Tutorial this might not be that hard anymore - but unfortunately many of you don't. Instead you would rather find out whether your idea works without wasting too much time if it doesn't.
Well, we cannot make you an expert on writing apps in an instant but we will try to help you getting started - from a programmers point of view :-)
Write a CUSTOMER_ID_MACRO containing a single WRITE command that states the application name and the app version number:
CUSTOMER_ID_MACRO:
WRITE " Tank Fill 1.2 "
END
Especially for longer macros it is also useful to redefine register names according to the actual application. At least the USER_MEMORY registers should get a proper name.
REG &LEVEL = &CH3
BIT |PUMP_1 = |SP1
BIT |PUMP_2 = |SP2
BIT |MED_LEVEL = |SP5 // only used for logic control, no relay attached
BIT |HIGH_LEVEL = |SP6 // only used for logic control, no relay attached
BIT |EMERGENCY = |CAPTURE_PIN
REG &ALARM_VALUE = &USER_MEMORY_1
Write a RESET_MACRO and initialize all variables there. Keep it up to date as you go on extending the macro.
RESET_MACRO:
#output = 0
|pumps_activated = false
END
If your application relies on a certain meter setup use the MEM command to preset the according registers. USER_MEMORY registers should always be initialized with the MEM command.
MEM &DISPLAY_FORMAT_CH1 = 0004 // 3 decimals
MEM &DATA_SOURCE_SP5 = addr(&LEVEL)
MEM &DATA_SOURCE_SP6 = addr(&LEVEL)
MEM &DATA_SOURCE_ANALOG1 = addr(#output)
MEM &ALARM_VALUE = 10000
If you plan to run the meter in a different communication mode (Master, Modbus...) you should set it back to ASCII in the RESET_MACRO so you can get access to the meter again. You may do that only conditional, though:
RESET_MACRO:
IF |CAPTURE_PIN = on THEN
&CODE3 = 0000
ENDIF
END
This is typically pretty easy so this may be the first thing to add to the MAIN_MACRO:
MAIN_MACRO:
#output = &LEVEL * 1.2 + (&LEVEL ^ 2) * 3.8
END
Logic control is usually quite easy to translate into a programming language. So this should be simple, too, as long as you already figured out the logic :-)
MAIN_MACRO:
// for copying a bit/boolean value you can use the short form
|PUMP_2 = |HIGH_LEVEL
// but for additional settings you have to write it explicitly
if |MED_LEVEL = on then
|PUMP_1 = on
|pumps_activated = true
else
|PUMP_1 = off
endif
// show a message when pumps are off again
if |MED_LEVEL = off and |pumps_activated = true then
|pumps_activated = false
write " back to normal "
endif
END
Even though this is not that difficult the EDIT_MACRO usually takes up quite an amount of code if you want to do it properly. As the Tutorial and the sample macros should be sufficient to explain how it works I will only give a few additional hints :-)
When you write your own user interface you typically want to hide the complexity from the user. So it is a good idea to hide those functions you don't need. If you allow access to the built-in menus you have to take the trigger events (UP/DOWN/PROG+UP/PROG+DOWN) into account as well as the fact that you are currently in these menus (&EDIT_STATE).
MEM &VIEW_MODE_BLANKING = 0x0000 // turn off view mode completely
MEM &SETPOINT_BLANKING = 0x0060 // edit only SP5/6 with PROG+DOWN
MEM &CODE_BLANKING = 0x0000 // note: editing brightness cannot be turned off
...
MAIN_MACRO:
// standard operation, only UP is pressed
if &STATE = 0 and &EDIT_STATE = 0 and |UP_BUTTON = on and \
|PROG_BUTTON = off and |DOWN_BUTTON = off then
...
endif
END
If you have a 7-segment display the letters 'M' and 'W' take up the space for two digits. Also some characters are relatively hard to read especially while scrolling text. So in general the interface should be rather simple to remain understandable. For a complex interface or elaborate text messages a 15-segment or a LCD display is recommended.
To keep track of the different STATE values it is recommended to use CONST definitions that are more readable. Sometimes it is also convenient to use these as index for a text array with the corresponding messages.
DIM Msg[] = [ "", "Setup", "Zero", "Full" ]
CONST eNONE = 0
CONST eENTER_SETUP = 1
CONST eANALOG_ZERO = 2
CONST eANALOG_FULL_SCALE = 3
EDIT_MACRO:
select &STATE
...
case eANALOG_ZERO:
|NON_VOLATILE_WRITE = on
EXIT_EDIT &D2A_AOP1_ZERO
EDIT &D2A_AOP1_FULL_SCALE
&EDIT_MIN = &D2A_AOP1_ZERO + 1
&EDIT_MAX = 99999
&EDIT_DEF = 10000
&STATE = eANALOG_FULL_SCALE
...
endsel
write Msg[&STATE]
END
If you change setup registers within the macro you have to set the |NON_VOLATILE_WRITE flag to ON before writing the register. Otherwise the change will not be stored in non-volatile memory, i.e. will be lost on power off.
The Tiger 320 Series provides only a very basic way to implement a communication protocol with the PRINT command and the SERIAL_INPUT comparisons. This will be sufficient for directly manipulating other devices (like another Tiger) or sending data and is explained in the Tutorial.
However, for more sophisticated protocols (e.g. for sending emails using an ethernet module, or parsing incoming data from another device) we added more features in the Tiger 380 series which allow for limited string operations. But, though getting easier, implementing a custom protocol still remains a tricky exercise which should not be attempted without a good understanding of how Tiger apps work.