Aktykuły które nie zmieściły się w żadnej kategorii

0102 /03
04Na stronie opiszę cześciowo język skryptowy LUA 5.1.4 w wydaniu na NodeMCU v3 jednocześnie opisując zastosowanie transmisji bezprzewodowej WiFi w oparciu o ESP8266 ESP12.06
070809

Przykłady były testowane na poniższym module ESP8266 czyli ESP-12.
Oprogramowanie z jakie korzystam to ESPlorer.


moduł NodeMCU v3 ESP8266

Następujące słowa kluczowe są zastrzeżone i nie mogą być używane jako nazwy:

and break do else elseif end false for function if in local nil not or repeat return then true until while

Następujące ciągi oznaczają inne tokeny:

+ - * / % ^ #
== ~= <= >= < > =
( ) { } [ ]
; : , . .. ...


Zawartość pliku operacje.lua
  1. function dodawanie_liczb()
  2. local a , b , c
  3.   a=10
  4.   b=11
  5.   c = a+b
  6.   print("Wynik ".. c.."\n")
  7. end
  8. function odejmowanie_liczb()
  9. local a , b , c
  10.   a=10
  11.   b=11
  12.   c = a-b
  13.   print("Wynik ".. c.."\n")
  14. end
  15. function mnozenie_liczb()
  16. local a , b , c
  17.   a=10
  18.   b=11
  19.   c = a*b
  20.   print("Wynik ".. c.."\n")
  21. end
  22. function dzielenie_liczb()
  23. local a , b , c
  24.   a=10
  25.   b=110
  26.   c = b/a
  27.   print("Wynik ".. c.."\n")
  28.   c = a/b
  29.   print("Wynik ".. c.."\n")    
  30. end
  31. z = 10 -- zmienna globalna
  32. function znaczenie_do_local()
  33.      print("z > "..z)
  34.      do                    
  35.        local z = z         
  36.        print("local z = z > "..z)
  37.        z = z+1
  38.        print("local z = z+1 > "..z)
  39.        do                  
  40.          local z = z+1     
  41.          print("local z = z+1 > "..z)
  42.        end
  43.        print("z > "..z)
  44.      end
  45.      print("z > "..z)
  46. end     
  47. function tablica_jednowymiarowa()
  48.     local t = {}     -- delaracja tablicy
  49.     print("tablica OK")
  50.     for i=1,100 do t[i] = i*2 end -- wpisanie wartości
  51.     print("t[9] > "..t[9])
  52.     print("t[90] > "..t[90])
  53. end    
  54. function operacje_matematyczne_na_stringach()
  55.     print("10" + 1)           --> 11
  56.     print("10 + 1")           --> 10 + 1
  57.     print("-5.3e-10"*"2")     --> -1.06e-09
  58.    -- print("hello" + 1)        -- błąd 
  59. end   
  60. function porownanie_stringow()
  61. print(tostring(10) == "10")   
  62. print(10 == "10")   
  63. print(10 .. "" == "10")       
  64. print(20 .. 10)   
  65. end
  66. function tworzenie_recordow()
  67.     a = {}; a.x = 50; a.y = 20
  68.     b = {x = 51, y = 21}
  69.     c = a
  70.     print(c.x);
  71.     print(c.y + b.y);   
  72.     -- {["x"]=0, ["y"]=0}
  73.     -- {"red", "green", "blue"}
  74.     -- {[1]="red", [2]="green", [3]="blue"}    
  75. end    
  76. function logiczne_operanty()
  77.     print(4 and 5)         --> 5
  78.     print(nil and 13)      --> nil
  79.     print(false and 13)    --> false
  80.     print(4 or 5)          --> 4
  81.     print(false or 5)      --> 5
  82.     print(not nil)      --> true
  83.     print(not false)    --> true
  84.     print(not 0)        --> false
  85.     print(not not nil)  --> false
  86.     print("(a and b) or c > zapisac mozna a ? b : c ")
  87. end    
  88. function dni_tygodnia()
  89. dzien = {"Poniedzialek", "Wtorek", "Sroda", "Czwartek",
  90.          "Piatek", "Sobota", "Niedziela"}
  91. print(dzien[7])
  92. end
  93. function ustalanie_wartosci_startowych()
  94.     a, b, c = 0
  95.     print("a,b,c = >".. a,b,c) 
  96.     a, b, c = 2, 3, 10
  97.     print("a,b,c = >".. a,b,c) 
  98.     print("deklaracje dla funkcji > a, b = f() ");
  99. end
