Close

The Code!

A project log for Wi-Fi christmas lights

Connecting some old fairy lights to an ESP8266 for absolutely no reason whatsoever

alex-huntAlex Hunt 12/17/2016 at 11:070 Comments

Here's the code I am currently running. The broad structure is:

  1. Create an open access point for users to connect to;
  2. Declare the variables needed to control the LED flashing speed etc.
  3. Create a table with the locations of various additional files needed. See this excellent tutorial here for how to serve up big files. I have copied most of this code but with a few small tweaks.
  4. Start the PWM on pin 1.
  5. Loop through all of the submitted data from the HTML form (stored in _GET in this example).
  6. Use the data to set the PWM value and alarm cycles.

The only slightly strange bit of the codes is the lines that follow this pattern:

partial_data = string.gsub(partial_data,"xxBVxx",ledPWM)

In the HTML files, each of the values for the form inputs is as follows:

<input class="slider-width" type="range" name="Brightness" min="0" max="1023" value="xxBVxx" onChange="form.submit()">
The nodemcu code goes through the HTML source and replaces xxBVxx with the correct PWM value. This ensures that the webpage served up has the sliders in the correct position.
--Close any servers already running
if srv then srv:close() srv=nil end

wifi.setmode(wifi.SOFTAP)
cfg={}
cfg.ssid="AlexsXmasLights"
wifi.ap.config(cfg)

--Variables for flashing lights
led1 = 1
ledPWM=500
flashSpeedOn=500
flashSpeedOff=500
glowOn="On"
glowSpeed=5
gpio.mode(led1, gpio.OUTPUT)
value = true
glow=true
scan=true

--Tables for file locations
local httpRequest={}
httpRequest["/"]="mainPage.html";
httpRequest["/index.html"]="mainPage.html";
local getContentType={};
getContentType["/"]="text/html";
getContentType["/index.htm"]="text/html";

local filePos=0;


--Start the PWM stuff at full
pwm.setup(led1,1000,ledPWM);
pwm.start(led1);

tmr.alarm(0, 500, 1, function ()
    if(glowSpeed>0)then
        if(glow==true)then
            ledPWM=ledPWM+1
        else
            ledPWM=ledPWM-1
        end
        if(ledPWM==1000)then
            glow=false
        end
        if(ledPWM==1)then
            glow=true
        end
        pwm.setduty(led1,ledPWM);
        tmr.interval(0, glowSpeed)
    else
        value = not value
        if(value==true) then
            pwm.setduty(led1,ledPWM);
            tmr.interval(0, flashSpeedOn)
        else
            pwm.setduty(led1,0);
            tmr.interval(0, flashSpeedOff)
        end
    end
end)

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on("receive", function(client,request)
        local buf = "";
        scan=false
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local _GET = {}
        if (vars ~= nil)then
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
                _GET[k] = v
            end
        end
      
        --Loop through info submitted
        for key,value in pairs(_GET) do 
            if(key=="FlashSpeedOn") then
                flashSpeedOn = tonumber(value);
                if(flashSpeedOn>0) then
                    tmr.start(0)
                else
                    tmr.stop(0)
                    pwm.setduty(led1,ledPWM);
                end
            end
            if(key=="glowSpeed") then
                glowSpeed = tonumber(value)
            end
            if(key=="FlashSpeedOff") then
                flashSpeedOff = tonumber(value);
                if(flashSpeedOff==0) then
                    tmr.stop(0)
                    pwm.setduty(led1,led1023);
                end
            end
            if(key=="Brightness") then
                ledPWM = tonumber(value);
            end
            if(key=="glowOn") then
                scan=true
                glow=true
            end
         end
        if getContentType[path] then
            requestFile=httpRequest[path];
            print("[Sending file "..requestFile.."]");            
            filePos=0;
            conn:send("HTTP/1.1 200 OK\r\nContent-Type: "..getContentType[path].."\r\n\r\n");            
        else
            print("[File "..path.." not found]");
            conn:send("HTTP/1.1 404 Not Found\r\n\r\n")
            conn:close();
            collectgarbage();
        end
    end)
    conn:on("sent",function(conn)
        local next1 = 0;
        if requestFile then
            if file.open(requestFile,r) then
                file.seek("set",filePos);
                local partial_data=file.read(512);
                if(partial_data~=nil) then
                    if (string.len(partial_data)==512) then
                        next1 = 1
                    end
                    partial_data = string.gsub(partial_data,"xxBVxx",ledPWM)
                    partial_data = string.gsub(partial_data,"xxFONVxx",flashSpeedOn)
                    partial_data = string.gsub(partial_data,"xxFOFFVxx",flashSpeedOff)
                    partial_data = string.gsub(partial_data,"xxGSxx",glowSpeed)
                    file.close();
                    if partial_data then
                        filePos=filePos+(512-string.len(partial_data))+#partial_data;
                        print("["..filePos.." bytes sent]");
                        conn:send(partial_data);
                        if (next1==1) then
                            return;
                        end
                    end
                end
            else
                print("[Error opening file"..requestFile.."]");
            end
        end
        print("[Connection closed]");
        conn:close();
        collectgarbage();
    end)
end)
    

Discussions