top of page

LUA API Guide

For FATBOX G3 (version 2.2)

 

LUA interpreter version: 5.1.5

Revision log:
V2.2
>add support for Zigbee (via usb port)
>add support for multi serial port (G3 extended ports version)
>add support for timeout in serial port & sms send/receive functions V2.1
>add support for CANbus (CAN2.0A & 2.0B)


V2.0
>add support for GPS (standalone mode, non-assist)
>add support for serial port handle hex/bin data
>add support for standard Modbus master (Modbus/RTU & Modbus/TCP)

>add support for special Modbus protocol using 32-bits registers

Intro to LUA

Introduction to LUA

LUA is a powerful scripting language used in many embedded devices worldwide.

Read up more on python at www.lua.org

 

The LUA script interpreter is embedded into the Linux/OpenWRT operating system of the FATBOX G3.

 

With LUA script running, user can execute customized functions to

  • -  Monitor digital input to create alarms/alerts.

  • -  Manage the sending & receiving of SMS messages.

  • -  Save events/data to a file in flash memory.

  • -  Handle Serial RS232/485 communications with serial devices.

  • -  Handle TCP/UDP communications with host or client.

First LUA Program

First LUA Program/ Importing to the FATBOX G3

1. Open a notepad.

2. Enter the following

 

require "G3"

green_tick_led=53

while true do:

switch_led(green_tick_led,1)

sleep(0.2)

switch_led(green_tick_led,0)

sleep(0.2)

end

3. Save the file as ‘user.lua’ to a USB drive with label ‘FATBOX’.

    Then create a folder ‘/user’ and put the file inside this folder.

    Confirm the file properties is type .lua and not .txt or .text.

4. Connect the USB drive to the FATBOX G3’s USB port.

5. Login via web browser using default ETH0 port IP 192.168.1.1

6. Click ‘Download to FATBOX’ under the LUA Script Management.

7. Click ‘Execute user.lua Script’ to run the script.

8. The blinking LED on the FATBOX G3 confirms the script running

Cellular Module Functions

Cellular Module Functions

Reboot G3 router

reboot()

soft reboot the G3 router

 

Example:
 

require "G3"
if read_IN() then

reboot()

end

Cellular status check

cellular_status()

returns 0 if not connected to cellular network

returns 1 if connected to cellular network

Example:


require "G3"

if cellular_status() then

print ("3G OK")

end

Check cellular signal strength

check_signal(timeout_sec)

returns 0 when there is no +CSQ signal received
returns +CSQ:[n] number between 0 and 31 indicating the signal strength level

Example:

require “G3”
while true do

csq=check_signal(10)      #timeout=10sec

print(csq)

ifcsq~=0 then

rssi=tonumber(string.match(csq, "%d+"))

print(rssi)

else rssi=0 end

sleep(1)

end

Cellular turn ON/OFF

cellular_off()
cellular_on()

switch on or off the cellular module.

 

Example:

 

require "G3"
if read_IN() then

cellular_on()

else:

cellular_off()

end

Pause LUA Program

 

sleep(x)

sleep for x seconds

 

Example:

 

require "G3"

sleep(0.5)

sleep(3)

 

Ping function

ping(host,interface)

returns 0 if ping failed
returns 1 if ping success
host=valid ip address or domain name eg “8.8.8.8” or “www.lua.org

interface=”eth0”,”eth1” or omitted for default route


Example

 

require "G3"
ping100=ping(“192.168.1.100”,”eth0”)

ping200=ping(“10.1.1.200”,”eth1”)

pingdnsserver=ping(“8.8.8.8”)

pingdomain=ping(“www.microsoft.com”)

I/O Functions

I/O Functions

Read position of DIP switch

read_dip(pos)

returns the DIP switch position for program selection/user feature activation.

Example:

require "G3"
if read_dip(2) then

