de:doc:lua:start
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
de:doc:lua:start [2013/10/27 17:38] – wsauer | de:doc:lua:start [2014/03/29 01:00] (current) – removed admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Erstelle Deine eigenen OOBD Scripts ====== | ||
- | |||
- | The " | ||
- | |||
- | |||
- | ===== What is Lua? ===== | ||
- | |||
- | Simply said, [[http:// | ||
- | |||
- | |||
- | This allows to make a program now but change its behavior later as needed. This is widely used in the OOBD script engine: The script engine is there from the beginning, but what it does is defined by the script which is loaded at runtime. Another script, another functionality.. | ||
- | |||
- | |||
- | Luckely Lua became quite popular in the last years, so it's available for all major platforms, like Desktop PCs, Smartphone and Mobile Phones. | ||
- | |||
- | |||
- | There are tons of documentation about Lua available in the internet, so we'll not explain the wheel here once more, we'll just focus on how Lua works inside OOBD. | ||
- | |||
- | |||
- | ===== The Lua - OOBD Interface ===== | ||
- | |||
- | If Lua runs inside another program, without further assistance it does it like in a black box: No connection from the inside to the outside, no inputs, no feedbacks. This is obviously not very senseful, so when Lua is implemented into another program, there are normally some interfaces made up to let Lua and its host communicate to each other. | ||
- | |||
- | |||
- | From the Lua perspective, | ||
- | |||
- | In the moment the OOBD interface supports two kinds of interfaces for Lua: Some for creating the menus, and some to talk to the serial line (( this is certainly subject to change in the future, when OOBD becomes more generic and the data links become more abstract)) | ||
- | |||
- | |||
- | **Important** To allow it during debugging to replace the hardcoded extended Lua functions against some own debugging code, normally the hardcoded functions are assigned to some Lua variables first, which then are used in the later script: | ||
- | |||
- | local serFlush =serFlushCall | ||
- | serflush() | ||
- | | ||
- | | ||
- | So by naming convention the hardcoded extended functions ends with xxx" | ||
- | |||
- | Please keep this in mind while reading this document or writing own code. | ||
- | |||
- | |||
- | But before we look in detail in the program flow itself, we need to understand how the lua compiler (luac) works and what that means for the program initialization: | ||
- | |||
- | ==== Compiling and Startup code ==== | ||
- | |||
- | To save memory and reduce the startup time, the Lua interpreter inside OOBD is not feed with the Lua programm source code text directly as this would need to be compiled first to be executed, which is time & memory consuming. Instead the compiling is done beforehand and just the compiled Lua program code is than used to be loaded into OOBD. | ||
- | |||
- | The compile process works like that, that the Lua compiler (a command line program called luac) translates the source code(s) (with the extension .lua) into a single file (with the extension .lbc) which contains the compiled program. | ||
- | |||
- | The command would be like this: | ||
- | |||
- | luac -o outputfile.lbc inputsource1.lua inputsource2.lua ... | ||
- | | ||
- | | ||
- | In the OOBD source code repository there are some samples about how to do this. | ||
- | |||
- | |||
- | If you want to set up your own compile process, there are two things you need to know, as luac works partly different as normal compilers | ||
- | |||
- | - luac does **not** evaluate any require() or doFile() statements, so these files would be missed in the output file. All needed files must be listed instead as input files to be contained in the output | ||
- | - also the sequence of the input files is important: Luac glues the files together in the same sequence as their are given; and in the same sequence the file is executed later. \\ Here you have to take care that variables and functions are been declared before they are used first time, otherways you'll get a " | ||
- | |||
- | Because of item 2, the lua function, which sets up the whole lua structures, should be the last and only command in the lasr file given to luac. | ||
- | |||
- | === The Start("","" | ||
- | |||
- | To give the OOBD application the possibility to reinitialize the system (like after an communication loss), the name of such a initialization function is defined: **Start("","" | ||
- | | ||
- | | ||
- | ==== The Menu commands ==== | ||
- | OOBD uses just tree functions to set up the menu structures. Let's have a look into some sample code first: | ||
- | |||
- | <code lua> | ||
- | function Start(oldvalue, | ||
- | identifyOOBDInterface() | ||
- | setSendID(" | ||
- | openPage(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | addElement(" | ||
- | pageDone() | ||
- | return oldvalue | ||
- | end | ||
- | |||
- | |||
- | ----------------- Do the initial settings -------------- | ||
- | |||
- | Start("","" | ||
- | return | ||
- | </ | ||
- | |||
- | |||
- | (BTW: Here you also see the start() function in action) | ||
- | |||
- | So what do we found here? First we have the | ||
- | === openPage(" | ||
- | |||
- | This function tells OOBD that a new menu should be made. The //title// is used, what a surprise, as title for that new menu. | ||
- | |||
- | Then the menu is filled with | ||
- | |||
- | === addElement(Description, | ||
- | |||
- | This call adds a single element to the list. For now these function has the following parameters | ||
- | |||
- | * Description(String): | ||
- | * function: Each menu is assigned to a Lua function, where one function can be shared between several menu items. The name of this function is given here (please take care about correct upper/lower characters) | ||
- | * initialValue(String): | ||
- | * Flagset(Integer): | ||
- | * id(String): The id is used to add an individual marker to a menu item. This is widely used when one single Lua function should support many menu items. This is descripted in detail in the [[# | ||
- | |||
- | === pageDone() === | ||
- | |||
- | The pageDone() function is easy, it just tells OOBD that the menu is defined now and ready to be shown. | ||
- | |||
- | The final result looks than similar like this (you' | ||
- | |||
- | {{: | ||
- | |||
- | |||
- | ==== The Menu Function Call ==== | ||
- | |||
- | As shown above, we've now set up the menu items - but now we want something happen when the user selects a menu item, won't we? | ||
- | |||
- | |||
- | So let's assume the user selects an item. What happens now? | ||
- | - OOBD looks, which Lua function is assigned to that menu item | ||
- | - than that Lua function is called, with two parameters: | ||
- | * the actual displayed value of that item | ||
- | * and the id with we gave to that menu item during initialization | ||
- | - than the called Lua function does something, e.g. a calculation or it starts to generate another submenu | ||
- | - when the function is finished, it returns a string value | ||
- | - that string value is then displayed as new value of the menu item | ||
- | |||
- | That's already all, that does the job :-) | ||
- | |||
- | |||
- | ==== The Communication | ||
- | |||
- | OOBD uses (actual) serial communication to talk to the diagnostic device. To allow Lua to send and receive data from the serial port, a few extended Lua functions exists: | ||
- | |||
- | === serFlush() === | ||
- | |||
- | It just clears the input buffer (from anything which was maybe received in the meantime and which is not needed anymore) | ||
- | |||
- | |||
- | === serWrite(String) === | ||
- | |||
- | Sends //String// to the output (which is normally the serial port) | ||
- | |||
- | |||
- | === serSleep(milliseconds) === | ||
- | |||
- | waits // | ||
- | |||
- | === serReadLn(msTimeout) === | ||
- | |||
- | reads from input until a LF (dez. 10 hex 0x0A) appears and returns that input as String | ||
- | |||
- | === serWait(OptionString, | ||
- | |||
- | In case you want to wait for some input strings, of which several could appear, you fill the // | ||
- | |||
- | |||
- | ==== Miscellaneous | ||
- | |||
- | === serDisplayWrite(String) === | ||
- | |||
- | |||
- | Writes //String// to the build in output console. | ||
- | |||
- | === dbLookup(db-File , searchstring) === | ||
- | |||
- | Searches in the //db-file// for all entries with index // | ||
- | |||
- | dbLookup() returns a Lua table | ||
- | | ||
- | myTable = dbLookup(" | ||
- | |||
- | // | ||
- | * if // | ||
- | * if // | ||
- | * if // | ||
- | |||
- | When something has been found, than //myTable// contains two sections, //header// and //data//. | ||
- | |||
- | The header section is needed in case you don't know in which column your wanted result is stored; you can identify the column by its column header name instead: | ||
- | |||
- | col= myTable.header[" | ||
- | print (col) | ||
- | 2 | ||
- | |||
- | // | ||
- | |||
- | |||
- | The //data// section then contains the found data itself, arranged as a two dimensional array, sorted by rows and columns. | ||
- | |||
- | result=myTable.data[row][column] | ||
- | | ||
- | **ATTENTION**: | ||
- | |||
- | column=3 | ||
- | row=2 | ||
- | result=myTable.data[tostring(row)][tostring(column)]) | ||
- | | ||
- | | ||
- | Here after all a piece of sample code | ||
- | |||
- | <code lua> | ||
- | myTable= dbLookupCall(" | ||
- | |||
- | print (" | ||
- | for k,v in pairs (myTable.header) do | ||
- | print (k," | ||
- | end | ||
- | |||
- | nrOfColumns = myTable.header.size | ||
- | nrOfRows = myTable.len | ||
- | |||
- | print ("Rows x Columns:" | ||
- | |||
- | |||
- | for row = 1 , nrOfRows , 1 do | ||
- | for column = 1 , nrOfColumns, | ||
- | | ||
- | print (cy, cx, myTable.data[tostring(row)][tostring(column)]) | ||
- | end | ||
- | end | ||
- | </ | ||
- | |||
- | ===== Some Programming Tricks ===== | ||
- | |||
- | Coming from old fashioned programming languages, you might be used to simple and static variable types like numbers and Strings. But Lua offers much more comfort here, especially with the support of nested (associative) Arrays. With that some things can be realized quite easy. | ||
- | |||
- | Let's assume a common scenario: You want to use a number of menu items, which basically do all the same (getting a value from a vehice) just with different parameters. | ||
- | |||
- | In former days you had to write one function for each single value and a long list of menu items, but in Lua, you can store all parameters, their meanings and even the function reference to get them in a single array like | ||
- | |||
- | < | ||
- | local Menu2Data = { | ||
- | id0x0815 = { byte = 1 , size = 1 , mult = 0.392156862745 , offset = 0, unit = " | ||
- | id0x4711 = { byte = 1 , size = 1 , mult = 0.392156862745 , offset = 0, unit = " | ||
- | -- ... here are all the other parameter settings | ||
- | |||
- | } | ||
- | </ | ||
- | |||
- | then, during your menu initialisation, | ||
- | |||
- | <code lua> | ||
- | openPage(" | ||
- | for key,value in pairs(Menu2Data) do | ||
- | res=_G[value.call](" | ||
- | addElement(value.title, | ||
- | end | ||
- | pageDone() | ||
- | |||
- | </ | ||
- | |||
- | And again: That's it | ||
- | |||
- | When than later on a function is called by its menu item, it gets the hash key of the Menu2Data array as its " | ||
- | |||
- | Please also note the use of the _G array in the sample above: Lua stores also all functions into its global _G array, where they can be refenced by their name and used as a normal function. So the '' | ||
- | - it finds a function by its name | ||
- | - then it calls these function as if the user would do it | ||
- | - it saves the actual return value (which represents e.g. the actual measuring data) in res | ||
- | - res is then be used as initial displayed value when setting up the menu | ||
- | |||
- | By that it's possible without big efforts to fill a menu with real data already during initialization, |
de/doc/lua/start.1382891923.txt.gz · Last modified: 2013/10/27 17:38 by wsauer