сайт для палких паяльників

Статьи о STM32 с примерами (SPL)
(на русском языке)

Популярность WiFi-модулей на базе ESP8266 настолько велика, что помимо прошивок для использования ESP8266 в качестве WiFi-модуля под управлением внешнего микроконтроллера, существует масса прошивок для использования его и как микроконтроллера с разными целевыми назначениями, в том числе и в сфере интернет вещей. В этом цикле статей мы будем изучать возможности ESP8266 с прошивкой NodeMCU и изучим скриптовый язык LUA.

Что такое ESP8266?

ESP8266 – это микроконтроллер с WiFi интерфейсом. Его можно использовать как WiFi модуль, и как микроконтроллер.

Плюсы ESP8266: WiFi интерфейс, 32-разрядное ядро с достаточной производительностью, низкая цена.
Минусы: По сравнению с другими 32-разрядными микроконтроллерами периферия не вызывает восхищения.

ESP8266 идеально подходит для домашних проектов, интернета вещей. ESP8266 программируется через последовательный порт UART, поэтому для его прошивки не требуется специального программатора. Особенность этого микроконтроллера в том, что он может выполнять программу, расположенную на внешней Flash памяти. Это позволяет производителю “наращивать” объем Флеша, что также является плюсом.

На базе ESP8266 выпускаются разные модули:

ESP-01
ESP-02
ESP-03
ESP-04
ESP-05
ESP-06
ESP-07
ESP-08
ESP-09
ESP-10
ESP-11
ESP-12S
ESP-12E
ESP-12F

Существует различные версии плат с уже запаянными модулями ESP8266, стабилизаторами напряжения, микросхемой для обеспечения работы последовательного порта UART через USB и разведенными на гребенку выводами, кнопками и тому подобное. Для работы с такими платами достаточно подключить их к USB порту компьютера. Никакого дополнительного оборудования не требуется. Это очень удобно. Одна из таких плат – NodeMCU. В примерах я буду использовать плату NodeMCU с модулем ESP-12F. Но, Вы вполне можете взять модуль, скажем ESP-01, подключить к нему UART-USB переходник и работать с ним аналогичным образом. У ESP-01 будет меньше памяти и меньше выводов, которые можно задействовать, но в остальном работа с ним аналогичная.

Что такое NodeMCU?

NodeMCU — открытый бесплатный проект на основе скриптового языка Lua. Прошивка достаточно мощная и позволяет очень быстро реализовывать различные типовые проекты. Например, сегодня, в качестве знакомства, мы сделаем WiFi розетку с управлением с мобильного телефона и с  Web-интерфейсом. Прошивка умеет исполнять Lua-скрипты как из последовательного UART порта (аналогично AT-командам) так и из внутренней flash памяти (выполняя скрипты). Lua скрипты сохраняются во Flash во внутренней файловой системе. Файловая система плоская, упрощенная. Т.е. без подкаталогов. Тем не менее – это круто. Не стоит забывать, что ESP8266 – это всего лишь микроконтроллер. Из скриптов так же можно получить доступ к файлам, читать и сохранять различную информацию. NodeMCU модульная. Что с одной стороны позволяет наращивать функционал, а с другой собрать прошивку только из требуемых модулей, не расходуя понапрасну память.

NodeMCU работает с протоколами обмена данными – HTTP, MQTT, JSON, CoAP.
Поддерживаются различные датчики –
акселерометры ADXL345,
магнитометры  HMC5883L,
гироскопы L3G4200D,
датчики температуры и влажности AM2320, DHT11, DHT21, DHT22, DHT33, DHT44
датчики температуры, влажности, атмосферного давления BME280,
датчики температуры, атмосферного давления BMP085,
множество дисплеев работающих по шинам I2C, SPI. С возможностью работы с разными шрифтами.
TFT дисплеи ILI9163, ILI9341, PCF8833, SEPS225, SSD1331, SSD1351, ST7735,
умные светодиоды и LED контроллеры – WS2812, tm1829, WS2801, WS2812,
поддерживаются интерфейсы – 1-Wire, I2C, SPI, UART,

