FWIW, hereâs how youâd do this in Open AT Lua. The main program, in Lua, would look like (untested code):
------------------------------------------------------------
-- Configuration settings. These can be changed on-the-fly.
------------------------------------------------------------
SERVER_IP = '192.168.192.2' -- Server where data is sent
SERVER_PORT = 1234 -- Listening port on the server
DATA_MAX_NUMBER = 10 -- Number of entries to read before sending
DATA_READ_INTERVAL = 6000 -- Time between two readings (1/10th seconds)
DATA_TABLE = { } -- Intermediate storage for data.
------------------------------------------------------------
-- Initialize the data gathering request, wait for data to
-- actually arrive, return the result.
------------------------------------------------------------
function read_data ()
request_data_from_C()
local _, event, data = wait('DATALOGGER', 'ARRIVED')
return data
end
------------------------------------------------------------
-- Send all the data gathered in DATA_TABLE to the server
-- through TCP/IP.
------------------------------------------------------------
function send_all_data ()
local socket = wip.tcp_client (SERVER_IP, SERVER_PORT)
for i = 1, # DATA_TABLE do
socket:write (DATA_TABLE [i])
socket:write ("\n")
end
socket:close()
end
------------------------------------------------------------
-- Every time it's called, read one data line and add it to
-- DATA_TABLE. If the table is full, flush it through the
-- TCP/IP network.
------------------------------------------------------------
function add_data_to_table ()
table.insert(DATA_TABLE, read_data())
if # DATA_TABLE > DATA_MAX_NUMBER then
send_all_data()
DATA_TABLE = { }
end
end
------------------------------------------------------------
-- Call add_data_to_table() at regular intervals
------------------------------------------------------------
function data_loop ()
while true do
wait (DATA_READ_INTERVAL)
add_data_to_table()
end
end
It relies on a couple of C functions, that will do your data acquisition. request_data_from_C() will start the data gathering process. When itâs finished, you signal that itâs completed by sending the signal âDATALOGGERâ.âARRIVEDâ to Lua (read_data() was waiting for this signal, thus simulating a blocking call from Luaâs PoV). The signal emission is done by the C function data_arrived() below.
/* Start the data collection */
static int request_data_from_C( lua_State *L) {
/* Initialize the data gathering routine. */
...
return 0; /* Return 0 results to Lua */
}
/* When data is ready, run this C callback */
static void data_arrived( char *data_line, int data_len) {
/* push data as an extra arg to the Lua event */
lua_pushlstring( L, data, data_len );
/* Trigger th event */
luaW_signal_str( L, "DATALOGGER", "ARRIVED", 1);
}
/* Register the 'request_data_from_C' function in Lua.
* Add this entry in the config table of your application's main source file. */
luaopen_datalogger( lua_State *L) {
lua_pushcfunction( L, request_data_from_C);
lua_setglobal( L, "request_data_from_C");
return 0;
}
The C code is always non-blocking, but it appears as blocking in Lua (read_data()), thus easing the application writing. Similarly, all TCP/IP code is blocking, no need to synchronize on WIP_CEV_XXX events nor to write a state automaton.
In the next version of WIP + Open AT Lua, there will be a full UART driving API from Lua, so chances are that you wonât need to write a single line of C for such an application.
This program will probably require some improvements before going to prod:
- Data should be stored in a flash table, so that they wonât be lost in case of a reset (thereâs a Lua API for this)
- You should decide what to do when TCP/IP is unreachable (error handling is done with function try() and dedicated bearer / socket events)
- Maybe you want to switch the GPRS off and on when appropriate (wip.bearer_client(âGPRSâ, gprs_config))
- You might want to be able to setup some emergency recovery procedures, e.g. change the server address and GPRS settings from an SMS (there are âSMSâ events for that).