Wywołanie powyższych funkcji.
  1. dofile('operacje.lua') -- ładowanie pliku
  2. print(" \n\r")
  3. dodawanie_liczb()
  4. odejmowanie_liczb()
  5. mnozenie_liczb()
  6. dzielenie_liczb()
  7. znaczenie_do_local()
  8. print(z)
  9. tablica_jednowymiarowa()
  10. operacje_matematyczne_na_stringach()
  11. print(" \n\r")
  12. porownanie_stringow()
  13. tworzenie_recordow()
  14. print("global >"..a.x)
  15. logiczne_operanty()
  16. dni_tygodnia()
  17. ustalanie_wartosci_startowych()
Łączenie różnych wartości w poleceniu print dokonujemy nie przez znak plusa tylko dajemy dwie kropki obok siebie.

Prosty serwer WWW
funkcja GoWiFi. Łączy się z ruterem domowej sieci WiFi.
Parametry wejściowe to nazwa sieci ( SSID ) oraz hasło do sieci, trzeci parametr to ostatni człon adresu IP, pod jakim ma być nasz serwer web.
Funkcja pobiera parametry z rutera i automatycznie składa nowy adres IP.
Odczytuje IP i do tego co odczyta dodaje ostatni człon xxx.xxx.xxx.myEndIP

Wywołanie funkcji mam w lini 27 kodu.
Od lini 29 zaczyna się obsługa serwera www. Na rządanie przeglądarki internetowej wysyłamy zawartość strony HTML.

  1. function GoWiFi(mySSID,myPASSWORD,myEndIP)
  2.   print("==> Ustawanie połaczenia WIFI")
  3.   wifi.setmode(wifi.STATION)
  4.   staIP={}
  5.   staIP.ssid = mySSID
  6.   staIP.pwd = myPASSWORD
  7.   staIP.save = false
  8.   wifi.sta.sethostname("LUA8266");
  9.   print("==> myHostName = LUA8266")
  10.   wifi.sta.config(staIP);
  11.   mySetingWiFi = tmr.create()
  12.   mySetingWiFi:register(1000, tmr.ALARM_AUTO, 
  13.    function() 
  14.       if wifi.sta.status()== 5 then
  15.          local a,b,c = wifi.sta.getip()
  16.          local o1,o2,o3,o4 = a:match("(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)" )
  17.          local nIP=o1.."."..o2.."."..o3.."."..tostring(myEndIP)
  18.          mySetingWiFi:stop();
  19.          wifi.sta.setip({ ip = nIP, netmask = b, gateway = c });
  20.          print("==> SetIP "..wifi.sta.getip());
  21.       else
  22.          print("no connection to SSID > "..mySSID) end
  23.    end)
  24.   mySetingWiFi:start()
  25. end  
  26. GoWiFi(" SSID naszego domowego WiFi"," hasło do naszej domowej sieci",199)
  27. srv=net.createServer(net.TCP)
  28.     srv:listen(80,function(conn)
  29.     conn:on("receive",function(conn,payload)
  30.     conn:send('<!DOCTYPE HTML>\n')
  31.     conn:send('<html>\n')
  32.     conn:send('<head><meta http-equiv="content-type" content="text/html; charset=UTF-8">\n')
  33.     conn:send('<meta name="viewport" content="width=device-width, initial-scale=1">')
  34.     conn:send('<title>ESP8266 Wifi</title>\n')
  35.     conn:send('</head>\n')
  36.     conn:send('<body>')
  37.     conn:send('<h2>Witam. IP Serwera '..wifi.sta.getip()..'</h2>\n')
  38.     conn:send('</body></html>\n')
  39.     conn:on("sent",function(conn) conn:close() end)
  40.     end)
  41. end)

