Monday 2 February 2015

ESP8266 Remote LUA console

Wow, it has been a year since I made my last post! Time really fly! Over 2014, I have been toying with many stuff, like BeagleBoneBlack, Raspberry PI, but didn't have the chance to write it down. I will write something on those soon hopefully, but today I will write about the ESP8266.

ESP8266 have been the latest hits in the electronics hobbyist world. Probably the next great thing after Arduino. Imagine having a 32bits MCU with built in WiFi and bunch of digital IO, and an A/D converter too, at US$3 only? Why not!

If you need more info on ESP8266, just head here:
http://www.esp8266.com/
http://www.seeedstudio.com/blog/2014/09/11/getting-started-with-esp8266/

In short, ESP8266 came loaded with the simple modem like AT firmware. You can connect the ESP8266 to an arduino nano and connect to the internet.






Using  this configuration, I created an internet clock with daylight saving incorporated. But that will be a separate post altogether, and I will do it later.

From the diagram above, you may ask why the 3.3V ESP8266 is connected directly to the Arduino Nano's IO without any level converter, as the Arduino Nano is a 5V device? Well, the ESP8266 is robust enough to handle that, so I just skip the level converter or even the resistors. And just to let everyone know, I did accidentally connected the ESP8266 to 5V power supply and it seem to survive that! 

Ok....

The ESP8266 came with a non industry standard 2mm pitch, thus making it difficult to use it on breadboard as is. So here is what I did:





For the ESP-03/12 that came with the 2mm pitch pin, I used 28pin IC socket, solder copper wires into the socket (like to top picture) and then solder the wires to the module. As for the ESP-01, I use SIL header with long pins, bent the pins as per the above picture and it is ready to be used on the breadboard.
If you notice, I also solder on the 3.3V regulator and capacitor onto the socket also. Having 3.3V regulator right on the module really solve my problem of having voltage drop on the whiteboard.

OK, now on the software. As mentioned above, the module came with AT firmware, but the module can also be re-flash with your own firmware. One of the most popular alternative firmware is the NodeMCU LUA interpreter. By having this interpreter, this module literally can operate on its own without external MCU like the ATMEGA328 on the Arduino. So we can use it just like the Arduino, except with built in WiFi.
To know about the NodeMCU firmware, please go here:
http://nodemcu.com/index_en.html
https://importhack.wordpress.com/2014/11/22/how-to-use-ep8266-esp-01-as-a-sensor-web-client/

To interact with the ESP8266 LUA intepreter, we need to use the serial port via USB serial converter.
And again, I just hook up the USB serial converter directly to the ESP8266 without any level converter. So far so good. And you may ask, can the the ESP8266 LUA scripts be interacted wirelessly? That was exactly the question I had before. I looked around the internet but could not find a readily available tutorial on how to accomplish that. So that is why I am writing  this blog now, to share my experience to make the ESP8266 remotely programmable, free from the USB serial converter. You can now install this little module somewhere remote (but within your wireless network), and upload/execute the LUA code wirelessly.

OK, here is the step:


1.Install NodeMCU into ESP8266 using NodeMCU flasher (if you haven't done so).
2.Download “Lua Uploader” by Hari Wiguna or the "ESPlorer" by 4refr0nt (thanks guys!)
3.Install "init.lua" into ESP8266 using USB serial port to ESP8266 (Edit your SSID and password before uploading into ESP8266). Or you can just use your own "init.lua" that will connect you to the network and execute a telnet program upon ESP8266 start-up.
 



-- Constants
SSID    = "xxxxxxx"
APPWD   = "yyyyyyy"
CMDFILE = "telnet.lua"   -- File that is executed after connection
-- Some control variables
wifiTrys     = 0      -- Counter of trys to connect to wifi
NUMWIFITRYS  = 200    -- Maximum number of WIFI Testings while waiting for connection
-- Change the code of this function that it calls your code.
function launch()
  print("Connected to WIFI!")
  print("IP Address: " .. wifi.sta.getip())
  -- Call our command file every minute.
  tmr.alarm(0, 10000, 1, function() dofile(CMDFILE) end )
end
function checkWIFI()
  if ( wifiTrys > NUMWIFITRYS ) then
    print("Sorry. Not able to connect")
  else
    ipAddr = wifi.sta.getip()
    if ( ( ipAddr ~= nil ) and  ( ipAddr ~= "0.0.0.0" ) )then
      -- lauch()        -- Cannot call directly the function from here the timer... NodeMcu crashes...
      tmr.alarm( 1 , 500 , 0 , launch )
    else
      -- Reset alarm again
      tmr.alarm( 0 , 2500 , 0 , checkWIFI)
      print("Checking WIFI..." .. wifiTrys)
      wifiTrys = wifiTrys + 1
    end
  end
end
print("-- Starting up! ")
-- Lets see if we are already connected by getting the IP
ipAddr = wifi.sta.getip()
if ( ( ipAddr == nil ) or  ( ipAddr == "0.0.0.0" ) ) then
  -- We aren't connected, so let's connect
  print("Configuring WIFI....")
  wifi.setmode( wifi.STATION )
  wifi.sta.config( SSID , APPWD)
  print("Waiting for connection")
  tmr.alarm( 0 , 2500 , 0 , checkWIFI )  -- Call checkWIFI 2.5S in the future.
else
 -- We are connected, so just run the launch code.
 launch()
end
-- Drop through here to let NodeMcu run




4. Install telnet.luainto ESP8266 using USB serial port to ESP8266. This is the program that actually echo ESP8266 UART input/output to the TCP port 8080 (and the ESP8266 UART still work).


print("====Wicon, a LUA console over wifi.==========")
print("Author: openthings@163.com. copyright&GPL V2.")
print("Last modified 2014-11-19. V0.2")
print("Wicon Server starting ......")
function startServer()
   print("Wifi AP connected. Wicon IP:")
   print(wifi.sta.getip())
   sv=net.createServer(net.TCP, 180)
   sv:listen(8080,   function(conn)
      print("Wifi console connected.")
  
      function s_output(str)
         if (conn~=nil)    then
            conn:send(str)
         end
      end
      node.output(s_output,0)
      conn:on("receive", function(conn, pl)
         node.input(pl)
         if (conn==nil)    then
            print("conn is nil.")
         end
      end)
      conn:on("disconnection",function(conn)
         node.output(nil)
      end)
   end)  
   print("Wicon Server running at :8080")
   print("===Now,Using xcon_tcp logon and input LUA.====")
end
tmr.alarm(0, 1000, 1, function()
   if wifi.sta.getip()=="0.0.0.0" then
      print("Connect AP, Waiting...")
   else
      startServer()
      tmr.stop(0)
   end
end)





Thanks to Openthings for this code.



5. Download and install Etherlogic virtual serial port www.etherlogic.com
    This is the window program that actually created a virtual COM port on your window PC where the LUA loader will  talk to as if it is a local COM port.
 
6. Setup virtual serial port for “Connector” and “Bridge”. You can use any unused COM port name that is not currently assigned to any local ports on your PC.


Below is how to create the "connector" COM1



And below is where the TCP client connection is made. You need to find out your ESP8266's IP address for below step (use wifi.sta.getip() ).
 


 192.168.0.105 is my ESP8266 IP address, and 8080 is the port specified in the "telnet.lua".

 

 

7. Start the virtual serial port emulation (and now you can disconnect the USB serial port from the ESP if you want to).

 
8. Fire-up your favorite LUA loader and select the emulated serial port (ie COM1 as below):
  
 

If you want to use the other LUA loader like the ESPlorer, make sure that you select the "Dumb" mode.



That's it! Now you can start using the ESP8266 with the LUA console without any wire attached.

This workaround will be temporary measure until we have someone created a LUA loader that can talk directly to the TCP port.
 
Happy ESPing.






7 comments:

  1. Thanks Sir for this post , I tried two codes and worked perfectly
    I'm thinking of connecting Esp serial port to raspberry pi serial port to connect to pi console over wifi , can you help with this project

    ReplyDelete
  2. good work Omar - i got this working under Linux by using your example with socat as the virtual port tcp redirector

    ReplyDelete
  3. any tip to do it on a mac ?

    ReplyDelete
  4. For anyone interested, direct loading by TCP should now be possible with luatool by the author of ESPlorer, a Python script that could be easily integrated with your favorite text editor: https://github.com/4refr0nt/luatool

    The project provides a telnet_srv.lua similar to the one in your example for the same purposes.

    ReplyDelete
  5. I've created ESPresso - a visual tool for direct TCP/IP file management. It uses telnet.lua from NodeMCU and allows wireless file uploading, deleting, renaming, compiling and running on ESP.
    See:
    http://www.esp8266.com/viewtopic.php?f=22&t=11042
    for more details and binaries (Windows 32 & 64, Linux binaries will be available soon).

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. @Unknown2 August 2016 at 23:09
    Thank you for Espresso. I've tried it
    -It's a great & compact standalone exe for Windows (no python, java...)
    - Connection is not smooth, I must start exe, connect (no reply from NodeMcu), close exe, restart exe then connect again then link is established. Sometimes 3x, but I end up always having a wifi link
    - Uploading lua script into NodeMcu is very smooth (seems much faster than a wired 115200 serial link !)
    - Reading anything from NodeMcu is horribly slow. For example, displaying the NodeMCU files list (about only 30 bytes) takes several seconds.

    Apart from the last problem (NodeMCU-> PC too slow), it's quite a neat solution to play with lua scripts over wifi without a serial link.

    ReplyDelete