Lua Fast-Tracks Embedded Web Application Development

(Lua Fast-Tracks IoT Development)

Learn why Lua and LSP provide the best web framework to use for web-enabling your RTOS, VxWorks, QNX, or embedded Linux.

Introducing Lua

Lua is a powerful, fast, lightweight, and embeddable scripting language. Lua combines simple procedural syntax with powerful data description constructs based on associative arrays and extensible semantics. Lua is dynamically typed, runs by compiling the script to bytecode for a register-based virtual machine, and has automatic memory management with incremental garbage collection.

Although not specifically designed for use in embedded devices, its status as the smallest and fastest scripting language available makes it ideally suited for that purpose. In addition, Lua is designed as a C library that can easily be linked to any application.

You may be convinced that using C alone is the best way to write code for embedded applications. However, when creating an embedded web application requiring a rich, responsive, and easily adaptable user interface like that which you enjoy in your favorite Smartphone, there is a smarter, more efficient development path than using C alone.

You may not be aware of it, but if you've ever used Adobe's Lightbox program, played Roblox or World of Warcraft, or run any number of other Web-based programs, you've experienced a scripting language known as Lua.

Making use of the Lua scripting language instead of C alone lets developers:

  • Focus resources on higher-level elements of device design
  • Quickly and easily design and deliver rich, responsive, high-performance user interfaces for web-based embedded applications, and reduce time to market from as much as many months to only days.

Let's look at how Lua delivers these two factors and then examine the "how-to" of it all.

Developers can focus on high-level design

Smartphones have made life difficult for developers of small, connected embedded systems. Users have become accustomed to the rich and attractive user interface that such phones provide, and they now expect all small web-based, embedded devices to provide a web-based GUI just as attractive as the apps on a smartphone. The problem is most small devices don't have the processing power and the amount of memory required to run standard application servers and their high-end server-side scripting environments. Your customers don't know or understand this, but they expect modern, great-looking user interfaces and want their user interaction to be fast - just like they find on their Smartphones.

In addition, as these small, web-based devices are expanding into areas such as industrial or building controls, medical devices, and more, companies are finding they need to address user expectations to remain competitive in delivering such user interfaces.

Until now, those user expectations have presented a massive challenge. Conventional wisdom among engineers dictates that using C code is best for small web-based devices rather than considering the use of a scripting language because scripting languages require "desktop computers and performance."

However, there is another answer. Enter the Barracuda Application Server by Real Time Logic. The Barracuda Application Server makes using a scripting language possible - and the Lua scripting language is why. So why does this make such a big difference?

To figure that out, let's look at what work needs to be done.

Development work can be broken down into the following categories:

  • Managing data (which is hopefully structured)
  • Parsing requests
  • Assembling responses

With C, structures can't be entered into lightly: everything must be strictly typed. When managing server-side web applications developed in C, memory must be explicitly reserved and released as needed. Parsing isn't rocket science, but it's tedious and extremely easy to get wrong. It requires incredible attention to every detail, making maintenance difficult. Assembling the page requires string concatenation on a grand scale, which is also time-consuming and error-prone in C code.

With application servers and scripting environments, however, much of this work has already been done for you. An application server is a compact middle layer that abstracts the web server details, giving you access to request and response objects and their associated APIs. This means your application only has to deal with high-level behavior and data. The application server handles the time-consuming and tedious low-level parsing and page-building details.

In the past, websites were developed via a Common Gateway Interface (CGI) interface. The problem was that CGI necessitated a full-blown operating system, such as Linux, equipped with external program loading capabilities, which prevented CGI from being compatible with embedded monolithic systems. The CGI was also difficult to manage and required you to write code that handled the HTTP request headers and the HTTP response headers.

Standard web servers equipped with CGI often use Perl scripting. However, C is required in most embedded environments since Perl is typically not supported.

Because scripts are more free-form and are compiled just in time, a single script line can implement the entire string concatenation. The lower-level machinations are automatically handled for you by Lua's virtual machine. Scripts also let you access and manipulate data without worrying about whether you've defined the right data type or organization.

