Raspberry Pi with Lua LÖVE Graphics

In a couple previous blogs I looked at using Lua to read/write with Raspberry GPIO pin, and creating simple text based (ncurses) Lua interfaces.

The Lua LÖVE Graphic engine is very popular for 2D gaming.

In this blog I wanted to document how I used Lua LÖVE Graphics with Raspberry Pi data, specifically I’ll look at:

  • Writing Text with different colours and Font sizes
  • Use a timer to periodically update the screen with Raspberry Pi temperatures
  • User keys to toggle Pi GPIO
  • Use button images to toggle logic

Getting Started with LÖVE Graphics

Rather than LÖVE being a graphic library it’s a replacement Lua interpreter, so you run your code directly through LÖVE. To install LÖVE:

sudo apt-get update 
sudo apt-get install love

You can check that love is running by:

pi@raspberrypi:~/ $ love --version
LOVE 11.1 (Mysterious Mysteries)

There are a number of IDE’s that are available, however any text editor will work. I used leafpad on the Pi.

First Example with Text and Keypresses

The LÖVE expects a project to be in it’s own directory with a main.lua file.

My first example was to launch a window with some text and then catch keystrokes. A “q” key will exit the program.

-- My First App --

platform = {}
love.window.setTitle("Raspberry Pi Data")

function love.draw()
-- draw some text and a rectangle --
  love.graphics.setColor(1,0,0) -- rgb, use red
  love.graphics.setFont(love.graphics.newFont(72)) 
  love.graphics.print("Hit q to exit", 200, 200) 

end

function love.keypressed( key )
   print(key)
   if key == "q" then
      	print( "Quiting Now")
	love.event.quit()
   end
end

This program is call main.lua . An example of this program running with output:

pi@raspberrypi:~/lua1 $ love ./
a
b
q
Quiting Now

lua1

Add a Timer Loop

There are a number of timer loop options. I found that some of these options however would take a lot of background CPU resources. One solution that worked well for me was to add a cron function from : https://github.com/kikito/cron.lua

I downloaded this code (cron.lua) and put it into my working project directory.

For this example I wanted to show the Raspberry Pi’s  GPU temperatures. For the GPU temperature, a Pi command line utility exists:

pi@raspberrypi:~ $ /opt/vc/bin/vcgencmd measure_temp
temp=44.0'C

This code example includes:

  • A reference to a cron file, and a timer variable is setup with a getGPU function
  • a shell to the command line : /opt/vc/bin/vcgencmd measure_temp , and then the output was read into a variable (GPU).
  • the love.draw function is refreshed with the love.update function.
-- Dynamically show the GPU temperature

platform = {}
love.window.setTitle("Raspberry Pi Data")

local cron = require 'cron'  -- this file is in the working dir

local msg = 0
local timer = cron.every(5, function() msg = getGPU()  end)


function getGPU() -- read the command line output
	f = assert (io.popen ("/opt/vc/bin/vcgencmd measure_temp"))
	for line in f:lines() do
	GPU = line
		print(line)
	end
	return GPU 
end

 
function love.update(dt)
	timer:update(dt)
end
 

function love.draw()	
	love.graphics.setColor(0,1,0) 
	love.graphics.setFont(love.graphics.newFont(72)) 
	love.graphics.print(msg, 200, 200)

	love.graphics.setColor(0,0,1) 
	love.graphics.setFont(love.graphics.newFont(24)) 
	love.graphics.print("Hit q to quit", 10, 10)	
end

function love.keypressed( key )
	print(key)
   	if key == "q" then
		print( "Q - quit has been pressed!")
		love.event.quit()
   	end
end

The output will look something like:

lua2

After I got the basic timer function working my next step will be to look at creating dynamic bars for Pi Sensors.

lua3

GPIO Reads and Writes

There are couple of choices for doing Lua connections to GPIO pins.

The lua-periphery library works well but it required sudo rights. For a command line program this isn’t a problem but by default the Raspberry Pi will not allow X-windows to run under super-user. A way to run X-Windows with sudo is:

sudo XAUTHORITY=$HOME/.Xauthority love /mypath_dir

Perhaps a simpler approach is to run the gpio command line program (this is pre-install on the PI’s). Below is some code that uses keystrokes to toggle a GPIO pin.

-- Toggle GPIO pins with keystrokes
 
function love.draw()
	love.graphics.setColor(0,0,1) 
	love.graphics.setFont(love.graphics.newFont(24)) 
	love.graphics.print("Keys: 0 = off, 1 = on, q to quit", 10, 10)	
	
	love.graphics.setColor(0,1,0) 
	love.graphics.setFont(love.graphics.newFont(72)) 
	f = assert (io.popen ("gpio read 7"))
	for line in f:lines() do
		pin7 = line
		print(line)
	end
	love.graphics.print("Pin 7 : " .. pin7, 200, 200)

end

function love.keypressed( key )
	print(key)
	if key == "0" then
		os.execute("gpio write 7 0")
	end
	if key == "1" then
		os.execute("gpio write 7 1")
	end
   	if key == "q" then
		print( "Q - quit has been pressed!")
		love.event.quit()
   	end
end

The output will be:

lua4

Buttons Toggles

Button images can be defined in the load function, then in the draw function they can be drawn based on some logic. Below is a example with two buttons (red/green), the mousepressed function will catch mouse clicks on the x-y sizing of the image. Then some logic was added to toggle between the two red/green buttons and text feedback.

-- Love 2 Button Example --

platform = {}
love.window.setTitle("Raspberry Pi Data")

local buttoncolor = "red"
 
function love.load()

	red = love.graphics.newImage("red.png")
	green = love.graphics.newImage("greenbutton.jpeg")
	
end
 
function love.update(dt)

end
 
function love.draw()
	love.graphics.setBackgroundColor( 1,1, 1)
	buttonx = 10
	buttony = 10
	if buttoncolor == "red" then
		love.graphics.draw(red,buttonx,buttony)
		r = 1
		g = 0
	else
		love.graphics.draw(green,buttonx,buttony)
		r = 0
		g = 1
	end
	love.graphics.setFont(love.graphics.newFont(48)) 
	love.graphics.setColor(0,0,0) 
	love.graphics.print("Click button\n 'q' to quit", 350, 20)	
	love.graphics.setColor(r,g,0) 
	love.graphics.print("Button State: " .. buttoncolor, 10, 350)
	love.graphics.setColor(1,1,1) 
end

function love.mousepressed(mx, my, button)
   if button == 1
   and mx >= buttonx and mx < buttonx + red:getWidth()
   and my >= buttony and my < buttony + red:getHeight() then
		if buttoncolor == "red" then
			buttoncolor = "green"
		else
			buttoncolor = "red"
		end      
		
   end
end

function love.keypressed( key )
	print(key)
   if key == "q" then
     print( "q - quit has been pressed!")
	 love.event.quit()
   end
end

The button image and the “Button State” text will toggle each time the button is clicked.

red_button

Final Comments

I found that I was able to do all the things that I needed for my Raspberry Pi project, however I struggled with the documentation and examples.

For me this was a chance to learn Love, but I would pick Python over Lua/Love for Raspberry Pi projects. I found that Python with Tkinter was considerably faster with a lot more examples.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s