ESP8266:Примеры/Погодная станция на базе ESP8266, регистрирующая данные в Excel

Материал из Онлайн справочника
Перейти к навигации Перейти к поиску

Перевод: Максим Кузьмин (Cubewriter) Контакты:</br>* Skype: cubewriter</br>* E-mail: cubewriter@gmail.com</br>* Максим Кузьмин на freelance.ru
Проверка/Оформление/Редактирование: Мякишев Е.А.


Pixel Art Mini Meow Animated.gif Черновик


Содержание

Погодная станция на базе ESP8266, регистрирующая данные в Excel[1]

Эта статья рассказывает, как установить беспроводное соединение между двумя модулями ESP и отправлять данные от трех датчиков в электронную таблицу Excel. По сути, этот проект – погодная станция, которая имеет функцию регистрации данных и может быть реализована в домашних условиях.

Но сначала вам нужно будет пройти следующие руководства:

Общий план проекта

Ниже – рисунок, объясняющий принцип работы проекта:

Esp8266-wireless-station.jpg

Необходимые компоненты

  • Рекомендуемый вариант – два модуля ESP-12E; альтернативный вариант – два модуля ESP-201 + один программатор FTDI
  • Один температурный датчик DS18B20
  • Одна макетная плата
  • Три кнопки
  • Три резистора на 10 кОм
  • Один резистор на 4700 Ом
  • Один потенциометр на 10 кОм

Справочная информация

Основы программирования на Lua

Это скриптовый язык программирования, написанный на C. Разработка этого проекта началась в 1993 году силами Роберту Иерузалимски, Луиша Энрике де Фигейреду и Валдемара Келе, работавшими тогда в подразделении Tecgraf при Католическом университете Рио-де-Жанейро.

Более подробно об этом языке программирования можно почитать в «Википедии».

Прошивка NodeMCU для ESP8266 основана на Lua, поэтому если вы хотите писать собственные скрипты для ESP8266, вам важно знать основы этого языка.

Переменные

Переменные в языке Lua не делятся по типу данных, но делятся по области видимости. Это значит, что переменные в Lua могут быть глобальными или локальными.

  • Глобальные переменные. Все переменные по умолчанию считаются глобальными (если в коде специально не задано, что они локальные).
pin = 3
test = "It works!"
  • Локальные переменные. Если переменная задана локальной, область ее видимости будет ограничена лишь ее функцией.
local pin = 3
local test = "It works!"
  • Поля таблиц. Это особый тип переменных, в которых может храниться все, за исключением «nil» (мы это затрагивать не будем).

Примечание: Lua – это язык, чувствительный к регистру. Поэтому переменная «PIN» – это не то же самое, что «Pin» или «pin».

Типы данных (типы значений)

Lua – это язык с динамической типизацией, поэтому у переменных нет типов данных. Типы данных есть только у значений. Значения могут храниться в переменных, передаваться в виде параметров и возвращаться в виде результатов.

В таблице ниже показаны типы данных для значений в языке Lua.

Тип значения Описание
Строка (string) Массив символов
Число (number) Действительное (двойной точности с плавающей запятой) число
Булево значение (boolean) Значение «true» или «false». Как правило, используется для проверки выполнения условий
Функция (function) Функция, написанная на Lua
Неопределенное значение (nil) В такой переменной не хранится никаких данных
Таблица (table), пользовательские данные (userdata) и поток (thread) Эти три типа данных мы затрагивать не будем

Вот примеры некоторых из этих типов значений:

1 print(type("Hello world!")) - строка
2 print(type(7))              -- число
3 print(type(true))           -- булево значение
4 print(type(print))          -- функция
5 print(type(nil))            -- неопределенное значение

Примечание: Работая с ESP8266 и прошивкой NodeMCU, вы изредка будете встречать тип данных «nil». Это будет значить лишь, что такая переменная не определена. Также, если вы хотите удалить какое-то значение в какой-то переменной, просто присвойте ей значение «nil».

Комментарии

Комментарии – это просто текст, в котором программист объясняет, как работает его код. Если какой-то фрагмент кода помечен как комментарий, то ESP-модуль проигнорирует его и не будет обрабатывать. Комментарии начинаются с двух тире («--»). Вот два типа комментариев:

  • Однострочные комментарии:
print("Hello World!") - комментарий в одну строчку
  • Многострочные комментарии:
--[[
print("Hello World!") – это многострочный комментарий
--]]

Операторы

Оператор – это символ, который говорит интерпретатору выполнить определенное математическое или логическое действие. В язык Lua встроено много операторов разных типов:

  • Арифметические операторы;
  • Операторы сравнения;
  • Логические операторы;
  • Прочие операторы;

Читая таблицы и примеры ниже, представьте, что имеете дело с двумя переменными: «А», в которой хранится значение «1», и «B», в которой хранится значение «2».

1 A = 1
2 B = 2
Арифметические операторы
Оператор Пример Результат
+ A + B 3
- A - B -1
* A * B 2
/ B / A 2
% B % A 0
^ B^2 4
- -A -1
Операторы сравнения
Оператор Пример Результат
== (A == B) false
~= (A ~= B) true
> (A > B) false
< (A < B) true
>= (A >= B) false
<= (A <= B) true
Логические операторы
Оператор Пример Результат
and (и) (A and B) false
or (или) (A or B) true
not (не) !(A and B) true
Оператор конкатенации

Теперь представьте, что у нас две новые переменные:

1 a = "Hello!"
2 b = "World!"
Оператор Пример Результат
.. a..b "Hello World!"

Циклы

Цикл позволяет выполнить блок кода несколько раз, пока выполняется заданное условие. Во фрагменте кода ниже – пока значением в переменной «boolean_value» является «true».

 1 -- цикл while
 2 while boolean_value
 3 do
 4  -- код будет выполняться, пока в «boolean_value» будет «true»
 5 end
 6 
 7 -- и цикл for
 8 for min, max, increment
 9 do
10   -- код будет выполняться, пока не будет достигнуто макс. значение
11 end

Операторы if… else

Операторы if... else (т.е. «если... иначе») – один из самых важных инструментов для управления программой. Они используются следующим образом:

1 if boolean_value then
2     -- если в переменной «boolean_value» значение «true»
3 else 
4     -- если в переменной «boolean_value» значение «false»
5 end

Названия этих операторов говорят сами за себя. Если выполнено условие «boolean_value=true», то программа выполнит код, идущий после «if». Но если условием является «boolean_value=false», то программа выполнит код, идущий после «else».

Функции

Функции – отличный способ организации кода. Если вы хотите сделать в программе что-либо несколько раз, вам необязательно по несколько раз прописывать этот код. Можно просто создать отдельную функцию, содержащую этот код, а затем вызывать ее, когда вам нужно.

Ниже показано, как создать новую функцию, принимающую один параметр (температуру в градусах Кельвина) и преобразующую это значение в градусы Цельсия и Фаренгейта.

 1 function displayTemperature(kelvin)
 2   celsius = kelvin  273.15
 3   print("Temperature in Celsius is: ", celsius)
 4 
 5   fahrenheit = (celsius*9/5+32)
 6   print("Temperature in Fahrenheit is: ", fahrenheit)
 7 end
 8 
 9 k = 294 - температура в градусах Кельвина
10 
11 displayTemperature(k) - эта строчка вызывает функцию, созданную выше

DS18B20 – цифровой температурный датчик с шиной 1-Wire

В этом проекте мы воспользуемся датчиком DS18B20. Давайте разберемся, как его подключать.

DS18B20 можно питать напряжением от 3,0 до 5,5 вольт, поэтому вы можете смело подключить GND к GND, а VDD – к 3.3V на ESP8266.

Затем подключите контакт DQ к IO04 на ESP8266. На контакте DQ также понадобится подтягивающий резистор на 4,7 кОм, чтобы подтянуть напряжение к 3,3 вольт.

Ds18b20-pinout.jpg

Считывание АЦП-значения

Для считывания аналоговых данных мы воспользуемся контактом ADC на ESP. Впрочем, этот контакт называют по-разному (и все эти названия взаимозаменяемы):

  • ADC (от «analog-to-digital converter», т.е. «аналогово-цифровой преобразователь»)
  • TOUT
  • Контакт 6
  • A0
  • Аналоговый контакт 0