Furthermore, not even the most ardent C advocate would identify text handling as easy when writing C code, and web applications require extensive text handling. So, the bottom line becomes clear. You can develop your web application in Lua in as little as 1/30th the time of C coders by using scripts and pre-built infrastructure instead of relying entirely on custom-written C.

Lua doesn't totally eliminate C from the equation - it is retained for what it does best. Scripting environments intentionally restrict scripts from getting down to the hardware level, so C routines, working similarly to drivers, are used to connect your hardware to your web application.

Lua delivers the user experience

In essence, the particular focus of web-based embedded applications means that their optimal development environment differs from that of other embedded applications. With today's users of small, web-based device applications demanding and expecting a rich user interface, Lua fits the bill.

Scripts are compiled just-in-time and executed on an embedded virtual machine. Although that virtual CPU brings additional overhead to the CPU, compared to compiled C code, it is not noticeable because the main overhead is in the network connection. Lua web applications typically respond lightning fast, even when run in small, web-based embedded devices.

Running together, as shown in Figure 1, the Barracuda Application Server and Lua scripting engine deliver applications that use much fewer resources than they would in standard application server frameworks.

Barracuda Application Server Block Diagram

Figure 1. You can write your applications as Lua scripts that interact with the application server and other blocks, including custom C routines.

Lua development how-to

As shown in Figure 1, the system services, application server, SSL stack, and Lua virtual machine allow you to focus on your application logic using high-level data structures in Lua scripts. Unlike most other languages, Lua is easily extended not only with software written in Lua itself but also with software written in other languages. It is, therefore, straightforward to use C for low-level access to your hardware.