Prosty serwer WWW
funkcja GoWiFi. Łączy się z ruterem domowej sieci WiFi.
Parametry wejściowe to nazwa sieci ( SSID ) oraz hasło do sieci, trzeci parametr to ostatni człon adresu IP, pod jakim ma być nasz serwer web.
Funkcja pobiera parametry z rutera i automatycznie składa nowy adres IP.
Odczytuje IP i do tego co odczyta dodaje ostatni człon xxx.xxx.xxx.myEndIP

Wywołanie funkcji mam w lini 27 kodu.
Od lini 29 zaczyna się obsługa serwera www. Na rządanie przeglądarki internetowej wysyłamy zawartość strony HTML.


Niektóre „znaki” (takie jak % ) mają specjalne znaczenie.
To są: ^ $ ( ) % . [ ] * + - ?

Jeśli chcesz użyć ich we wzorcu (jak same), musisz poprzedzić je symbolem%.
na przykład. %% pasuje do pojedynczego% (patrz także uwaga powyżej na temat „wyślij do skryptu”).
W praktyce można bezpiecznie umieścić% przed dowolnym znakiem innym niż alfanumeryczny. W razie wątpliwości umieść % przed znakiem specjalnym.


0102 /03
04Do obsługi I2C jest wymagane posiadanie odpowiednich modułów w jądrze LUA.
Tuż po starcie interpreter LUA informuje nas jakie ma wgrane moduły.

modules: adc,bit,file,gpio,http,i2c,mqtt,net,node,ow,pwm,spi,tmr,uart,websocket,wifi,wifi_monitor

Poniższe frgmenty kodu nie działają bez : bit oraz i2c

06
070809

moduł NodeMCU v3 ESP8266

Do modułu podłączyłem pamięć EEPROM. Oczywiście mija się to z celem, gdyż dane możemy trwale zapisywać w ESP. Zrobiłem to w celach prezentacji kodu obsługi I2C.

moduł NodeMCU v3 ESP8266

moduł NodeMCU v3 ESP8266

Poniżej jest umieszczony skrypt który szuka urządzeń na szynie I2C. Mówiąc krócej scaner I2C.

  1. scl=1 -- pin GPIO5 -- D1
  2. sda=2 -- pin GPIO4 -- D2
  3. -- inicjowanie i2c  SLOW FAST 
  4. i2c.setup(0,sda,scl,i2c.FAST)
  5. function scanI2C()
  6. -- podajemy adres 7 bitowy ostatni by nie jest podawany (adres > > 1) 
  7.   for i=0,127 do
  8.       -- begin-1
  9.       i2c.start(0)
  10.       if (i2c.address(0, i ,i2c.TRANSMITTER)==true) then
  11.          print("==> adres : "..i, "OK"); 
  12.          else
  13.          --print("==>"..i, "error"); 
  14.          end
  15.       i2c.stop(0)
  16.       end;    
  17. end;
  18. print(" ==>Start I2C")
  19. scanI2C();
  20. print(" ==>End I2C")