Все эти термины – для одного и того же контакта на ESP8266. Более подробно о нем можно почитать в этой статье.

На данный момент контакт ADC имеет 10-битное разрешение, а также входное напряжение от 0 до 1,0 вольт (если питается от внешней цепи).

Доступ к контакту ADC на ESP8266

На ESP-201 получить доступ к контакту ADC очень просто – вам нужно лишь подключить провод-перемычку к контакту, выделенному красным цветом на рисунке ниже:

ESP8266 – Wireless Weather Station with Data Logging to Excel esp-201 1.png

Прошивка обоих ESP при помощи NodeMCU

Для этого проекта мы воспользуемся прошивкой NodeMCU, и о том, как загрузить ее на ESP, читайте тут.

Загрузка ESPlorer IDE

Для загрузки скриптов на ESP8266 рекомендую использовать программу ESPlorer IDE (она создана пользователем 4refr0nt). Чтобы скачать и установить ее, проделайте следующее:

  1. Кликните здесь, чтобы скачать ZIP-архив с ESPlorer IDE
  2. Распакуйте архив
  3. Перейдите в главную папку
  4. Запустите файл «ESPlorer.jar»
  5. Откройте ESPlorer IDE

Загрузка скрипта на ESP8266 (при помощи 3,3-вольтового программатора FTDI)

Чтобы загрузить скрипт на ESP8266 (и для клиента, и для сервера), вам нужно лишь настроить последовательное соединение между программатором FTDI и модулем ESP8266. Делается это следующим образом:

  • Контакт VCC на ESP8266 – к контакту 3.3V на программаторе
  • Контакт GND – к контакту GND
  • Контакт TX – к контакту RX
  • Контакт RX – к контакту TX
  • GPIO-контакт 0 – к контакту 3.3V
  • GPIO-контакт 15 – к контакту GND

Скрипты для клиента

На клиента нужно будет загрузить три скрипта:

Начните с загрузки скрипта «counetMax.lua». По сути, этот скрипт – просто цифра «1», которая работает счетчиком и помогает сбросить плату при разрыве соединения с сервером:

1

Когда вы загрузите скрипт, ESPlorer IDE напечатает вот такую ошибку:

ESP8266 – Wireless Weather Station with Data Logging to Excel uploading-counter-max 2.png