Также можно задействовать модуль шифрования, планировщик задач, часы реального времени, протокол синхронизации часов через интернет SNTP, таймеры, АЦП канал (один), проигрывать аудио файлы, формировать на выходах ШИМ-сигнал (до 6), использовать сокеты, есть поддержка FatFS, т.е можно подключать SD-карточки и так далее.

Подробная документация NodeMCU здесь: https://nodemcu.readthedocs.io/en/master/

Что такое язык Lua?

Lua – это интерпретируемый язык, который, как и большинство современных интерпретируемых языков, может хранить скомпилированные версии скриптов. Это позволяет увеличить скорость работы. Lua позиционируется как мультипарадигмовый. Он не сложный, и если Вы уже программировали на любом языке, то Lua Вы изучите очень быстро. Если Вы только начинаете программировать, тогда Lua удивит Вас своей доступностью для начинающих.

Есть некоторые особенности при работе с Lua на NodeMCU. В основном это связано с конечным объемом памяти микроконтроллера ESP8266. Нужно придерживаться простых правил и выдерживать стиль работы с Lua. Об этих правилах расскажу чуть позже. Если же сохранять такой же стиль, как и при написании программ на С, то у Вас не получиться ощутить всей мощи Lua и прошивки NodeMCU. Когда Вы начинаете писать на Lua, это увлекает, и Вы начинаете воплощать в жизнь все более объемные задачи. Вы теряете ощущение того, что вы работаете с микроконтроллером и невольно нагружаете задачами, которые не по плечу микроконтроллеру. Нужно помнить, что у ESP8266 ограниченные ресурсы и не следует его грузить задачами, которые под силу выполнить микрокомпьютерам или полноценным компьютерам.

Документация по LUA на русском языке: http://www.lua.ru/doc/
Изучаем LUA за 15 минут: http://tylerneylon.com/a/learn-lua/

Где скачать NodeMCU?