Poniżej jest umieszczony skrypt który skanuje szynę oraz robi zapis i odczyt danych z pamięci EEPROM po przez szynie I2C.

  1. scl = 1 -- pin GPIO5 -- D1
  2. sda = 2 -- pin GPIO4 -- D2
  3. chi2c = 0 -- które I2C
  4. -- inicjowanie i2c  SLOW FAST 
  5. i2c.setup(0,sda,scl,i2c.FAST)
  6. function _delay( ms ) -- opoznienie w milisekundach
  7.   tmr.delay ( ms * 1000)  -- tmr.delay liczy z dokladoscia do  1us
  8.   return result
  9. end  
  10. function scanI2C()
  11. -- podajemy adres 7 bitowy ostatni by nie jest podawany (adres > > 1) 
  12.   for i=0,127 do
  13.       -- begin-1
  14.       i2c.start(chi2c)
  15.       if (i2c.address(chi2c, i ,i2c.TRANSMITTER)==true) then
  16.          print("==> adres : "..i, "OK", "Hex",i*2 ); 
  17.          else
  18.          --print("==>"..i, "error"); 
  19.          end
  20.       i2c.stop(chi2c)
  21.       end;    
  22. end;
  23. function ReadEE( AddEE, A16 )
  24.     local c=0;
  25.     --local hByte , lByte  
  26.     --hByte = bit.rshift( bit.band(A16 , 0xFF00),8) 
  27.     --lByte = bit.band(A16 , 0xFF) 
  28.     --print("==> > ".. hByte ,lByte  ); 
  29.     i2c.start(chi2c);
  30.     i2c.address(chi2c, AddEE, i2c.TRANSMITTER);
  31.     i2c.write(chi2c, bit.rshift(bit.band(A16,0xFF00),8));
  32.     i2c.write(chi2c, bit.band(A16,0xFF));
  33.     i2c.stop(chi2c);
  34.     i2c.start(chi2c);
  35.     i2c.address(chi2c, AddEE, i2c.RECEIVER);
  36.     c = i2c.read(chi2c, 1);
  37.     i2c.stop(chi2c);
  38.     return c;
  39. end
  40.                 
  41. function WriteEE( AddEE, A16 , value)
  42.   local c=0
  43.     i2c.start(chi2c)
  44.     i2c.address(chi2c, AddEE, i2c.TRANSMITTER)
  45.     i2c.write(chi2c, bit.rshift(bit.band(A16,0xFF00),8)); -- starsza czesc adresu
  46.     i2c.write(chi2c, bit.band(A16,0xFF)); -- mlotrze czesc adresu 
  47.     c = i2c.write(chi2c, value)
  48.     i2c.stop(chi2c)
  49.     _delay(10); -- wymagany czas na zapisanie danych w pamieci eeprom
  50.     return c
  51. end
  52. function Czytaj()
  53. local i
  54.   for i=250,260 do
  55.     print(" ==> adres EE "..i,"dane "..string.byte(ReadEE( 80, i )))
  56.   end
  57. end; -- function
  58. print(" ==>Start I2C")
  59. scanI2C();
  60. print(" ==>End I2C")
  61. WriteEE(80, 0x00FF, 55 ); 
  62. WriteEE(80, 0x0100, 56 ); 
  63. WriteEE(80, 0x0101, 57 ); 
  64. Czytaj()

Efekt wykonanie powyższego skryptu.

moduł NodeMCU v3 ESP8266

Do szyny I2C był jeszcze podłączony PCF8574 o adresie 39. Pamięć ma adres 80.

  1. uint8_t ReadEE(uint8_t AddEE, uint16_t A16 )
  2. {
  3.    uint8_t ret;
  4.    twi_start();
  5.    twi_write(AddEE);
  6.    twi_write(A16 >> 8); // starsz część adresu w eepromie
  7.    twi_write(A16 & 0xFF); // młotsza część adresu w eepromie
  8.    twi_start();
  9.    twi_write(AddEE | 1);
  10.    ret=twi_read(0);
  11.    twi_stop();
  12.    return ret;
  13. }
  14. void WriteEE(uint8_t AddEE, uint16_t A16 ,uint8_t value)
  15. {
  16.    twi_start();
  17.    twi_write(AddEE);
  18.    twi_write(A16 >> 8);
  19.    twi_write(A16 & 0xFF);
  20.    twi_write(value);
  21.    twi_stop();
  22.    _delay_ms(10); // czas na zapis
  23. }

W poniższej siatce mamy wypisane funkcje z biblioteki bit

moduł NodeMCU v3 ESP8266

0102 /03
04Do obsługi SPI jest wymagane posiadanie odpowiednich modułów w jądrze LUA.
Tuż po starcie interpreter LUA informuje nas jakie ma wgrane moduły.

modules: adc,bit,file,gpio,http,i2c,mqtt,net,node,ow,pwm,spi,tmr,uart,websocket,wifi,wifi_monitor

Poniższe frgmenty kodu nie działają bez : bit oraz spi
06
070809

Układ ESP8266 posiada interfejs SPI ale jego użytkowanie jest utrudnione.
Wynika to z faktu że do tych pinów jest podłączona pamięć flash.