Затем загрузите на ESP8266 скрипт под названием «ds18b20.lua» (убедитесь, что он назван именно так). Он есть в двух версиях: одна позволяет считывать температуру в градусах Цельсия, а другая – в градусах Фаренгейта.

  1 --------------------------------------------------------------------------------
  2 -- Скрипт к температурному датчику DS18B20 (1-Wire) для NODEMCU
  3 -- ЛИЦЕНЗИЯ: http://opensource.org/licenses/MIT
  4 -- Автор - Vowstar <vowstar@nodemcu.com>
  5 -- Оптимизировал: Питер Скэргилл (Peter Scargill)
  6 --------------------------------------------------------------------------------
  7 -- Задаем название модуля, чтобы потом 
  8 -- сделать его параметром для setfenv()
  9 local modname = ...
 10 local M = {}
 11 _G[modname] = M
 12 --------------------------------------------------------------------------------
 13 -- Локально используемые модули
 14 --------------------------------------------------------------------------------
 15 -- Модуль для таблицы 
 16 local table = table
 17 -- Модуль для строки
 18 local string = string
 19 -- Модуль для шины 1-Wire 
 20 local ow = ow
 21 -- Модуль для таймера
 22 local tmr = tmr
 23 -- Расчеты ограничены окружением «local»
 24 setfenv(1,M)
 25 
 26 --------------------------------------------------------------------------------
 27 -- Реализация – постарался сделать как можно короче
 28 --------------------------------------------------------------------------------
 29 
 30 function readNumber(pin)
 31         ow.setup(pin)
 32         ow.reset(pin)
 33         ow.write(pin, 0xCC, 1)
 34         ow.write(pin, 0xBE, 1)
 35         data = nil
 36         data = ""
 37         for i = 1, 2 do
 38             data = data .. string.char(ow.read(pin))
 39         end
 40         t = (data:byte(1) + data:byte(2) * 256) / 16
 41         if (t>100) then
 42         t=t-4096
 43         end
 44         ow.reset(pin)
 45         ow.write(pin,0xcc,1)
 46         ow.write(pin, 0x44,1)  
 47         return t          
 48 end
 49 
 50 -- Возвращаем модуль «table»
 51 return M
 52 Наконец, загружаем на ESP главный скрипт под названием «init.lua».
 53 -- Беспроводная погодная станция с регистрацией данных 
 54 -- в таблицу Excel при помощи Things Gateway
 55 -- Автор: Ив Абур (Yves Arbour) 
 56 --
 57 -- Скрипт основан на следующих работах:
 58 --
 59 -- Руи Сантос (Rui Santos) – Клиент ESP8266 
 60 -- Скрипт к температурному датчику DS18B20 (1-Wire) для NODEMCU
 61 -- Vowstar <vowstar@nodemcu.com> 
 62 -- Питер Скэргилл (Peter Scargill)
 63 -- Wimp Weather Station; автор: Нейтан Сидле (Nathan Seidle), sparkfun
 64 
 65 wifi.sta.disconnect()
 66 wifi.setmode(wifi.STATION)
 67 wifi.sta.config("test","12345678")
 68 wifi.sta.connect() 
 69 print("Looking for a connection")  //  "Поиск соединения"
 70 temp=0
 71 function readds18b20sensor()
 72     t=require("ds18b20.lua")   
 73    -- print(t.readNumber(2))  for debuging
 74     temp = (t.readNumber(2)) --GPIO 04
 75 end
 76 
 77 winDirection=0
 78 gpio.mode(0,gpio.INPUT)
 79 function readWindDirection ()
 80     windDirection = adc.read(0)
 81         if (windDirection < 26) then windDirection=90 --E
 82        --if (windDirection < 17) then windDirection=113      -- ESE
 83        --elseif (windDirection < 21) then windDirection=68   -- ENE
 84        --elseif (windDirection < 26) then windDirection=90   -- E
 85        --elseif (windDirection < 36) then windDirection=158  -- SSE
 86        elseif (windDirection < 43) then windDirection=135 --SE
 87        --elseif (windDirection < 60) then windDirection=203  -- SSW
 88        elseif (windDirection < 85) then windDirection=180 --S
 89        --elseif (windDirection < 98) then windDirection=23   -- NNE
 90        elseif (windDirection < 120) then windDirection=45 --NE
 91        --elseif (windDirection < 170) then windDirection=248  -- WSW
 92        elseif (windDirection < 210) then windDirection=225 -SW
 93        --elseif (windDirection < 275) then windDirection=338  -- NNW
 94        elseif (windDirection < 380) then windDirection=0 --N
 95        --elseif (windDirection < 500) then windDirection=293  -- WNW
 96        elseif (windDirection < 750) then windDirection=315 --NW
 97        elseif (windDirection < 1005) then windDirection=270 --W
 98        else windDirection=-1
 99        end
