Over the years I’ve been seeing Lua programs pop up in places that I didn’t expect, for example:
- Sony PSP (Play Station Portable)
- Nintendo DS
- Redis in-memory data server
- ESP- 8266 and NodeMCU micro controllers
In this blog I wanted to document a couple of examples of using Lua on Raspberry Pi projects. (For a blog on using Lua with simple curses GUI’s).
An Introduction of Lua
Lua is a lightweight interpreted scripting language. The Lua interpreter is supported on most operating systems, however like Python not all of its libraries are support on all OS’s.
Lua’s greatest following is in the gaming world. The love2d graphic framework is open source and it works on Windows, Mac OS X, Linux, Android and iOS.
There are some good Lua tutorials to get you jump started. If you’re familiar with Python and Basic programming the Lua language is fairly easy to learn.
Install of Lua on a Raspberry Pi
To install Lua on a Pi enter the following lines:
sudo apt-get update sudo apt-get install lua5.1 sudo apt-get install liblua5.1-0-dev -- development files, need by LuaRocks sudo apt-get install lua-socket sudo apt-get install luarocks -- package manager for Lua modules sudo luarocks install luasocket
There a number of versions of Lua, going from 5, 5.1, 5.2 to 5.3. I used version 5.1 because most of the examples used this version, but there isn’t a problem loading multiple versions.
Lua has a package manager called luarocks, this is similar to pip on Python, where you can install custom libraries or packages on the Pi.
There are a number of choices on how Lua can access Pi GPIO pin. I found that the lua-periphery library to be a reliable option. To install this library enter:
sudo luarocks install lua-periphery
To read a GPIO input:
local GPIO = require('periphery').GPIO -- Open GPIO 10 with input direction local gpio_in = GPIO(10, "in") local value = gpio_in:read() print ("GPIO pin 10 :", value) gpio_in:close()
To toggle an LED with a keyboard value :
-- toggle.lua : get user a user value to send to a GPIO local GPIO = require('periphery').GPIO -- Open GPIO 4 with output direction local gpio_out = GPIO(4, "out") while (true) do print ("Enter an output value:") s = io.read("*n") gpio_out:write(s) print ("Output value:", gpio_out:read(),"\n") end gpio_out:close()
To run the LED toggle program:
$ sudo lua5.1 gpio1.lua Enter an output value: 1 Output value: true Enter an output value: 0 Output value: false
To exit the program enter “Control-C”
Lua Socket Applications
For many application you want to remotely view or control data. One way to do this is to create an application that is a socket server. A simple Lua socket server application that show what a remote socket client sends is:
-- sock.lua : a socket server that prints client input local socket = require("socket") -- create a TCP socket and bind it to the local host, at any port local server = socket.bind("*", 444) -- loop forever waiting for clients print ("Lua Socket Server on Port 444") while 1 do -- wait for a connection from any client local client = server:accept() -- receive the line local line, err = client:receive() print("Input:", line) client:close()
The socket server can be tested by opening a second terminal window and then use a bash script to send a text string to the open port (444 for this example):
$ echo "1" > /dev/tcp/localhost/444 $ echo "0" > /dev/tcp/localhost/444
Our Lua socket server application will show the client text that is sent:
$ sudo lua5.1 sock.lua Lua Socket Server on Port 444 Input: 1 Input: 0
A Lua Socket Server with GPIO Control
The next step is combine that socket server with GPIO call. For the next example if a 0 or 1 is sent, then the GPIO output will be set to 0 or 1.
-- load libraries local socket = require("socket") local GPIO = require('periphery').GPIO local gpio_out = GPIO(4, "out") -- create a TCP socket and bind it to the local host, at any port local server = socket.bind("*", 444) -- loop forever waiting for clients print ("Lua Socket Server on Port 444") while 1 do -- wait for a connection from any client local client = server:accept() -- receive the line local line, err = client:receive() print("Input:", line) if (line == "0") then gpio_out:write(0) elseif (line == "1") then gpio_out:write(1) end client:close()
You can use the same bash script from the above example to toggle a GPIO pin.
I like how in 1 day I was able to go from, no real knowledge on Lua, to remotely using sockets to control Raspberry Pi GPIO pins.
I found my biggest issue was a standard and simple graphic interface. Love2D has a lot of potential but it’s a little like Python PyGame great for games but a little over kill if you want to create a dialog with a couple of buttons. The Lua curses library offers an “old style” interface but the documentation and examples are a little weak.
I can’t see myself giving up Python for Lua but I could perhaps see using Lua on projects where:
- Lua is used on ESP-8266/NodeMCU and you want to include some Raspberry Pi integration
- Lua is been used on a Redis database server and either a Pi or a ESP-8266 is passing up/down data