Close

Firmware 2 & web page : enabling basic functionality

A project log for IuT voltmeter for a breadboard

Measure several voltages on a breadboard and display results on a smartphone for less than $10 for parts

AlexanderNAlexanderN 06/08/2017 at 21:080 Comments

This log is about configuring the ESP for operating as WiFi access point (straightforward), enabling TCP server and programming relevant callback to serve dynamic web pages (learned a few new to me useful things), adding JavaScript code to reload the web page from the server automatically every 300 ms (my first practical use of JavaScript) and adding a script to start all the things on power up (init.lua).

I opted for unencrypted access point but provided all the available callback functions for debugging purposes (at some stage I would like to stress test the ESP AP capabilities by conncecting/disconnecting various stations). The first line loads ADC initialisation and measurement code discussed before

dofile("ads_module.lua")

-- wifi section - acess point, unencrypted with service callbacks

function wifi_conn(T)
  print("\n\tAP - station connected".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID)
end
function wifi_disconn(T)
  print("\n\tAP - station disconnected".."\n\tMAC: "..T.MAC.."\n\tAID: "..T.AID)
end     
function wifi_probe(T)
  print("\n\tAP - station probed".."\n\tMAC: "..T.MAC.."\n\tRSSI: "..T.AID)
end
function blank()
    return
end 

wifi.setmode(wifi.STATIONAP)

cfg={}
cfg.ssid = "IuT_volt"
wifi.ap.config(cfg)

wifi.eventmon.register(wifi.eventmon.AP_STACONNECTED,wifi_conn) 
wifi.eventmon.register(wifi.eventmon.AP_STADISCONNECTED,wifi_disconn)
wifi.eventmon.register(wifi.eventmon.AP_PROBEREQRECVED,blank) 

tmr.delay(5000000) -- let it turn on first

print(wifi.ap.getip())
The following snippet creates and operates a TCP server via relevant callbacks
-- net section - server

html_st = 'p{text-align:center;font-size:60px}' ..
'var d=new Date();document.getElementById("demo").innerHTML=d.toLocaleTimeString();var myVar=setInterval(myTimer,300);' ..
'function myTimer(){window.location.reload()};'

srv = net.createServer(net.TCP)
srv:listen(80, function(conn)

    local response = {}
    conn:on("receive", function(conn, pl)
        --print("\r\n*** server received:\r\n"..pl.."\r\n*** end payload");
        response = html_st;
        response = response .. rez .. ' V';
        response = response .. '</p></body></html>';
        conn:send(response)
    end)
    conn:on("sent", function(conn) conn:close() end)
end)
--srv:close()
Dynamic web pages are created on the fly by displaying the ADC conversion rez along with the measurement units (V) on the page. The dynamic web page is prepared by concattenating the fixed header with the measured voltage and fixed footer. It reloads itself every 300 ms form the server by using JavaScript timer and reload method.

The HTML/Javascript content of the page was first tested in a browser locally

<!DOCTYPE HTML>
<html>
<head>
<style>
p {
  text-align: center;
  font-size: 60px;
}
</style>
</head>
<body>

<p id="demo"></p>

<script>

    var d=new Date();
    document.getElementById("demo").innerHTML=d.toLocaleTimeString();
    var myVar = setInterval(myTimer, 300);
    function myTimer() {
        window.location.reload();        
    }
          
</script>

<p>
<!-- Here will come the voltage from the ADC -->
</p>

</body>
</html>
that was later condensed by using a free online tool - HTML compressor for RAM savings. I considered placing the header and the footer into separate files, and reading these before serving the page but at this stage this potential RAM reduction was found unnecessary.

I added provision for printing the time stamp in order to test for how long the voltmeter could operate from the battery. This provision was found useful to find whether the client is operating properly or is waiting for the response that will never come as the request was either not received or processed properly by the server. Some stress tests showed that the ESP can serve one client quite reliably but connecting two clients frequently caused dropped connections form one of these, not necessarily the same each time. (An ESP server can operate up to 4 clients simultaneously but this is complicated for the IuT_voltmeter because the ESP operates in the access point mode and the frequency of the requests is 6 per seconds for the two clients).

Finally, the lua.init file was to switch on the on-module LED when the module is reset, and if the poushbutton, connected to pin D3 (as it is done for the button mini shield), is not found pressed after 3 s, the IoT voltmeter starts its operation

print("init.lua started ...")
print("Hold the button NOT to start the code")

pin_in=3
gpio.mode(pin_in, gpio.INPUT,gpio.PULL_UP)
pin_out=4
gpio.mode(pin_out, gpio.OUTPUT)
gpio.write(pin_out,gpio.LOW)

tmr.delay(3000000)

gpio.mode(pin_out, gpio.INPUT,gpio.FLOAT)

if gpio.read(pin_in)==0 then 
    print("\nDEFAULT MODULE DID NOT START - CANCELLED BY THE USER\n")
    gpio.write(pin_out,gpio.HIGH)
    return
else
    dofile('IuT_00.lua')
end

At this stage the hardware, firmware and web page became fully ready for testing.

Discussions