21 mai 2016

mini DX Cluster cu ESP8266 ( partea 2 )

Si experimentele continua…
      In prima parte solutia pe care am gasit-o la realizarea proiectului consta in crearea unui client TCP care se conecta la DX Cluster ( DXC ) si apoi crearea unui server TCP care gestiona conectarile clientilor la acesta. Transferul datelor, a spoturilor in sine, se facea odata la 100 msec cu ajutorul unui timer. Solutia aceasta nu mi-a placut deloc in sine, deoarece mi se parea corect ca trimiterea spoturilor catre clientul serverului, trebuia sa se faca ‘on event’, adica in momentul receptionarii unui spot. Plecind de la aceasta dorinta am gasit solutia optima, si probabil cea mai corecta. Mai intii creez serverul TCP, serverul care va gestiona conectarea clientilor catre DXC si il pun in asteptarea unui viitor client. Cind un client se conecteaza la server, creez o conexiune TCP si ma conectez la DXC, iar in momentul receptionarii spoturilor le trimit catre clientul serverului. Cind clientul se deconecteaza, conexiunea TCP cu DXC se inchide, serverul revenind dinou in starea de asteptare.  Aceasta solutie functioneaza foarte bine si astfel nu voi pierde niciun spot receptionat, iar serverul va va fi ocupat decit pe durata conectarii clientului sau.
      Pe timpul experimentelor am constatat si alte evenimente paralele cu aplicatia, evenimente nedorite. Citeva dintre acestea au fost: intreruperea conexiunii de internet dintre routerul meu si provider sau intreruperea conexiunii wireless. Deoarece in programul scris de mine nu au fost prevazute asemenea momente, modulul raminea fara conexiune si chiar daca totul revenea la normal, acesta nu se mai reconecta deloc.  Pentru rezolvarea acestor probleme, am setat un timer care odata la 10 secunde se verifica starea conexiunii wireless si daca se constata nereguli, modulul se restarteaza automat. Deasemenea, pentru a prevenii eventuale disfunctionalitati in conexiunea cu internetul, am prevazut ca odata pe ora, numai daca nu am un client conectat, modulul sa se restarteze automat, indiferent de starea conexiunilor wireless si internet in sine. Am simulat diferite momente, respectiv pierderea conexiunii wireless sau internet si apoi revenirea acestora. Modulul s-a comportat corect restabilind cu succes conexiunea.
      Am adaugat si unele briz-briz-uri, caci altfel nu se poate, conectarea unui client la server este semnalizata de un LED ce se gaseste pe modulul ESP8266.
      Deoarece pina voi rezolva problema uploadarii codului sursa arhivat pe blog, il voi publica aici, in continuare.
      Daca nu fac experimente si modulul este liber, puteti sa incercati functionarea conexiunii,  conectindu-va cu un program client TCP la adresa: http://ywar2.go.ro:9876
      Acum ma grabesc sa inchid, deoarece mi-a mai venit inca o idée…

---------------------------------------------------------------
--                         v1.5.7                            --
---------------------------------------------------------------
-- se verifica existenta conexiunii WiFi la fiecare 10 secunde
-- din ora in ora restartez automat modulul daca nu am niciun
-- client conectat
-- se afiseaza ip-ul userului conectat
-- conectarea utilizatorilor este semnalizata prin LED-ul WiFi
---------------------------------------------------------------

    -- setez id wireless si parola
    ssid = "YO7FWS"
    pass = "********"

    -- configurez wifi in client mode
    wifi.setmode(wifi.STATION)

    -- wifi config start
    wifi.sta.config(ssid,pass)
    
    -- wifi connect
    wifi.sta.connect()
    
    -- variabila folosita la contorizarea unei ore
    t = 0

    -- variabila care indica daca am un utilizator conectat
    -- true -> conectat, false -> deconectat
    conectat = false
    
    -- pinul la care este conectat ledul de pe modulul WiFi
    -- led ON -> client conectat, led OFF -> client deconectat
    pin = 4
    
    --  setez pinul ca iesire
    gpio.mode(pin, gpio.OUTPUT)
    
    -- verific daca mai sint conectat la reteaua WiFi
    -- daca sint deconectat atunci restart modul
    tmr.alarm(0, 10000, 1, function()
        if wifi.sta.status() == 1 then node.restart() end
        if wifi.sta.status() == 2 then node.restart() end
        if wifi.sta.status() == 3 then node.restart() end
        if wifi.sta.status() == 4 then node.restart() end

        -- cronometrez o ora
        t = t + 1

        -- cind a trecut o ora, daca nu am niciun client
        -- conectat, atunci restart modul
        -- 1[h]*60[min]*60[sec]*1000[msec]/10000[msec] = 360
        if (t >= 360) and (conectat == false) then node.restart() end
    end)

    -- creez un server viitor dx cluster
    server = net.createServer(net.TCP,28800)
    
    -- variabile care memoreaza spoturile ptr a fi retransmise
    spot = ''
    
    -- serverul sta in stand by pina ce se conecteaza un client 
    -- cind un client s-a conectat atunci...
    server:listen(9876, function(server)

        -- creez o conexiunea client la un dx cluster
        client = net.createConnection(net.TCP, false)
    
        -- ma conectez la dx clusterul lui N2YO
        client:connect(7300,"dxc.n2yo.net")
        
        -- debugg
        print('Client conectat')
        
        -- aprind ledul
        gpio.write(pin, gpio.LOW)

        -- indic client conectat
        conectat = true
        
        -- interoghez serverul despre IP
        ip,port = server:getpeer()
        
        -- trimit un mesaj de intimpinare
        server:send('Bine ati venit pe Dx Clusterul meu\nVizionare placuta !\nIP-ul dvs este '..ip..'\n')
        
        -- cind se receptioneaza un mesaj sau spot
        client:on("receive", function(sck, spot) 
        
            -- daca mesajul este de logare atunci transmit clusterului indicativul
            if spot == 'login: ' then 
                client:send("yo7fws\n") 
            else 
                -- altfel transmit clientului meu spotul  
                server:send(spot)
            end
            
            -- debugg
            --print(spot)
        end)
        
        -- cind clinetul se deconecteaza 
        server:on('disconnection', function(server)
        
            -- inchid conexiunea cu dx cluterul
            client:close()
            
            -- debugg
            print('Client deconectat') 


            -- indic client deconectat
            conectat = false

            -- resetez contorul de restart la 1 ora
            t = 0
            
            -- sting ledul
            gpio.write(pin, gpio.HIGH)
        end)
    end)
    
    
---------------------------------------------------------------
--                     YO7FWS - MAI 2016                     --
---------------------------------------------------------------

Pentru gasirea unor solutii pe timpul scrierii programului m-am mai inspirat si de aici:
https://nodemcu.readthedocs.io/en/dev/en/modules/gpio/


Constantin Badican  - YO7FWS
---  73's   YO7FWS  ---