To develop such a system, you write and compile your C functions using your standard C tools. Depending on the requirements of your OS, you either compile them into a monolithic system or you build a separate executable process. To connect Lua to your C functions, you create Lua bindings (either manually or using an automation tool such as our online binding generator that you include in the C project when it is compiled.

The Lua scripts themselves are written using a straightforward, easy-to-learn procedural syntax (Figure 2).

local function calculatePwmDutyCycle(angle)
   local pulseWidth = ((angle - minAngle) * (maxPulseWidth - minPulseWidth) / (maxAngle - minAngle)) + minPulseWidth
   return (maxPwm / cycleTime) * pulseWidth

-- The following function runs as a coroutine timer.
-- timer: /ba/doc/?url=lua.html#ba_timer
local function servo()
   local ok,err=esp32.ledtimer{
      mode="LOW", -- speed_mode
      bits=bits, -- duty_resolution (bits)
      timer=0, -- timer_num
   if ok then
      local duty = 2000 / 20000 * 100
      local led,err=esp32.ledchannel{
         timer=0, -- timer_sel
         duty = calculatePwmDutyCycle(180),
      if ok then
         while true do
            for angle=0,180 do
               local pwmDuty = calculatePwmDutyCycle(angle)
               printf("Angle of rotation: %d, PWM Duty Cycle: %d : %%%2.1f", angle, pwmDuty, pwmDuty/maxPwm*100);
               --printf("Angle of rotation: %d, PWM Duty Cycle", 0);
               coroutine.yield(true) -- Sleep

Figure 2. Source code for servo control with the ESP32 as shown in video below.

Servo control using Lua and real-time WebSocket communication.

The above video shows an older version of our Xedge32 Lua development environment for ESP32.

Lua's just-in-time compiler executes while the system is operating. Whenever you navigate or refresh the browser, the virtual machine will compile any changed script before sending the requested response to the browser, automating the script compilation and execution. This starkly contrasts with a C program that requires cross-compilation on a desktop computer, linking, and uploading the executable to the device. Figure 3 illustrates the development process.

C to Lua development flow

Lua to C/C++ access is called a Lua binding and can be created manually or by using our automatic Lua Binding Generator.

LSP development cycle

Figure 3. The development flow. C code is compiled ONLY once. The Lua scripts are compiled just in time in the embedded device when requested by the browser.

C++ vs. Lua Comparison:

For a practical illustration, consider our C++ WebSocket example on GitHub. The C++ version spans over 200 lines of code, requiring careful management of threads and synchronization. In contrast, the Lua equivalent achieves the same functionality in just 26 lines, thanks to our Cosocket technology, which eliminates the need for complex thread handling. You can review the code yourself; the C++ example includes the Lua version as a comment at the top of the file for easy comparison.

C coder vs Lua coder and time to market


In the end, what really matters is that users experience your system in a way that includes the high-end graphics and attractive visual standards that they expect and demand. The last thing you want to provide is a dated, tired, and mediocre web-based user interface that looks like it was designed in 1990. However, you don’t want to spend unnecessary effort and development time on the user interface by using tools that take your focus away from your own technology. By using a web environment that supports fast prototyping/development, one that’s designed to work on small embedded systems, and doing this along with a scripting language like Lua, you can focus on high-level design while also giving your users the interface they want. The Barracuda Application Server with the Lua module is specifically designed to enable embedded computer programmers to design the user interfaces and IoT required by today's end-users rapidly.

The Barracuda App Server provides a high-level development environment that enables full-stack developers to design web-based user interfaces for devices. This is possible thanks to the scripting language integrated into the Barracuda App Server. A full-stack developer can design web interfaces for devices -- something that they would normally not be able to do since they are not C programmers. Your embedded engineers can then focus on your device and only need to provide a device API for the full-stack developer(s).

For a hands-on Lua device management tutorial, check out Your First Professional Embedded Web Interface.

The term full-stack means developers who are comfortable working with both back-end and front-end technologies. To be more specific, it means that the developer can work with LSP, HTML, CSS, JavaScript, and everything in between, including Ajax and REST.

Attention Full-Stack Web Developers!

Are you ready to take your coding prowess to the next level by diving into the world of real-time device management applications? Discover how you can broaden your skill set with our Microcontroller Skills Certification specifically tailored for full-stack developers like you.

Additional Embedded Web Server Tutorials

Facing Challenges? Let's Overcome Together!

Dive deep into our treasure trove of embedded web server and IoT tutorials designed for enthusiasts like you. Yet, if deadlines loom or challenges arise, remember our experts are on standby. With Real Time Logic, you have the freedom to learn and the assurance of expert support when you need it. Let's bring your project to fruition your way.


OPC-UA Client & Server

An easy to use OPC UA stack that enables bridging of OPC-UA enabled industrial products with cloud services, IT, and HTML5 user interfaces.

Edge Controller

Edge Controller

Use our user programmable Edge-Controller as a tool to accelerate development of the next generation industrial edge products and to facilitate rapid IoT and IIoT development.

On-Premises IoT

On-Premises IoT Platform

Learn how to use the Barracuda App Server as your On-Premises IoT Foundation.

Embedded Web Server

Barracuda Embedded Web Server

The compact Web Server C library is included in the Barracuda App Server protocol suite but can also be used standalone.

WebSocket Server

Microcontroller Friendly

The tiny Minnow Server enables modern web server user interfaces to be used as the graphical front end for tiny microcontrollers. Make sure to check out the reference design and the Minnow Server design guide.

WebDAV Server

Network File System

Why use FTP when you can use your device as a secure network drive.

HTTP Client

Secure HTTP Client Library

PikeHTTP is a compact and secure HTTP client C library that greatly simplifies the design of HTTP/REST style apps in C or C++.

WebSocket Client

Microcontroller Friendly

The embedded WebSocket C library lets developers design tiny and secure IoT applications based on the WebSocket protocol.

SMTP Client

Secure Embedded SMTP Library

Send alarms and other notifications from any microcontroller powered product.

Crypto Library

RayCrypto C Library

The RayCrypto engine is an extremely small and fast embedded crypto library designed specifically for embedded resource-constrained devices.

Embedded PKI Service

Automatic SSL Certificate Management for Devices

Real Time Logic's SharkTrust™ service is an automatic Public Key Infrastructure (PKI) solution for products containing an Embedded Web Server.


Modbus TCP client

The Modbus client enables bridging of Modbus enabled industrial products with modern IoT devices and HTML5 powered HMIs.

Posted in Whitepapers