Natomiast w modułach ESP-12E wyprowadzone na zewnątrz piny GPIO 6,7,8,9,10 i 11 są zdublowane z pinami pamięci flash. GPIO9 jest podłączony do pinu HOLD, a GPIO10 jest podłączony do pinu WP (WriteProtect) układu pamięci flash. W moim module próba użycie GPIO9 oraz GPIO10 kończyła się koniecznością wgrywania pliku bin ponownie.

Na zagranicznych forach spotkałem się z opiniami że można korzystać z SPI również do swoich celów. Jak mi się to uda to opiszę jak to zrobić.


moduł NodeMCU v3 ESP8266

Poniżej umieściłem opis wyprowadzeń i spotykanych ich oznaczeń.
  1. -- D0   = GPIO-16;
  2. -- D1   = GPIO-5;
  3. -- D2   = GPIO-4;
  4. -- D3   = GPIO-0;
  5. -- D4   = GPIO-2;
  6. -- D5   = GPIO-14;
  7. -- D6   = GPIO-12;
  8. -- D7   = GPIO-13;
  9. -- D8   = GPIO-15;
  10. -- D9   = GPIO-3;
  11. -- D10  = GPIO-1;
  12. -- D11  = GPIO-9;
  13. -- D12  = GPIO-10;
  14. gpio16 = 0; -- ok
  15. gpio5  = 1; -- ok
  16. gpio4  = 2; -- ok
  17. gpio0  = 3; -- ok 
  18. gpio2  = 4; -- ok not led modułu
  19. gpio14 = 5; -- ok
  20. gpio12 = 6; -- ok 
  21. gpio13 = 7; -- ok
  22. gpio15 = 8; -- ok
  23. gpio3  = 9; -- RX UART
  24. gpio1  =10; -- TX UART
  25. -- gpio9  =11; -- flash
  26. -- gpio10 =12; -- flash

