samedi 5 mars 2016

The purpose of this project is a simple "web messenger", including a weblink allowing you to enter a text remotely (from your smartphone or PC), and a receiver displaying any new message sent through the weblink.

You can easily modify this project to display any web based information you wanted (last tweets, weather,





0) What you need
   a) One ESP8266 (I used this one for debugging purposes but a cheaper one costs 2$) and an usb cable to power the messenger
   b) A 5V to 3.3 V converter. Cost : 0,4 $
   c) A 16x2 I2C LCD module.Cost 1,7 €
   d) A 3.3V - 5V logic converter (the LCD is 5V, the ESP 3.3V). Cost 0,28 € here
   d) The box is a business card plastic box (cost : zero)

You'll need a wifi internet access + a web hosting allowing PHP

1) The hardware

The hardware part is relatively simple.







 2) The software
    a) The web page (to be hosted on your php server)

msg_link.html : this is the page you'll call to send a new message

<html><body>
¨Please type your message
<form action="fetchmsg.php" method="post">
<table>
<tr><th>Auteur</th><td><input name=aut size=16 maxlength=16 type=text></td></th></tr>
<br>
<tr><th>Message</th><td><input name=msg size=144 maxlength=144 type=text></td></th></tr>
</table>
<br>
<input type=submit value="Send">
</form>
<br>

fetchmsg.php : this page is called by the msg_link.html page and stores your message in a "message.txt" file on your web host

<html><body><?php
$msg=$_POST['msg'];
$aut=$_POST['aut']."                ";
$counter_name = "message.txt";
$f = fopen($counter_name, "w");
$payld=substr($aut,0,16).substr(trim($msg),0,144);
fwrite($f,"<html><header><meta http-equiv='Cache-Control' content='no-cache, no-store, must-revalidate'/><meta http-equiv='Pragma' content='no-cache'/></header>BEGIN_MSG".$payld);
fclose($f);

echo "Message sent''".$payld."''/n";
?>

</body>
</html>

 b) On the nodemcu

init.lua 

NB: the delay is there to help you stop the program at startup if needed. Once you have debugged your code you can delete it

tmr.delay(2000000)
dofile("main.lua")

main.lua
main.lua is based on V Dronnikov's lcd control software (https://github.com/dvv/nodemcu-thingies/blob/master/lcd1602.lua).

ADR = 0x27
_ctl = 0x08
payload=""
oldpl=""
tries=100
w = function(b, mode)
    i2c.start(0)
    i2c.address(0, ADR, i2c.TRANSMITTER)
    bh = bit.band(b, 0xF0) + _ctl + mode
    bl = bit.lshift(bit.band(b, 0x0F), 4) + _ctl + mode
    i2c.write(0, bh + 4, bh , bl + 4, bl)
    i2c.stop(0)
end

  -- backlight on/off
light = function(on)
    _ctl = on and 0x08 or 0x00
    w(0x00, 0)
end

clear = function()
    w(0x01, 0)
end

  -- return command to set cursor at row/col
 _offsets = { [0] = 0x80, 0xC0, 0x94, 0xD4 } -- 20x4
  -- local _offsets = { [0] = 0x80, 0xC0, 0x90, 0xD0 } -- 16x4

locate = function(row, col)
    return col + _offsets[row]
end

define_char = function(index, bytes)
    w(0x40 + 8 * bit.band(index, 0x07), 0)
    for i = 1, #bytes do w(bytes[i], 1) end
end

put = function(...)
    for _, x in ipairs({...}) do
      -- number?
      if type(x) == "number" then
        -- direct command
        w(x, 0)
      -- string?
      elseif type(x) == "string" then
        -- treat as data
        for i = 1, #x do w(x:byte(i), 1) end
      end
      tmr.delay(800)
    end
end

  -- show a running string s at row. shift delay is _delay using timer,
  --     on completion spawn callback

  run = function(row, s, _delay, timer, callback)
    _delay = _delay or 40
    tmr.stop(timer)
    local i = 16
    local runner = function()
      -- TODO: optimize calculus?
      put(
          locate(row, i >= 0 and i or 0),
          (i >= 0 and s:sub(1, 16 - i) or s:sub(1 - i, 16 - i)),
          " "
        )
      if i == -#s then
        if type(callback) == "function" then
          tmr.stop(timer)
          callback()
        else
          i = 16
        end
      else
        i = i - 1
      end
    end
    tmr.alarm(timer, _delay, 1, runner)
end

domsg = function()
    if (tries ==0) then
    dofile("checkmsg.lua")
    if (payload ~= oldpl) then
tmr.alarm(1, 20000, 1, domsg)
    light(off)
    put(locate(0,0),string.sub(payload,1,16))
    run(1,string.sub(payload,17,-3),600,0)
    oldpl=payload
tmr.delay(100000)
    light(0)
tmr.delay(100000)
    light(off)
tmr.delay(100000)
    light(0)
else
put(locate(1,0),"Connection ok   ")
    end
     end
end


i2c.setup(0,3,4,i2c.SLOW)
w(0x33, 0)
w(0x32, 0)
w(0x28, 0)
w(0x0C, 0)
w(0x06, 0)
w(0x01, 0)
w(0x02, 0)

put(locate(0,0),"Esp messager")
put(locate(1,0),"Connecting wifi ")
dofile("connect.lua")
tmr.alarm(1, 2000, 1, domsg)

connect.lua

NB:You need to change Your_SSID and Your_Password according to you internet accesss

wifi.setmode(wifi.STATION)
wifi.sta.config("Your_SSID","Your_Passwod")
wifi.sta.connect()
tmr.alarm(0, 1000, 1, function()
   if wifi.sta.getip() == nil then
      print("Connecting to AP...\n")
      tries = tries - 1
      if (tries < 0) then
          tmr.stop(0)
      end
   else
      ip, nm, gw=wifi.sta.getip()
      print("IP Info: \nIP Address: ",ip)
      print("Netmask: ",nm)
      print("Gateway Addr: ",gw,'\n')
      print("Mac:"..wifi.sta.getmac())
 tries=0
      tmr.stop(0)
   end

end)

checkmsg.lua

NB: You need to change 215.555.55.5,  /~your/folder and host.your.com respectively to the IP adress of your web host (if you dont know it you'll find online lost of tools to obtain it based on the internet adress of you msg_link.html file), the full path of you msg_link.html page and your host name

conn=net.createConnection(net.TCP)
conn:on("receive", function(conn, pl)
i=string.find(pl,"BEGIN_MSG")
if (i ~= nil) then
payload=string.sub(pl,i+9)
print("Recu:"..payload)
end
    collectgarbage()
    end)

conn:on("sent",function(conn)
    end)
conn:connect(80,'215.555.55.5')
conn:send("GET /~your/folder/message.txt HTTP/1.1\r\n")
conn:send("Host: host.your.com\r\n")
conn:send("Accept: */*\r\n")
conn:send("User-Agent: Mozilla/4.0 (compatible; esp; Win NT 5)\r\n")
conn:send("\r\n")