Конечно, можно скачать исходные коды NodeMCU (https://github.com/nodemcu/nodemcu-firmware/releases/) и скомпилировать с нужными параметрами. Но мы не будет так делать. Существует сайт https://nodemcu-build.com, на котором можно собрать NodeMCU с необходимыми Вам модулями. Вы просто отмечаете те модули, которые Вам нужно, указываете свой e-mail и нажимаете внизу кнопку “Start ysour build“. Сначала на указанный e-mail приходит письмо о том что сборка началась. А затем извещение об окончании и ссылки для скачивания integer и float версий. Если в своем проекте Вы не будете использовать вычисления с плавающей запятой, тогда качайте “integer“. Не стоит жадничать и включать те модули, которые Вы не собираетесь использовать. В любой момент можно собрать новую прошивку, добавив недостающий модуль. Для примеров я собрал NodeMCU с такими модулями:

Как залить NodeMCU на ESP8266?

Теперь, когда у нас есть файл прошивки NodeMCU, его нужно залить в ESP8266. Прежде всего, при подключении платы NodeMCU к компьютеру должен появиться виртуальный Com порт. Как правило, последние версии Windows установки драйверов не требуют. Ubuntu сразу распознает подключенное устройство.

Прошивка NodeMCU под Windows

Заходим по этой ссылке: https://github.com/nodemcu/nodemcu-flasher. И из папки Win32/Release (для 32-битной Windows), или из папки Win64/Release (для 64-битной Windows) качаем файл ESP8266Flasher.exe. Эта программа не требует установки. Просто запускаем ее. Переходим в закладку “Config“, нажимаем “шестеренку” чтобы выбрать файл прошивки.

Возвращаемся на закладку “Operation” указываем порт, и нажимаем кнопку “Flash“.

После нажатия “Flash” должны увидеть МАС-адреса и примерно такую картину.

Ждем пока прошивка завершиться. В нижнем углу должна появиться зеленая галочка.


После этого нужно выключить и снова включить ESP8266. Прошивка завершена.

Если после нажатия кнопки “Flash” процес прошивки не начался (не появились МАС-адреса), нажмите кнопку “reset” на плате и повторите попытку.

Прошивка NodeMCU под Ubuntu

Сначала установите esptool:

git clone https://github.com/themadinventor/esptool.git

Прошить командой:

sudo python esptool.py --port /dev/ttyUSB0 write_flash 0x00000 The_Path_To_The_NodeMCU_Firmware.bin

/Dev/ttyUSB0 – порт на котором висит ESP8266.
The_Path_To_The_NodeMCU_Firmware.bin – путь к файлу прошивки.

Кстати, esptool можно использовать и под Windows. esptool написан на Pyton, для работы под Windows нужно установить Pyton.

esptool пригодиться нам для заливки бинарных файлов на файловую систему NodeMCU. Можно заливать любые файлы, в том числе скрипты. Скрипты можно писать хоть в Notepad, но я предпочитаю ESPlorer.

ESPlorer, init.lua – пишем первый скрипт

Для написания и заливки скриптов будем использовать программу ESPlorer. Это кроссплатформенная программа написана на Java и так же не требует установки. Работает одинаково как под Windows так и под Ubuntu.

ESPlorer качаем здесь: http://esp8266.ru/esplorer-latest/?f=ESPlorer.zip

Распаковываем архив.

Под Windows запускаем файл ESPlorer.bat

Под Ubuntu:

sudo java-jar ESPlorer.jar

Примечание: далее описанна робота с ESPlorer v0.1. Внешний вид новых версий может иметь не принципиальные отличия.

Указываем порт и скорость 9600:

И нажимаем “Open“. Увидем следующще

У ESPlorer обнаружилась паршивая особенность. Он не всегда четко подключается к NodeMCU. Если попробовать послать любую команду (кнопкой Send) в консоли пролетает мусор вместо нормального ответа. Иногда после нескольких повторов все налаживается. Если Вас это беспокоит, попробуйте изменить скорость подключения на 115200.

Приступим к созданию первого скрипта на языке Lua. Скрипт с именем init.lua стартует автоматически после запуска NodeMCU. Создадим файл init.lua.

напечатаем всего одну строчку:

print("Yes it works!")

Сохраняем файл как init.lua. После сохранения файл выполниться и мы должны увидеть работу первого скрипта.

По умолчанию файл сохраняется и на диск компьютера и заливается на ESP8266.

Теперь о самой большой неприятности, которая есть у NodeMCU. При некоторых критических ошибках (это случается не так часто, но если случается, то запоминается на долго) NodeMCU может перезагружаться. И самое страшное, что может случиться – это циклическая перезагрузка. Это случается если допустить критическую ошибку в скрипте который стартует автоматически. NodeMCU стартует, выполняет “глючный” скрипт, нарывается на критическую ошибку и уходит в перезагрузку. И так до бесконечности.

Для того, чтобы обезопасить себя на этапе изучения NodeMCU, я использую описанный ниже прием. В стартовом скрипте init.lua запускаем таймер, который сработает только один раз и через указанное время (в данном случае через 5 секунд) выполнит процедуру запуска другого скрипта (в данном случае main.lua). Больше ничего в скрипте init.lua не делаем. Все операции выполняются в скрипте main.lua. Таким образом, если мы допустим ошибку в скрипте main.lua, и NodeMCU уйдет в циклическую перезагрузку, после перезагрузки у нас будет 5 секунд для того чтобы удалить или исправить “глючный” скрипт.

Текст init.lua:

print ( "Waiting ...")
tmr.register (0, 5000, tmr.ALARM_SINGLE, function (t) tmr.unregister (0); print ( "Starting ..."); dofile ( "main.lua") end)
tmr.start (0)

Кроме того, такой подход позволяет легко включать в автозагрузку любо нужный скрипт, достаточно в файле init.lua вместо main.lua указать имя другого скрипта. Это очень удобно, когда вы на одной плате тестируете несколько проектов или несколько версий скрипта.

Подключаемся к Wifi или создаем свою Wifi точку

Для подключения к WiFi создаем main.lua и пишем:

--WiFi Settup
wifi.setmode(wifi.STATION)
local cfg={}
cfg.ssid="MyWiFi"
cfg.pwd="MyWiFiPassword"
wifi.sta.config(cfg)
cfg = nil
collectgarbage()

После успешного подключения модуль получить IP адрес. Узнать его можно с помощью команды:

=wifi.sta.getip()

Если мы хотим, чтобы ESP8266 создал свою собственную WiFi точку:

--WiFi AP Settup
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="ESPWIFI"
cfg.pwd="1234567890"
wifi.ap.config(cfg)
cfg = nil
collectgarbage()

Примечание: WiFi точка не поднимется, если пароль короче 8 символов. По умолчанию IP адрес точки всегда 192.168.4.1

Его можно узнать командой:

=wifi.ap.getip()

Что такое collectgarbage()? Функция collectgarbage – это сборщик мусора. Ее следует вызывать в конце каждого скрипта. Обратите внимание, переменная cfg объявлена как local. Она будет доступна только в текущем скрипте. Если local убрать, то переменная cfg была бы глобальной и доступной в других скриптах.

GPIO. Мигаем светодиодом

Для управления реле (мы ведь собрались делать WiFi розетку) потребуется изучить работу с выводами GPIO. Пока попробуем использовать GPIO вывод в качестве выхода и устанавливать высокий и низкий уровень сигнала. Для наглядности подключим светодиод как показано на схеме.

my_pin_nummber = 1
-- Устанавливаем режим работы как выход
gpio.mode (my_pin_nummber, gpio.OUTPUT)
-- Задать высокий уровень
gpio.write (my_pin_nummber, gpio.HIGH)
-- Задать низкий уровень
gpio.write (my_pin_nummber, gpio.LOW)
-- Мигаем светодиодом 10 раз
gpio.serout (1, gpio.HIGH, {+990000,990000}, 10, 1)

Нумерация выводов:

IO indexESP8266 pin
0GPIO16
1GPIO5
2GPIO4
3GPIO0
4GPIO2
5GPIO14
6GPIO12
7GPIO13
8GPIO15
9GPIO3
10GPIO1
11GPIO9
12GPIO10

D0(GPIO16) can only be used as gpio read/write. No support for open-drain/interrupt/pwm/i2c/ow

ESP-12F

Плата NodeMCU

Примечание: Существует несколько версий плат Nodemcu. Распиновка Вашей платы может отличаться.

Websocket

Теперь сделаем сервер, который будет работать на указанном порту (пусть будет 333). Затем мы с помощью терминальной программы подключимся к нашему серверу, указав его IP и порт. И потом будем обмениваться данными.

Скрипт main.lua:

--WiFi AP Settup
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="ESPTEST"
cfg.pwd="1234567890"
wifi.ap.config(cfg)

--Create Server
sv=net.createServer(net.TCP)

function receiver(sck, data)    
  -- Print received data
  print(data)
  -- Send reply
  sck:send("Recived: "..data)
end

if sv then
  sv:listen(333, function(conn)
    conn:on("receive", receiver)
    conn:send("Hello!")
  end)
end

print("Started.")

Теперь наш скрипт поднимает Wi-Fi точку, создает сервер, который на порту 333 ожидает подключения. В момент подключения сервер отправит клиенту строку “Hello!“, а приняв от клиента данные, вернет ему строку “Recived: ” и дальше все, что он принял.

Теперь мы можем подключиться мобильным телефоном к Wi-Fi точке ESP8266. В принципе, создавать точку не обязательно. Вы можете переписать скрипт и сделать так, чтобы ESP8266 подключался к Вашей WiFi сети. Тогда Вам нужно узнать его IP и далее использовать его вместо 192.168.4.1, который далее используется в примерах.

Но нам еще нужна терминальная программа для подключения на IP адрес ESP8266 (192.168.4.1) и указанный порт (333). На обычном компьютере можно установить PuTTY. Для мобильных телефонов под Android я использую JuiceSSH.

Передача данных с мобильного телефона с помощью JuiceSSH

Установим JuiceSSH и создадим подключение на IP 192.168.4.1, порт 333.

Сразу после подключения должны увидеть такую картину:

Отправим ему радостное “Yes” и должны получить ответ.

Теперь доработаем скрипт так, чтобы получив “1”, он включал светодиод, а получив “0” – выключал.

Доработанная версия скрипта main.lua:

--WiFi AP Settup
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="ESPTEST"
cfg.pwd="1234567890"
wifi.ap.config(cfg)

--Set Pin mode
my_pin_nummber = 1
gpio.mode(my_pin_nummber, gpio.OUTPUT)

--Create Server
sv=net.createServer(net.TCP)

function receiver(sck, data)
     if string.sub (data, 0, 1) == "1" then
          gpio.write(my_pin_nummber, gpio.HIGH)
     else
          if string.sub (data, 0, 1) == "0" then
               gpio.write(my_pin_nummber, gpio.LOW)
          end
     end
     
     print(data)
end

if sv then
  sv:listen(333, function(conn)
    conn:on("receive", receiver)
    conn:send("Hello!")
  end)
end

print("Started.")

Попробуйте отправить “1” и “0”. Светодиод должен загораться и гаснуть.

Разумеется, управлять светодиодом через терминальную программу очень неудобно. Но в дальнейшем именно терминальная программа позволит Вам отлаживать более сложные проекты.

Работа с RoboRemoFree

В Интернете можно найти массу программ под Android, которые помогают организовать интерфейс для такого рода задач, не прибегая к программированию. Я покажу, как это можно сделать с помощью RoboRemoFree.

Устанавливаем и запускаем RoboRemoFree

Создаем подключение к серверу. Желательно чтобы мобильный телефон/планшет был подключен к той-же WiFi сети, где находиться сервер. В данном случае наш ESP8266. Заходим в “Menu”, выбираем пункт “connect”

Выбираем тип подключения “Internet (TCP)”

Указываем IP и порт

Далее в меню выбираем пункт “interface”

Выбираем интерфейс. Программа позволяет создавать несколько интерфейсов с разными органами управления.

Затем переходим в режим редактирования интерфейса

Нажимаем на свободном пространстве и выбираем, что мы хотим установить. Мы будем использовать кнопки. Выбираем “button”

После чего на интерфейс будет установлена кнопка. Ее можно перемещать и изменять ее размеры.

Чтобы изменить название на кнопке, нужно нажать не ней и выбрать пункт “Set text”

Затем укажем еще один параметр – “set press action”. Зададим “1”. При нажатии кнопки будет отправлена указанная строка по созданному нами подключению. Т.е. Наш ESP8266 получит символ “1” и включит светодиод.

Аналогично создадим кнопку “Off” и установим set press action “0”.

Наш интерфейс готов. Выходим из режима редактирования, выполнив пункт меню “don’t edit ui”.

Если подключение к серверу (ESP8266) было успешным, можно пользоваться. По нажатию кнопки “On” светодиод должен загореться, по нажатию кнопки “Off” светодиод должен погаснуть.

Web интерфейс

Есть и другой путь – можно сделать Web интерфейс и управлять светодиодом еще и через браузер.

Тот же скрипт + Web интерфейс:

--WiFi AP Settup
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="ESPTEST"
cfg.pwd="1234567890"
wifi.ap.config(cfg)

--Set Pin mode
my_pin_nummber = 1
gpio.mode(my_pin_nummber, gpio.OUTPUT)

--Create Server
sv=net.createServer(net.TCP)

function receiver(sck, data)
     if string.sub (data, 0, 1) == "1" then
          gpio.write(my_pin_nummber, gpio.HIGH)
     else
          if string.sub (data, 0, 1) == "0" then
               gpio.write(my_pin_nummber, gpio.LOW)
          end
     end
     print(data)
end

if sv then
  sv:listen(333, function(conn)
    conn:on("receive", receiver)
    conn:send("Hello!")
  end)
end

--Create HTTP Server
http=net.createServer(net.TCP)

function receive_http(sck, data)    
  local request = string.match(data,"([^\r,\n]*)[\r,\n]",1)
  if request == 'GET /on HTTP/1.1' then
    gpio.write(my_pin_nummber, gpio.HIGH)
  end
  if request == 'GET /off HTTP/1.1' then
    gpio.write(my_pin_nummber, gpio.LOW)
  end  

  sck:on("sent", function(sck) sck:close() end)
  
  local response = "HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n"..
     "<html><title>NodeMCU on ESP8266</title><body>"..
     "<h1>NodeMCU on ESP8266</h1>"..
     "<hr>"..
     "<a href=\"on\">On</a> <a href=\"off\">Off</a>"..
     "</body></html>"
  sck:send(response)
end

if http then
  http:listen(80, function(conn)
    conn:on("receive", receive_http)
  end)
end

print("Started.")

Небольшое пояснение как работает web-сервер вообще, и наш скрипт в частности. Стандартный порт для web-сервера – 80. Т.е. когда Вы в браузере набираете http://192.168.4.1/, то браузер подключается к серверу (192.168.4.1) на порт 80 и отправляет запрос. Запрос выглядит примерно так:

GET / HTTP / 1.1
Host: 192.168.4.1
User-Agent: Mozilla / 5.0 (Windows NT 5.1; rv: 2.0.1) Gecko / 20100101 Firefox
Accept: text / html, application / xhtml + xml, application / xml; q = 0.9, * / *; q = 0.8
Accept-Language: ru-RU, ru; q = 0.8, en-US; q = 0.5, en; q = 0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1

Для нас представляет интерес первая строка запроса: “GET / HTTP/1.1“. В ней указан URL. Если в браузере набрать http://192.168.4.1/on , тогда в первой строке запроса будет “GET /on HTTP/1.1“. А если в браузере набрать http://192.168.4.1/off тогда будет “GET /off HTTP/1.1“. Именно эту строку и анализирует скрипт и в зависимости от полученного URL включает или отключает светодиод.

Далее скрипт отправляет html страничку. Но после отправки нужно разорвать подключение. Поскольку отправка занимает некоторое время, а ждать окончания отправки технически глупо, на событие “sent” (отправлено) подключим функцию со строкой sck:close(). Это делается в строке: sck:on(“sent”, function(sck) sck:close() end). После чего выполняется отправка html страницы sck:send(response). Скрипт продолжает работу. Когда ответ будет полностью отправлен, сработает sck:close().

Страницы большого размера таким образом отправить не получится. Весомое содержимое нужно отправлять кусками. Подробнее об этом будет рассказано в другой статье.

Подключаем реле с нагрузкой

Внимание! Напряжение более 40 Вольт опасно для жизни человека! Будьте внимательны и аккуратны, собирая схему и подключая бытовые приборы. Не прикасайтесь к токоведущим частям.

А теперь вместо светодиода подключим модуль реле, а в качестве нагрузки – скажем лампу, обогреватель, компрессор для аквариума, вентилятор и т.п.

При подключении реле могут быть нюансы. Если блок реле с оптической развязкой (с оптопарой), то, скорее всего, Вам ничего переделывать не придется. Если блок реле без оптической развязки, как у меня, тогда придется переделать работу с GPIO, поскольку во первых реле включается низким уровнем, а не высоким, а во вторых высокий уровень ESP8266 – это 3.3В, для 5-ти вольтового блока реле этого не достаточно, поэтому мне пришлось настроить выход как OPENDRAIN, после чего все заработало как надо.

Финальная версия скрипта выглядит так:

--WiFi AP Settup
wifi.setmode(wifi.STATIONAP)
cfg={}
cfg.ssid="ESPTEST"
cfg.pwd="1234567890"
wifi.ap.config(cfg)

--Set Pin mode
my_pin_nummber = 1
--gpio.mode(my_pin_nummber, gpio.OUTPUT)
gpio.mode(my_pin_nummber, gpio.OPENDRAIN)

--Create Server
sv=net.createServer(net.TCP)

function receiver(sck, data)
     if string.sub (data, 0, 1) == "1" then
          --gpio.write(my_pin_nummber, gpio.HIGH)
          gpio.write(my_pin_nummber, gpio.LOW)
     else
          if string.sub (data, 0, 1) == "0" then
               --gpio.write(my_pin_nummber, gpio.LOW)
               gpio.write(my_pin_nummber, gpio.HIGH)
          end
     end
     print(data)
end

if sv then
  sv:listen(333, function(conn)
    conn:on("receive", receiver)
    conn:send("Hello!")
  end)
end

--Create HTTP Server
http=net.createServer(net.TCP)

function receive_http(sck, data)    
  print(data)
  
  local request = string.match(data,"([^\r,\n]*)[\r,\n]",1)
  if request == 'GET /on HTTP/1.1' then
    --gpio.write(my_pin_nummber, gpio.HIGH)
    gpio.write(my_pin_nummber, gpio.LOW)
  end
  if request == 'GET /off HTTP/1.1' then
    --gpio.write(my_pin_nummber, gpio.LOW)
    gpio.write(my_pin_nummber, gpio.HIGH)
  end  

  sck:on("sent", function(sck) sck:close() collectgarbage() end)
  
  local response = "HTTP/1.0 200 OK\r\nServer: NodeMCU on ESP8266\r\nContent-Type: text/html\r\n\r\n"..
     "<html><title>NodeMCU on ESP8266</title><body>"..
     "<h1>NodeMCU on ESP8266</h1>"..
     "<hr>"..
     "<a href=\"on\">On</a> <a href=\"off\">Off</a>"..
     "</body></html>"
  sck:send(response)
end

if http then
  http:listen(80, function(conn)
    conn:on("receive", receive_http)
  end)
end

print("Started.")

Теперь мы можем включать и выключать “розетку” с мобильного телефона с помощью программы RoboRemoFree или с помощью браузера. Разумеется, с обычного компьютера через браузер тоже можно управлять.

Все это хорошо, но что дальше? Если у нас будет 5, 10, 20 подобных устройств? Как их объединить, чтобы не надо было подключаться к каждому устройству отдельно. Для этого существует протокол MQTT, но это будет отдельная тема. А пока мы изучим возможности ESP8266 и NodeMCU.

Некоторые правила работы с языком Lua на NodeMCU

1. Не пишите длинные скрипты. Размер памяти ESP8266 не бесконечен. Разбивайте программу на функциональные модули и делайте их в виде отдельных скриптов, запуская их с помощью dofile(). Например, код подключения к Wifi:

--WiFi Settup
wifi.setmode (wifi.STATION)
local cfg = {}
cfg.ssid = "MyWiFi"
cfg.pwd = "MyWiFiPassword"
wifi.sta.config (cfg)
cfg = nil
collectgarbage ()

можно вынести в отдельный скрипт “wifi.lua” и выполнить его из основного скрипта командой dofile(“wifi.lua”).

2. Переменные, которые используются только в текущем скрипте объявляйте как local. В конце скрипта, когда переменная уже не нужна, присваивайте ей значение nil и явно вызывайте сборщик мусора collectgarbage()

Желаю успехов.

Смотри также:

23 комментария: ESP8266 NodeMCU Прошивка. Делаем WiFi розетку

  • Павел говорить:

    Здравствуйте! У Вас интересные статьи мне как очень начинающему они были сильно полезны!! Спасибо Вам огромное! Но так как я очень начинающий у меня возник затык. Не могу сообразить, как сделать, так что бы управлять несколькими портами gpio, если не трудно подскажите, пожалуйста. И еще при перезагрузке платы у меня ничего не сохраняется, как залить код, что бы он сохранялся? Спасибо Вам еще раз большое!!!

  • Ravil Buraev говорить:

    Здравствуйте! У Вас интересные статьи мне как начинающему пользоваться ESP8266 они были полезны! Спасибо Вам огромное! Ждем продолжения !

  • ElPrg говорить:

    Отличная полноценная , статья. Спасибо! Хотел спросить, а как со стабильностью работы даного модуля ??

    • andre говорить:

      У меня лично с этим модулем никаких проблем не было. Несколько лет назад у меня было полное разочарование в модуле ESP-01, но ESP-12 – это совсем другое дело.

  • Максим говорить:

    Расскажите пожалуйста про протокол MQTT, хочу понять как реализовать брокер и связать всё в единую систему.
    А так же сделайте пожалуйста пост, о том, как не прошивать адрес wifi сети, а вводить вручную через интерфейс, что важно если устройства нужно переносить и перенастраивать на другую сеть.

    • andre говорить:

      Статья про MQTT будет позже, в самом конце цикла статей про NodeMCU. Про то как сохранять настройки через web-интерфейс можно подсмотреть в этом проекте: http://www.avislab.com/blog/gps-tracker-esp8266_ru/ Подробно про web тоже будет статья позже.

      Если Хотите настраивать устройство через UART, посмотрите статью http://www.avislab.com/blog/esp8266-nodemcu-uart_ru/ там описан вариант ввода параметров. Останется только их сохранить и использовать в скриптах.

      • Максим говорить:

        Спасибо, за оперативный ответ.
        У меня еще есть ряд вопросов, я задам их Вам по почте.

  • Руслан говорить:

    Здравствуйте не могу запустить пример, тот в котором светодиод загорается при отправке 0 і 1, пишет

    main.lua:28: out of memory
    stack traceback:
    [C]: in function ‘listen’
    main.lua:28: in main chunk
    [C]: in function ‘dofile’
    stdin:1: in main chunk
    Может подскажите чтото. Спасибо

    • andre говорить:

      Такое может быть если скрипт дважды запустить. listener уже занял порт и повторный вызов функции sv:listen(333, function(conn) вызовит ошибку. Приходиться каждый раз ресетить модуль.

  • Руслан говорить:

    или такое пишет
    > =node.info()
    2 1 0 63783 1458400 4096 2 40000000
    > dofile(“init.lua”)
    Waiting …
    > Starting …
    PANIC: unprotected error in call to Lua API (main.lua:28: out of memory)
    �{�z�J8���0�

  • Руслан говорить:

    Здравствуйте, а где описано как отправить большую страницу, Сейчас отправляется гдето 400 символов, максимум 10 переменных, больше не хочет слать, Пробовал разбивать на части толку нет, видимо оперативки не хватает.

    • andre говорить:

      Добрый день. Планируется статья по созданию Web интерфейсо на ESP. В ней будут описаны все тонкости и проблемы с которыми я столкнулся и методы их решения. Вы абсолютно правы, главная проблема – конечный объем памяти ESP. Статью смогу закончить примерно через месяц, не раньше.

  • Алекс говорить:

    Очень хорошая статья! Узнал для себя кое что новое. Но это если б так легко было знать и писать эти каляки маляки под названием программирование. Ну никак не дается(( Если не сложно помогите с кодом: ESP должен быть связующим звеном между смартфоном, который подключаешь к точке доступа из ESP. На смартфоне программа которая шлет и получает АТ команды по wi-fi, на RX TX сидит устройство, которое делает тоже самое, получает и шлет АТ команды, все должно пересылаться в оба конца по заданному IP и порту. и скорости порта. Вроде все. Заранее спасибо.

    • andre говорить:

      Добрый день. Задумку понял. Постараюсь в ближайшее время набросать пример.

        • andre говорить:

          Если вкратце, то вот:

          –Ports setting
          TCP_PORT = 333
          uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)

          –WiFi Settup
          wifi.setmode(wifi.STATION)
          local cfg={}
          cfg.ssid=”HomeWiFi”
          cfg.pwd=”WiFiPassword”
          wifi.sta.config(cfg)
          cfg = nil

          –WiFi AP Settup
          –wifi.setmode(wifi.STATIONAP)
          –cfg={}
          –cfg.ssid=”ESPWIFI”
          –cfg.pwd=”1234567890″
          –wifi.ap.config(cfg)
          –cfg = nil

          collectgarbage()

          — Close old Server
          if sv then
          sv:close()
          end
          –Create Server
          sv=net.createServer(net.TCP)
          connection=nil

          function receiver(sck, data)
          — Print received data
          uart.write(0, data)
          end

          function disconnect(sck)
          connection=nil
          end

          if sv then
          sv:listen(TCP_PORT, function(conn)
          if connection == nil then
          conn:send(“Hello!”)
          conn:on(“receive”, receiver)
          conn:on(“disconnection”, disconnect)
          connection = conn
          else
          conn:send(“Sorry just one connection allowed.\r\n\r\n”)
          conn:close()
          end
          end)
          end

          — UART
          uart.on(“data”, “\r”,
          function(data)
          connection:send(data..”\n”)
          end, 0)

          Подробности чуть позже…

  • Сергій Слободян говорить:

    Доброго дня!
    Класні статті пишите, читаю з задоволенням. От якби ще розсилку з новинами організували – я б обов’язково підписався.

  • Гончаренко говорить:

    Можете, пожалуйста, подробней описать суть команды gpio.OPENDRAIN
    Т.К. сам столкнулся с проблемой что ЕСП не может управлять 5 вольтово логикой

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

 
Translate
Архіви

© 2011-2017 Андрій Корягін, Кременчук - Київ, Україна