100 end
101 irqPin = 1  --GPIO5
102 windSpeed = 0
103 windClicks = 0
104 lastWindCheck = 0
105 function debounce (func)   
106     local delay = 100000   
107     return function (...)  
108         now = tmr.now() 
109         now = now - lastWindCheck               
110         if now < delay then return end
111         lastWindCheck = tmr.now()        
112         return func (...)
113     end
114 end
115 
116 function windSpeedIrq ()    
117     windClicks = windClicks+1 * 10000000
118     print (windClicks)
119 end  
120 function calcWindSpeed ()
121     local deltaTime = tmr.now () - lastWindCheck        
122     windSpeed = windClicks / deltaTime
123     print(deltaTime)              
124     windSpeed = windSpeed * 1492 /10000 -- Replace " *1492/10000 " with " *24/100 " for Km/h instead of Mp/h
125     windClicks = 0
126     lastWindCheck = tmr.now()
127 end 
128 gpio.mode(irqPin,gpio.INT)
129 gpio.trig(irqPin,"down",debounce(windSpeedIrq))
130       
131 file.open("counterMax.lua","r")
132 counter=(file.read())
133 file.close()
134   tmr.alarm(0, 2000, 1, function()
135    if(wifi.sta.getip()~=nil) then
136           tmr.stop(0)
137           print("Client IP Address:",wifi.sta.getip())
138             //  "IP-адрес клиента:"
139           cl=net.createConnection(net.TCP, 0)
140           cl:connect(80,"192.168.4.1")
141           tmr.alarm(1, 5000, 1, function()
142           counter=counter+1       
143        
144         readds18b20sensor()            
145         readWindDirection()
146         calcWindSpeed()
147         print (temp)
148         print(windSpeed)
149 -- Next is the properly formated string that Things Gateway needs to show Date,Time,Wind speed,Wind direction and  Temp.    
150   cl:send("XLS,write,Example,A"..counter..",%date%\nXLS,write,Example,B"..counter..",%time%\nXLS,write,Example,C"..counter..","..windSpeed.."\nXLS,write,Example,D"..counter..","..windDirection.."\nXLS,write,Example,E"..counter..","..temp)
151   
152   cl:on("disconnection",function(reconnect)
153     file.open("counterMax.lua","w+")
154     file.writeline(counter)
155     file.close()
156    end)
157        end)
158    else
159          print("Connecting...")  //  "Подключение..."
160        end
161 end)
162 function reconnect()    
163 wifi.setmode(wifi.STATION)
164 wifi.sta.config("test","12345678")
165 wifi.sta.connect()
166 end

Схема для клиента

Соберите клиентскую часть согласно картинке ниже (если используете модуль ESP-12, воспользуйтесь этой схемой):

ESP8266 – Wireless Weather Station with Data Logging to Excel weatherStation-201-Sketch bb 3.png

Кнопка справа, подключенная к IO05, используется для симуляции данных о скорости ветра. Впрочем, это скорость ветра не в реальном времени, а средний показатель за последние 5 секунд.

То есть не важно, как часто вы будете нажимать на эту кнопку. Если нажать на нее 5 раз в течение 5 последних секунд, это будет частота 1 раз в секунду, что даст 1,492 миль/ч или 2,4 км/ч. Впрочем, на данный момент в проекте используются целые числа, поэтому в результате получится 1492 м/ч и 24 км/ч. Вам нужно будет разделить эти значения уже в самой в таблице Excel – соответственно, на 100 и 10.

Скрипт для сервера

 1 -- Создал: Руи Сантос (Rui Santos) – Сервер ESP8266
 2 -- Модифицировал: Ив Абур (Yves Arbour); после модификации строка 
 3 -- печатается напрямую в таблицу Excel при помощи Things Gateway
 4 
 5 print("ESP8266 Server")  //  "Сервер ESP8266"
 6 wifi.setmode(wifi.STATIONAP);
 7 wifi.ap.config({ssid="test",pwd="12345678"});
 8 print("Server IP Address:",wifi.ap.getip())  //  "IP-адрес сервера: "
 9  
10 sv = net.createServer(net.TCP)
11 sv:listen(80, function(conn)
12     conn:on("receive", function(conn, receivedData)
13       --print("Received Data"..receivedData) 
14           //  "Полученные данные..."
15         print(receivedData)-- string "Received Data" removed...
16         -- Things Gateway игнорирует строки, которые не начинаются
17         -- правильной команды...
18         -- В данном случае для таблицы Excel нужна команда XLS        
19     end)
20     conn:on("sent", function(conn)
21       collectgarbage()
22     end)
23 end)

Схема для сервера

Соберите серверную часть согласно картинке ниже (если используете модуль ESP-12, воспользуйтесь этой схемой):

ESP8266 – Wireless Weather Station with Data Logging to Excel WirelessWeatherStationServer 201 bb-1 4.png