Poniżej przedstawiam programowy sposób pracy SPI na przykładnie wyświetlacz LCD 5110 opartego na układzie PCF

  1. -- podłaczenie wyświetlacza D0, D8, D4, D7, D5, BL do 3V, Vcc i Gnd
  2. pRST  = 0
  3. pCE   = 8
  4. pDC   = 4
  5. pDin  = 7
  6. pClk  = 5
  7. font5x7= {0,0,0,0,0,0,0,95,0,0,0,7,0,7,0,20,127,20,127,20,36,42,127,42,18,35,19,
  8.           8,100,98,54,73,85,34,80,0,5,3,0,0,0,28,34,65,0,0,65,34,28,0,20,8,62,8,
  9.           20,8,8,62,8,8,0,80,48,0,0,8,8,8,8,8,0,96,96,0,0,32,16,8,4,2,62,81,73,69,
  10.           62,0,66,127,64,0,66,97,81,73,70,33,65,69,75,49,24,20,18,127,16,39,69,69,
  11.           69,57,60,74,73,73,48,1,113,9,5,3,54,73,73,73,54,6,73,73,41,30,0,54,54,0,
  12.           0,0,86,54,0,0,8,20,34,65,0,20,20,20,20,20,0,65,34,20,8,2,1,81,9,6,50,73,
  13.           121,65,62,126,17,17,17,126,127,73,73,73,54,62,65,65,65,34,127,65,65,34,
  14.           28,127,73,73,73,65,127,9,9,9,1,62,65,73,73,122,127,8,8,8,127,0,65,127,65,
  15.           0,32,64,65,63,1,127,8,20,34,65,127,64,64,64,64,127,2,12,2,127,127,4,8,16,
  16.           127,62,65,65,65,62,127,9,9,9,6,62,65,81,33,94,127,9,25,41,70,70,73,73,73,
  17.           49,1,1,127,1,1,63,64,64,64,63,31,32,64,32,31,63,64,56,64,63,99,20,8,20,
  18.           99,7,8,112,8,7,97,81,73,69,67,0,127,65,65,0,2,4,8,16,32,0,65,65,127,0,4,
  19.           2,1,2,4,64,64,64,64,64,0,1,2,4,0,32,84,84,84,120,127,72,68,68,56,56,68,
  20.           68,68,32,56,68,68,72,127,56,84,84,84,24,8,126,9,1,2,12,82,82,82,62,127,8,
  21.           4,4,120,0,68,125,64,0,32,64,68,61,0,127,16,40,68,0,0,65,127,64,0,124,4,24,
  22.           4,120,124,8,4,4,120,56,68,68,68,56,124,20,20,20,8,8,20,20,24,124,124,8,4,
  23.           4,8,72,84,84,84,32,4,63,68,64,32,60,64,64,32,124,28,32,64,32,28,60,64,48,
  24.           64,60,68,40,16,40,68,12,80,80,80,60,68,100,84,76,68,0,8,54,65,0,0,0,127,
  25.           0,0,0,65,54,8,0,16,8,8,16,8,120,70,65,70,120}
  26. -- wysyłanie bitów 
  27. function LCDByte(d,cl, data)
  28.  for i=0,7 do
  29.      gpio.write(d, (bit.isset(data, 7-i) and 1 or 0) )
  30.      gpio.write(cl, gpio.HIGH)
  31.      tmr.delay(1)
  32.      gpio.write(cl, gpio.LOW)
  33.      end
  34. end
  35. -- przygotowanie do wysłanie bajtu
  36. function LCDWrite(dc,data)
  37.  gpio.write(pDC, dc)
  38.  gpio.write(pCE, gpio.LOW)
  39.  LCDByte(pDin, pClk, data)
  40.  gpio.write(pCE, gpio.HIGH)
  41. end
  42. -- wysyłanie znaku pojedyńczo 
  43. function LcdPrintChar(c)
  44.  LCDWrite(1, 0)
  45.  cc = 1+(string.byte(c) - 32)*5 -- oblicznie pozycji w tabeli 
  46.  for i=0,4 do
  47.      LCDWrite(1, font5x7[cc+i])
  48.      end
  49.  LCDWrite(1, 0)
  50. end
  51. -- wyałanie łańcuch znaków 
  52. function LcdPrintStr(str)
  53.  local i
  54.  for i = 1, #str do
  55.   a= str:sub(i,i)
  56.   --print(a)
  57.      LcdPrintChar(str:sub(i,i))
  58.  end
  59. end  
  60. -- pozycja na ekranie
  61. function LcdLocate(x,y)
  62.  LCDWrite(0,64+x) 
  63.  LCDWrite(0,128+y)
  64. end
  65. -- kasowanie ekranu 
  66. function LcdClear()
  67.   for i = 0,504 do
  68.       tmr.delay(1)
  69.       LCDWrite(1, 0)
  70.       end
  71. end
  72.  -- inicjowanie lce
  73. function initLCD()
  74.  gpio.mode(pCE,   gpio.OUTPUT)
  75.  gpio.mode(pRST,  gpio.OUTPUT)
  76.  gpio.mode(pDC,   gpio.OUTPUT)
  77.  gpio.mode(pDin,  gpio.OUTPUT)
  78.  gpio.mode(pClk,  gpio.OUTPUT)
  79.  gpio.write(pCE,  gpio.LOW)
  80.  gpio.write(pRST, gpio.LOW)
  81.  tmr.delay(1)
  82.  gpio.write(pRST, gpio.HIGH)
  83.  LCDWrite(0, 0x20)
  84.  LCDWrite(0, 0x0C)
  85.  LCDWrite(0, 0x21)
  86.  LCDWrite(0, 0x04)
  87.  LCDWrite(0, 0x14)
  88.  LCDWrite(0, 0xBF)
  89.  LCDWrite(0, 0x20)
  90.  print("init_LCD")
  91. end
  92.  
  93. function pisz() 
  94.  initLCD()
  95.  LcdClear()
  96.  LcdLocate(0,0) LcdPrintStr(" DASEJ (C)  ")
  97.  LcdLocate(1,0) LcdPrintStr(" ")
  98.  LcdLocate(2,0) LcdPrintStr("Test LCD5110")
  99.  LcdLocate(3,0) LcdPrintStr(" ")
  100.  LcdLocate(4,0) LcdPrintStr(" ")
  101.  LcdLocate(5,0) LcdPrintStr("www.dasej.pl")
  102. end
  103.  
  104. pisz()

Dasej (C) 2019 : 7306