LuaPaste

Easy way to update lua script on NodeMCU

LuaPaste

Lua script to make uploading other scripts easier. Just paste the script in the terminal and the ESP will store it in a file.

Materials needed:
- ESP8266 running NodeMCU
- USB to Serial adapter if your ESP board does not include one
- UART Terminal program to communicate with your ESP

Introduction

The ESP8266 module with NodeMcu firmware is just amazing!
It has Lua interpreter, so you can write programs using just a Serial Terminal (I use CuteCom on Ubuntu).
You can store .lua scripts directly on ESP8266, and then run them, for example: dofile("test.lua").
Here is an example from https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_en
for storing a file in the module's memory:

file.open("hello.lua","w+")
file.writeline([[print("hello nodemcu")]])
file.writeline([[print(node.heap())]])
file.close()


The problem is that for each line in your lua file, you have to write the additional file.writeline([[" and "]]).
There are programs that do this automatically for you, like LuaLoader (Windows executable) or luatool (python script).
But you need a PC to use them.

I decided to write a lua script to make things easier (and faster).

Steps:

1.
Make sure your ESP runs NodeMCU and can be accessed from terminal.

2.
Set terminal char delay to big enough delay like 100ms.

3.
Send some enters to see if the connection is OK (NodeMCU must respond with ">" )

4.
Copy the LuaPaste script and paste it in the terminal.

-- LuaPaste v1.2 by RoboRemo

function luaPaste()
  local s=""
  local function a5(cb) tmr.stop(0) tmr.alarm(0,500,0,cb) end
  local function read(cb)
    uart.on("data", 0, function(a) s=s..a a5(cb) end, 0)
  end
  local function run()
    print("enter file name")
    read(function()
      if s:sub(-1,-1)=="\n" then s = s:sub(1,-2) end
      if s:sub(-1,-1)=="\r" then s = s:sub(1,-2) end
      if s:sub(-1,-1)=="\n" then s = s:sub(1,-2) end
      file.remove(s) file.open(s, "w+") print("file "..s.." opened") s=""
      read(function() file.write(s) file.close() print("file closed") uart.on("data") end)
    end)
  end
  a5(run)
  uart.on("data", 0, function(a) a5(run) end, 0)
end
luaPaste()


Older versions:

luapaste_v11.lua

luapaste_v10.lua

5.
Wait (only this time) (number of characters in LuaPaste script x 100 ms)

6.
Enter luapaste.lua (get response "file luapaste.lua opened")

7.
Set char delay to 0 ms

8.
Paste the script again. No more waiting this time :) (get response "file closed")

9.
How to use LuaPaste:
- command: dofile("luapaste.lua")
- get response "enter file name"
- enter init.lua
- get response "file init.lua opened"
- paste the entire file directly in the terminal. (I use moserial terminal for this. CuteCom does not work, because its cmd buffer is too small for pasting an entire file)
- get response "file closed" (500 ms after the last character)
- command: node.restart()
- now the init.lua is running

What's new in v1.2:
When entering file name, it waits 500 ms after the last character, instead of waiting for "\n". This solves the problem with terminals that append "\r\n" at the end, which resulted in filenames like "init.lua\r" instead of "init.lua", and "init.lua\r" was not called at node.restart().
It also removes the "\n" or "\r" or "\r\n" or "\n\r" (does it exist?) from the end of the filename if the terminal is adding it.

I hope that LuaPaste is useful to you.
If yes, please tell others about it, don't keep it only for yourself :)