print (“dip switch #2 read position down!”)

else:

print (“dip switch #2 read position up!”)

end

Read digital input

read_IN()

returns 0 when IN is open circuit.
returns 1 when IN is shorted to GND terminal.

 

Example:

require "G3"
if read_IN() then

print (“IN terminal shorted to GND!”)

else:

print (“IN terminal is open”)

end

Trigger LED output

switch_led(n,level)

switch on or off the on-board LEDs

Example:

require "G3"

while true do

switch_led(53,1)

sleep(0.2)

switch_led(53,0)

sleep(0.2)

end

Blink LED output

blink_led(n, time)

blinks the on-board LEDs for a specific time period

Example:

require "G3"

while true do

blink_led(53,0.2)

sleep(0.2)

blink_led(54,0.2)

sleep(0.2)

blink_led(51,0.2)

sleep(0.2)

blink_led(52,0.2)

end

SMS Functions

SMS Functions

Initialize cellular module for SMS text/pdu

init_modem(mode)

mode= “sms” or “pdu”

 

Example:

 

require "G3"

init_modem(“sms”)     #for sending SMS in text mode.

init_modem(“pdu”)      #for sending SMS in pdu mode.

 

 

Sending SMS as normal text

sms_send(number,message,timeout_sec)

number= mobile number in international format
message= standard text limited to 160 characters (GSM 7-bit alphabet)

 

Example:

 

require "G3"
init_modem(“sms”)
number=”+6xxxxxxxxxxx”
message=”ALARM!!! Battery voltage low.”
while true do

sleep(10)
print (“DIGITAL IN = ”..read_IN())

if (read_IN()==1) then

print (“External IN triggered. ALARM sent!”)

sms_send(number,message,10)        #timeout=10sec

end

end

Reading SMS as normal text

 

sms_read(timeout_sec)

returns 0 when there is no sms received

returns the sms message when sms is received

 

Example:

 

require "G3"
init_modem(“sms”)
repeat

sleep(10)
print (“Waiting for incoming sms...”)

msg=sms_read(60)               #timeout=60sec
until msg ~=0

print (msg)

Sending SMS in PDU mode

pdu_send(length, pdu, timeout_sec)

length = Total length in octets (8bits eg. FF) excluding SMSC data.

pdu = The actual PDU data in hex form.


Example:


length = "20"

#20 >Length (decimal) of PDU data in octets (exclude SMSC info)

pdu = "0011000B911689674523F10008FF0677ED6D88606F"

#00 >SMSC, zero means use SMSC stored in phone/SIM
#11 >SMS-SUBMIT

#00 >TP-Message-Reference
#0B >Length of phone number (11)
#91 >International format for phone number
#1689674523F1 >phone number=61987654321
#00 >TP-PID
#08 >TP-DCS Data Coding Scheme 00=ASCII 04=Binary 08=UCS2(Unicode)

#FF >TP-Validity-Period
#06 >TP-User-Data-Length
#77ED6D88606F >sms message in Chinese for "Short Message"

require "G3"
init_modem(“pdu”)
while true do

sleep(10)
print ("DIGITAL IN= "..read_IN())

if (read_IN()==1) then

print "External IN triggered. PDU data sent!"

pdu_send(length,pdu,10)           #timeout=10sec

end

end

Reading SMS in PDU mode

pdu_read(timeout_sec)

returns 0 when there is no PDU message received

returns the PDU message when received

 

Example:

require "G3"

init_modem(“pdu”)

repeat

sleep(5)

msg=pdu_read(10)          #timeout=10sec

until msg ~= 0

print (msg)

Serial Port Functions

Serial Port Functions

Open/close serial RS232/485

serial_open(port,baud_rate,data_bits,stop_bits,parity)

opens the serial port with defined port number, baud rate, data bits, stop bits and parity.

serial_close(port)

close the serial port with defined port number

serial_raw(port)

set serial port with defined port number to raw mode

baud_rate = 2400, 4800, 9600, 19200, 38400, 57600, 115200
data_bits = 7, 8
stop_bits = 1, 2
parity = ‘N’, ‘E’, ‘O’ (i.e. None, Even, Odd parity)

Note* : RS232 or RS485 type setup via G3 web configure.
Note**: Only available on G3 model with extended serial and usb port.
Note^ : CONSOLE is the Linux system console and not available for programming access.

Sending serial RS232/485

 

serial_send(port,message,timeout_sec)

Send a message in ASCII code
 

Example:
 

require "G3"

serial_open(1,115200,8,1,’NONE’)    #opens port1 @115200baudrate, 8databit, 1stopbit, no parity

message="SEND MESSAGE FROM LUA\r\n"

serial_send(1,message,10)    #send message via port1 with timeout=10sec

print ("send="..message)

serial_close(1)   #close port1

Send a message in HEX/BIN value.

 

Example:

require "G3"
serial_raw(1)    
#set port1 to raw mode

serial_open(1,115200,8,1,’NONE’)    #opens port1 @115200baudrate, 8databit, 1stopbit, no parity

hexdata=string.char[0x01,0x04,0x1A,0x2B,0x3F]

serial_send(1,hexdata,10)    #send hexdata via port1 with timeout=10sec

serial_close(1)    #close port1

 

 

Reading serial RS232/485

serial_read(port,end_char,timeout_sec)

end_char = return when receive the end of message character

returns None when there is no serial data received
returns serial data upon receiving end_char or upon timeout

Example (ASCII code):

require "G3"

serial_open(1,115200, 8,1,’NONE’)      #opens port1 @115200baudrate, 8databit, 1stopbit, no parity

end_char="\n"      #return on receiving newline char

rxstr=serial_read(1,end_char,10)      #read port1, returns only upon end_char or timeout=10sec

print("serial read data = "..rxstr)     

serial_close(1)     #close port1

Example (HEX/BIN code):

require "G3"
serial_open(1,115200, 8,1,’NONE’)     
#opens port1 @115200baudrate, 8databit, 1stopbit, no parity

end_char=string.char(0x00)      #return on receiving char value 0x00

rxstr=serial_read(1,end_char,10)      #read port1, returns only upon end_char or timeout=10sec

byte2 = string.byte(rxstr,2)       #convert non-printable char to numerical char
byte3 = string.byte(rxstr,3)
print(byte2, byte3)

serial_close(1)       #close port1

serial_receive(port,length,timeout_sec)

length = serial input buffer maximum size
returns nil when there is no serial data received

returns serial data upon input buffer full or upon timeout

Example (ASCII code):

import G3

G3.serial_open(1,115200, 8,1,’N’)      #opens port1 @115200baudrate, 8databit, 1stopbit, no parity

length=10      #input buffer max size

rxstr=G3.serial_receive(1,length,10)      #read port1, returns only upon input buffer full or timeout=10sec

print “serial receive data = “, rxstr

G3.serial_close(1)      #close port1

Example (HEX/BIN code):

import G3
G3.serial_open(1,115200, 8,1,’N’)      
#opens port1 @115200baudrate, 8databit, 1stopbit, no parity

length=10      #input buffer max size

rxstr=G3.serial_receive(1,length,10)      #read port1, returns only upon input buffer full or timeout=10sec

byte3 = ord(rxstr[3])       #convert non-printable char to char value
byte4 = ord(rxstr[4])

print “serial receive data = ”, byte3, byte4

serial_close(1)        #close port1

 

Modbus Master Functions

Modbus Master Functions

Initialize Modbus master module

init_mbm()

Function to load modbus library into memory.
This must be executed once before any Modbus function call.

Open new connection context to Modbus slave

L1=mbm.open(“rtu”, baudrate, parity, data, stop, timeout)

returns a valid context L1 (>=0)

“rtu”

= Modbus/RTU device via SERIAL port RS232/RS485

baudrate

= serial baudrate of RTU device (1200,2400,4800,9600,19200,38400,57600,115200)

parity

= serial parity of RTU device (“N”,“E”,”O”)

data

= serial data bit of RTU device (7,8)

stop

= serial stop bit of RTU device (1,2)

timeout

= response timeout (seconds)

 

L1=mbm.open(“tcp”, ip_address, ip_port, timeout)

returns a valid context L1 (>=0)

“tcp”

= Modbus/TCP device via ETH port ETH0/ETH1

ip_address

= IP address of Modbus device (eg “192.168.1.100”)

ip_port

= IP port of Modbus device (default 502)

timeout

= response timeout (seconds)

Connect using connection context to Modbus slave

mbm.connect(L1)

L1 = a valid connection context (>=0) from mbm.open() function

returns 0 if connection successful
returns -1 if connection failed/timeout

Read Boolean status from Modbus slave

FC=01 for read discrete coils

data_8bitTable, status = mbm.fc1(L1, node, coil_address, coil_count, timeout)

FC=02 for read discrete inputs

data_8bitTable, status = mbm.fc2(L1, node, input_address, input_count, timeout)

Write Boolean state to Modbus slave

FC=05 for write single discrete coil

status = mbm.fc5(L1, node, coil_address, coil_state, timeout)

FC=15 for write multiple coils

status = mbm.fc15(L1, node, coil_address, coil_count, timeout, data_8bitTable)

Read data registers from Modbus slave

FC=03 for read holding registers (40,001 in old Modicon convention)

data_16bitTable, status = mbm.fc3(L1, node, reg_address, reg_count, timeout)

data_32bitTable, status = mbm.fc3_32bit(L1, node, reg_address, reg_count, timeout)

FC=04 for read input registers (30,001 in old Modicon convention)
data_16bitTable, status = mbm.fc4(L1, node, reg_address, reg_count, timeout)

data_32bitTable, status = mbm.fc4_32bit(L1, node, reg_address, reg_count, timeout)

Write data registers to Modbus slave

FC=06 for write single register

status = mbm.fc6(L1, node, reg_address, data_16bit, timeout)
status = mbm.fc6_32bit(L1, node, reg_address, data_32bit, timeout)

FC=16 for write multiple registers
status = mbm.fc16(L1, node, reg_address, reg_count, timeout, data_16bitTable)

status = mbm.fc16_32bit(L1, node, reg_address, reg_count, timeout, data_32bitTable)

xxx_address

=address of first coil/input/register to be read/write

 

xxx_count

=number of coils/inputs/registers to be read/write

 

coilstate

=integer with value 0 or 1

 

data_16bit

=16bit unsigned integer

 

data_32bit

=32bit unsigned integer

 

data_8bitTable

=array of 8bit unsigned integer elements

 

data_16bitTable

=array of 16bit unsigned integer elements

 

data_32bitTable

=array of 32bit unsigned integer elements

 

L1

=a valid connection context for the Modbus device

 

node

=Modbus/RTU slave address

=Modbus/TCP node=1

 

timeout

=response timeout (seconds)


status

=returns 1 for read/write success


 

Turn on/off the debug messages

mbm.debug(L1,0) turn off debug message in console

mbm.debug(L1,1) turn on debug message in console

Disconnect the Modbus context

mbm.disconnect(L1)
Close the Modbus connection context L1.

Close the Modbus context

mbm.close(L1)
Close and free the Modbus connection context L1.

Example:

require “G3”

init_mbm()

ip_addr=”192.168.1.100”;ip_port=502;timeout1=10

L1 = mbm.open(“tcp”,ip_addr,ip_port,timeout1)

baud=115200;parity=”N”;data=8;stop=1;timeout2=5

L2 = mbm.open(“rtu”,baud,parity,data,stop,timeout2)

status1 = mbm.connect(L1)

status2 = mbm.connect(L2)

mbm.debug(L1,1)

mbm.debug(L2,1)

if status1==0 then
node1=1;reg_addr1=100;reg_cnt1=8
data_16bitTable1,stat1 = mbm.fc3(L1,node1,reg_addr1,reg_cnt1,timeout1)

end
if stat1==1 then
print(“mbm.fc3 test read register confirmed\r\n”)
i=0
while (i<reg_cnt1) do
i=i+1
print(data_16bitTable1[i]..”\r\n”)
end
end

if status2==0 then
node2=0xC8;reg_addr2=0x1F;reg_cnt2=0x0A

data_16bitTable2={0x111A,0x222B,0x333C,0x444D,0x555E,0x666F,0x7770,0x8881,0x9992,0x0003}

stat2 = mbm.fc16(L1,node2,reg_addr2,reg_cnt2,timeout2,data_16bitTable2)
end
if stat2==1 then
print(“mbm.fc16 test write register confirmed\r\n”)
end

mbm.disconnect(L1)

mbm.disconnect(L2)

mbm.close(L1)

mbm.close(L2)

CANBus Functions

CANBus Functions

Initialize the on-board CANbus interface (specs: CAN 2.0A/B)

can_open(baud_rate)

baud_rate = your target CANbus system baud rate eg 50000,100000,125000,250000,500000 or 1000000

Maximum CAN baudrate supported by G3 is 1Mbps.
This must be executed once before any CANbus function call.

Sending CANbus messages

can_send(canid,extended,data_send)

 

canid

=000-7FF (3 hex chars for CAN 2.0A (standard))

=00000000-1FFFFFFF (8 hex chars for CAN 2.0B (extended))

extended

=0 (11-bit message ID for CAN 2.0A (standard))

=1 (29-bit message ID for CAN 2.0B (extended))

data_send

=ASCII hex chars of value 1-byte (eg 1A) to 8-bytes (eg 1A2B3C4D5E6F7A8B)

Option to separate by ‘.’ , e.g. 11.22.33.44.55.66.77.88

Receiving CANbus messages

data_receive = can_receive(canid,canmask,timeout)

returns 0 when no validated CANbus message received on timeout

canid

=000-7FF (3 hex chars for CAN 2.0A (standard))

=00000000-1FFFFFFF (8 hex chars for CAN 2.0B (extended))

canmask

=000-7FF (bit value 0 mask out message)

=00000000-1FFFFFFF (bit value 0 mask out message)


timeout

=receive timeout (seconds)

Mask usage example:
canid=0x5A0, canmask=0x7FF
canid & canmask = 0x5A0
Above mask will receive message with ID 0x5A0

canid=0x280, canmask=0x280
canid & canmask = 0x280
Above mask will receive message with ID 0x280 to 0x28F.

Close the CANbus interface

can_close()

Close the CANbus interface.

Example:

require "G3"

can_open(125000)       #baud rate=125000bps

sleep(0.1)

id1=”280”       #canid=0x280
extended1=0       #standard mode
data1=”AABBCC”       #data=0xAA,0xBB,0xCC

can_send(id1,extended1,data1)

id2="1F177678"       #canid=0x1F177678
extended2=1        #extended mode

data2="11.22.33.44.55.66.77.88"         #data=0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88

can_send(id2,extended2,data2)

canid={}

canmask={}

canid[1]="111";canid[2]="222";canid[3]="333";canid[4]="444";canid[5]="555" canmask[1]="7FF";canmask[2]="7FF";canmask[3]="7FF";canmask[4]="7FF";canmask[5]="7FF";

timeout=10 --seconds

while (read_IN()==1) do

can_data=can_receive(canid, canmask, timeout)

print (can_data)

end

can_close()

ZigBee Functions

ZigBee Functions

zigbee_status()

returns 1 if zigbee port found

returns 0 if zigbee port not found
 

zigbee_open(speed)

opens the zigbee port
speed = 19200 (for Telegesis ETRX357 Zigbee adapter)

zigbee_close()

close the zigbee port

data_receive=zigbee_read(timeout_sec)

returns 0 when no Zigbee message received

timeout_sec =receive timeout (seconds)

Zigbee report attributes message comprise of ZCL header and attributes report.
Typical ZCL reporting :

RX:D55A,0104,02,0A,0702,0D:<18><F3><0A><0A><E1><21><A5><5C><43><E1><21><85><13>

Note that the attributes report with <xx> denotes the raw data value received. Eg <18>=0x18

Function zigbee_read() will convert the raw data value to ascii code. Eg <18> will be reported as “18”

RX:D55A,0104,02,0A,0702,0D:18F30A0AE121A55C43E1218513

Example:

require "G3"

 

if zigbee_status() then

zigbee_open(19200)

while True:

data_receive=zigbee_read(10)      #timeout=10sec

until data_receive ~= 0):

print (data_receive)

zigbee_close()

else:

print (“zigbee port not found”)

end

 

GPS Functions

GPS Functions

This function is using the GPS capability built into the cellular module.

The external GPS antenna (non-active type) is an optional item.

gps_start(interval)

interval = GPS positioning time interval (1-1800 seconds)
function initialize the GPS to standalone mode (non-assist) and start positioning.

 

gps_stop()
stops the GPS positioning routine in the wireless module


gps_read(timeout)
returns 0 when there is no gps position reported
returns a valid gps position report on every interval time after position lock-in success

timeout =receive timeout (seconds)

Example:

 

require "G3"

interval=10

gps_start(interval)

while (read_IN()==1) do       #eg connect INPUT to engine ignition switch

sleep(1)

gps=gps_read(10)        #timeout=10sec

print(gps)

end

gps_stop()

 

LUA Script Debug

LUA Script Debug via SSH or Console (extended port version)

You can connect via SSH or CONSOLE to edit/run scripts and view debug information.


Just enable SSH (need reboot) and connect via SSH as ‘root’ and using same password as web login.

 

When connected, you can run your Python scripts as below example.


Eg. /# lua /user/user.lua


Note that the LUA samples are located in the folder /scripts.


Eg. /# lua /scripts/python/chkdip.lua

Special Setup Requirements

Setup Requirement for Specific Applications

Setup G3 router for SMS reboot application

For LUA application making use of SMS to reboot, it is recommended to disable the ‘Signal LEDs’ as shown below.

 

 

 

Setup G3 router for SMS online/offline application

For LUA application making use of SMS to trigger ppp online/offline, it is recommended to

  • -  Disable the ‘Signal LEDs’ as shown above.

  • -  Disable the ‘Reboot on Ping Failure’ as shown below.

  • -  Disable the ‘Reboot on 3G Data Failure’ as shown below.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Got another Question? Write to us.

bottom of page