Я создал для ESP-201 специальную плату. Ее особенности:

  • Желтый провод: Его можно подключить либо между 0-ым GPIO-контактом и GND (чтобы загружать прошивку NodeMCU), либо между 0-ым GPIO-контактом и VCC (чтобы сохранять скрипты на ESP)
  • 15-ый GPIO-контакт припаян к контакту GND
  • К контакту RST подключена кнопка и подтягивающий резистор на 10 кОм (то есть, если нажать на эту кнопку, резистор притянет сигнал к «земле», а затем вернется в исходное положение)
ESP8266 – Wireless Weather Station with Data Logging to Excel ESP8266-with-PCBs 5.jpg

Сборка

Запитайте оба ESP и убедитесь, что между серверным ESP и компьютером по-прежнему установлена последовательная коммуникация, потому что именно через нее сервер будет отправлять данные в таблицу Excel.

ESP8266 – Wireless Weather Station with Data Logging to Excel 6.jpg

Загрузка и установка Things Gateway

В этом проекте мы воспользуемся программой Things Gateway, написанной Роберто Валголио (Roberto Valgolio), чтобы в реальном времени записывать в таблицу Excel данные, которые будут постоянно обновлять сами себя.

Things Gateway – это PC-программа, которая подключается к микроконтроллеру и способна делать следующее:

  • Извлекать данные из файлов Excel
  • Записывать данные в файлы Excel
  • Записывать логи в файлы *.csv
  • Отправлять электронные письма (при соблюдении заданных условий)
  • Показывать значения и графики (графики независимы от Excel)

Things Gateway также умеет подключаться к GPS и показывать на экране...

  • Скорость, направление, высоту и другую навигационную информацию
  • Маршрут в реальном времени на Google Maps

Зайдите на сайт Things Gateway, загрузите программу и установите ее. Данный проект тестировался с версией Beta4.

ESP8266 – Wireless Weather Station with Data Logging to Excel ThingsGatewaydownload 7.jpg

Запуск Things Gateway

Открывается Things Gateway очень просто. Просто пройдите в Этот компьютер > Документы > ThingsGateway и откройте программу.

ESP8266 – Wireless Weather Station with Data Logging to Excel things-gateway-app 8.jpg

Затем сделайте следующее:

  1. Перейдите на вкладку «Config»
  2. В поле «port» впишите порт сервера
  3. В поле «speed» впишите 9600

Все нужные пункты выделены на картинке ниже красным цветом:

ESP8266 – Wireless Weather Station with Data Logging to Excel things-config 9.png

Демонстрация

Откройте вкладку RealTime и в столбце «From» выберите пункт «Serial», а в столбце «To» – пункт «Excel».

ESP8266 – Wireless Weather Station with Data Logging to Excel ThingsGateway-1 10.jpg

Если все настроено правильно, далее откроется таблица Excel и начнет заполняться данными, которые будут появляться каждые несколько секунд.

ESP8266 – Wireless Weather Station with Data Logging to Excel ThingsGateway-excel 11.jpg

Ваши данные будут записываться в таблицу Excel, находящуюся в этой папке:

ESP8266 – Wireless Weather Station with Data Logging to Excel things-gateway-example 12.jpg

Дальнейшие улучшения

Этот пример позволяет попробовать и другие функции Things Gateway:

  • Графики, обновляющиеся самостоятельно и в реальном времени (независимо от Excel)
  • Запись логов в файлы формата *.csv
  • Автоматическая отправка электронных писем при соблюдении заданных условий (к примеру, если скорость ветра возрастет на столько-то или температура упадет на столько-то, если в морозильнике недостаточно холодно и т.д.)
  • Запись логов в файл «stream.txt» с коэффициентом обновления 0.1, 0.5, 1.5, 10, 60 или 3600
  • GPS-отслеживание маршрута на Google Maps с коэффициентом обновления 0.1, 0.5, 1.5, 10, 60 или 3600

Улучшения, которые планируется добавить в будущем:

  • Другие датчики вроде датчика атмосферного давления BMP180
  • Датчики света
  • Датчики влажности
  • Любой другой цифровой или аналоговый датчик, использующий мультиплексинг

Также помните, что Things Gateway создавался с прицелом на использование с платой Arduino, но если отправлять через последовательную коммуникацию правильные строки, эту программу можно использовать с любой платой.

См.также

Внешние ссылки