sunnuntai 19. kesäkuuta 2016

verkko-ohjattu LED

Ekskursioni Lua-ohjelmointiin NodeMCU:lla edistyy. Kirjoitin lähiverkossa toimivan serverin, jonka kautta voi ohjata RGB-LEDiä puhelimella, tabletilla tai millä vain laitteella jossa on selain. Kytkentä ei voisi olla simppelimpi, sillä NodeMCU toimii 3.3 voltin jännitteellä, joka on tarpeeksi lähellä LEDin käyttöjännitettä. Kytkin yhteisen katodin maahan ja jokaisen värin anodin omaan ulostulopinniinsä. Pitempiaikaiseen installaatioon olisi ehkä silti syytä laittaa virtaa rajoittavat vastukset anodeihin, sillä valo on melko kirkas.


NodeMCU-firmwaren tehokkuus näkyy hyvin koodin pituudessa: koko ohjelma on vain noin sata riviä pitkä ja siitäkin suurimman osan muodostaa asiakaslaitteelle tarjoiltava HTML. Vastaavan serverin ohjelmointi pelkällä C:llä vaatisi jäätävän paljon enemmän koodia. Lua on kuitenkin rakennettu C:n päälle ja tukee tarvittaessa C-kielen funktioita kun halutaan suorituskykyä.

Ohjelma avaa lähiverkkoon yksinkertaisen serverin, joka kuuntelee TCP-yhteyksiä portissa 80 ja lähettää asiakkaalle nettisivun joka sisältää punaisen, sinisen ja vihreän neliön, joita klikkaamalla lähetetään palvelimelle get-metodilla avain/arvopari (esim ?vari=PUNAINEN). Ohjelma tulkkaa avaimen ja arvon URL:n perästä saadessaan get-komennon, ja sytyttää halutun LEDin.

Alla oleva listaus toimii, mutta se on yksinkertaisempi mitä aluksi koodasin. Jostain syystä merkkijonoksi tallennettu bufferi ei voi olla suurempi kuin 1460 tavua, ja jouduin poistamaan HTML-koodista noin puolet. Tutkimukset aiheesta jatkuvat, sillä mitään tämän monimutkaisempaa ei niin minimaaliseen tilaan mahdu. Tuli mieleen ainakin koodin pätkiminen alle 1460 tavun paketteihin ja niiden lähettäminen asiakkaalle yksi kerrallaan, mutta toivoisin jotain vähemmän monimutkaista ratkaisua.




  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
-- Wifi-asetukset
wifi.setmode(wifi.STATION)
wifi.sta.config("SSID","salasana")
-- Tulosta IP
print(wifi.sta.getip())

-- Määritä LEDit
led1 = 1 -- Punainen
led2 = 3 -- Vihreä
led3 = 2 -- Sininen
gpio.mode(led1, gpio.OUTPUT)
gpio.mode(led2, gpio.OUTPUT)
gpio.mode(led3, gpio.OUTPUT)

-- Määritä serveri
srv=net.createServer(net.TCP) -- Luo serveri, protokolla TCP
srv:listen(80,function(conn) -- Kuuntele porttia 80 (HTTP)
    conn:on("receive", function(client,request)
        local buf = "";
        -- Etsi URL:n lopusta avain (vari) ja arvo (PUNAINEN,SININEN,VIHREA)
        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
            -- Sijoita avain ja arvo muuttujiin
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
                _GET[k] = v
            end
        end
        --Lisää HTML-sivu puskuriin
        buf = buf..[[
        <html>
<head>
    <style>
    body {
    background: #222;
    padding: 0;
    margin: 0;
    }
    #boksit {
        margin:auto;    
    }
    h1 {
        font-family:Arial;
        color: #fff;
        font-size: 4em;
    }
    .laatikko {
        width: 50vw;
        height: 50vw;
        float:left;
        clear: none;
        display: block;
        padding:0;
        margin: auto;
    }
    #punainen {
        background: #f00;
    }
    #sininen {
        background: #00f;
    }
    #vihrea {
        background: #0f0;
    }
    </style>  
</head>
<body>
    <h1>Awesome LED-serveri</h1>
    <div id="boksit">
        <a href=\"?vari=PUNAINEN\"><div id="punainen" class="laatikko"></div></a>
        <a href=\"?vari=SININEN\"><div id="sininen" class="laatikko"></div></a>
        <a href=\"?vari=VIHREA\"><div id="vihrea" class="laatikko"></div></a>
    </div>
</body>
</html>]];

        -- Sytytä oikean värinen valo
        local _on,_off = "",""
        if(_GET.vari == "PUNAINEN")then
            gpio.write(led1, gpio.HIGH);
            gpio.write(led2, gpio.LOW);
            gpio.write(led3, gpio.LOW);
        elseif(_GET.vari == "SININEN")then
            gpio.write(led1, gpio.LOW);
            gpio.write(led2, gpio.LOW);
            gpio.write(led3, gpio.HIGH);
        elseif(_GET.vari == "VIHREA")then
            gpio.write(led1, gpio.LOW);
            gpio.write(led2, gpio.HIGH);
            gpio.write(led3, gpio.LOW);
        end
        -- Lähetä puskuri selaimelle
        client:send(buf);
        -- Sulje yhteys
        client:close();
        -- Poista väliaikaiset muuttujat
        collectgarbage();
    end)
end)

Ei kommentteja:

Lähetä kommentti