标签 nodemcu 下的文章

这个周末,把N年前买的,都是基于ESP8266的小板子(ESP-01和基于ESP-12E的NodeMCU)拿出来玩了下,发现还有可玩性。主要是刷上MicroPython,就带来更多玩法。以前写过相关的Blog文,现在看着,觉得没用,于是重写一篇。

1. ESP8266硬件

可以简单理解为支持2.4GHz WiFi的廉价、低功耗芯片。详细的特点,参考官方文档:
https://www.esp8266.com/wiki/doku.php?id=feature_set

官方Wiki,基本想了解的都可以在这里找到:
https://www.esp8266.com/wiki/doku.php?id=start

ESP8266的硬件家族介绍:
https://www.esp8266.com/wiki/doku.php?id=esp8266-module-family

有人做了个对比:
ESP8266 module comparison: ESP-01, ESP-05, ESP-12, ESP-201, Test Board and NodeMCU
https://blog.squix.org/2015/03/esp8266-module-comparison-esp-01-esp-05.html

简单来说,一般入门的,推荐购买NodeMCU或者D1 Mini这种带USB转TTL芯片的,接上电脑就可以开发了。像ESP-01这种简单且廉价的,最好作为硬件项目的模块来用,普通玩家不要像我这样贪便宜去购买。因为开发时,ESP-01需要USB转TTL来连电脑,实际使用时也需要3.3V的电源来启动。

NodeMCU开发板官网:
https://www.nodemcu.com/index_cn.html

D1 mini官方文档:
https://www.wemos.cc/en/latest/d1/d1_mini.html

2. 选择固件(Firmware)

还是先看官方WiKi的介绍:
Loading new firmware onto an ESP8266
https://www.esp8266.com/wiki/doku.php?id=loading_firmware

能玩的固件,有3个:

1)AT命令固件(AT-Command firmware),适合ESP-01这种作为模块嵌入到硬件项目。其它硬件使用AT命令操控ESP8266来使用WiFi联网。

2)NodeMCU固件,基于Lua语言的,NodeMCU官方网站有简单介绍。另外,其固件需要从定制网站选择模块,build完后,会发Email并提供下载。

NodeMCU固件定制网站
https://nodemcu-build.com/

3)MicroPython,基于Python3语法作为开发语言的固件。一般需要2MB以上空间,NodeMCU板基于ESP-12E,内部空间(flash)是4MB,可以刷最新版本。ESP-01内部空间只有1MB,能刷v1.12或以下的版本,或者刷定制针对1MB的定制版。但是ESP-01运行MicroPython不稳定,网上有说是硬件的问题。所以ESP-01最好不要刷MicroPython。

MicroPython官网:
https://micropython.org/

MicroPython源码:
https://github.com/micropython/micropython

MicroPython针对ESP8266的资料,包括刷机和开发文档:
MicroPython - Quick reference for the ESP8266
https://docs.micropython.org/en/latest/esp8266/quickref.html

MicroPython针对ESP8266的固件下载:
MicroPython Firmware for Generic ESP8266 module
https://micropython.org/download/esp8266/

3. 刷入固件

不管刷什么固件,都是一样的操作。先下载固件文件,再安装刷机工具。刷固件前,先擦除所有数据,再刷固件。网上有很多教程,包括不同操作系统,图形化工具或者命令行操作。下面以Ubuntu为例,默认连接在/dev/ttyUSB0,使用esptool.py作为工具操作。

sudo apt update
sudo apt install python3-pip
sudo pip3 install esptool #安装esptool.py
sudo esptool.py --port /dev/ttyUSB0 erase_flash #擦除所有数据
sudo esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=detect 0 firmware_file_name.bin #刷入固件

4. 调试系统

命令行调试的话,Windows上可以用PuTTY(需要装对应TTY驱动),Linux(例如Ubuntu)上可以用minicom或者screen命令连上去。

screen命令的格式是screen -S 名称 /dev/接口名称 波特率,其中名称是方便暂时断开后再进入,即如下:

sudo screen -S esp /dev/ttyUSB0 115200

minicom命令,可以设置参数,直接连上,如下:

sudo minicom -D /dev/ttyUSB0 -b 115200

也可以不设参数,直接使用sudo minicom,进去后设置。具体操作是
-> 按[Ctrl] + [A]
-> 按[Z]
-> 按[O],即选择“cOnfigure Minicom..O”
-> 选“Serial port setup”
-> 弹出菜单按如下设置:

+-----------------------------------------------------------------------+
| A -    Serial Device      : /dev/ttyUSB0                              |
| B - Lockfile Location     : /var/lock                                 |
| C -   Callin Program      :                                           |
| D -  Callout Program      :                                           |
| E -    Bps/Par/Bits       : 115200 8N1                                |
| F - Hardware Flow Control : No                                        |
| G - Software Flow Control : No                                        |
|                                                                       |
|    Change which setting?                                              |
+-----------------------------------------------------------------------+

-> 选“Save setup as dfl”,回车
-> 选“Exit”,回车
然后就进入控制台了。

5. 开发工具

一般推荐ESPlorer,基于Java的开源图形化开发工具。该工具比较全面,三个固件都支持,可以用来做调试,也可以做开发,上传文件。本来想写下一些基本测试代码,比如连上WiFi之类,但是该工具都提供了对应的按钮,啥都不用写了。

ESPlorer官网:
https://esp8266.ru/esplorer/

ESPlorer源码:
https://github.com/4refr0nt/ESPlorer

说起物联网,最早接触的是Arduino。可是入手Arduino Mega后,一直没做出什么好玩的东西,以致Mega丢在角落里好几年。近来在部门经理的怂恿下,入手了NodeMCU,做了个检测盆栽的土壤湿度。本来想在Github开个项目,但是这第一版太简单了,就随便记录一下。

NodeMCU的特点,在于自带WiFi(还可以使用AP模式),而且价格便宜。当然,缺点也在WiFi,比较耗电。为了省电,可以设置网卡的硬件参数(wifi.setphymode()),关闭WiFi(wifi.sleeptype()),甚至是整块板进入深度睡眠模式(node.dsleep(), rtctime.dsleep())。其开源、基于Lua的开发简单、尺寸迷你等优点,也是其好玩之处。

这个项目很简单,就是NodeMCU连个土壤湿度检测模块,定时(10分钟)获取一次数据,并上传到服务器。服务器是采用树梅派,用Python3,利用Flask框架,写了个HTTP服务,用于保存提交的数据,并做数据展示。数据都保存在MySQL数据库。

NodeMCU上的init.lua

print("\n")
print("ESP8266 Started")

dsleepTime = 630000000
ssid = "my-wifi"
password = "123456"
serverIp = "192.168.1.1"
serverPort = 8080

wifi.setphymode(wifi.PHYMODE_N)
wifi.setmode(wifi.STATION)
wifi.sta.config(ssid, password)
tmr.alarm(0,1000,1,function() 
    curIp = wifi.sta.getip()
    if curIp ~= nil then
        print("Current IP:"..curIp)
        tmr.stop(0)
        sendData(readValue(0, 5))
    end
end)

--发送数据到服务器    
function sendData(value)
    print("sendData start")
    conn = net.createConnection(net.TCP, false)
    conn:on("receive", function(conn, pl)
        print("Send data with value: "..value)
        print("Result:\n"..pl)
        conn:close()
        conn = nil
        wifi.sta.disconnect()
        
        node.dsleep(dsleepTime)
    end)
    conn:connect(serverPort, serverIp)
    conn:send("GET /gather/?key=123456&value="..value
        .." HTTP/1.1\r\nHost: " + serverIp + "\r\n"
        .."Connection: keep-alive\r\nAccept: */*\r\n\r\n")

    --connect time out
    tmr.alarm(1,5000,1,function()
        print("[error]connet to server time out")
        --conn:close()
        --conn = nil
        --wifi.sta.disconnect()
        tmr.stop(1)
        
        node.dsleep(dsleepTime)
    end)
end

--读取土壤湿度数据
--一次有效的采样,最少取3次数据,去掉最大值和最小值,再计算平均值
function readValue(adcPin, readTimes)
    if readTimes <= 2 then
        readTimes = 3
    end
    
    local curValue = 0
    local maxValue = 0
    local minValue = 0
    local sumValue = 0
    
    for i = 0, readTimes - 1 do
        curValue = adc.read(adcPin)
        sumValue = sumValue + curValue
        if maxValue < curValue then
            maxValue = curValue
        end
        if (minValue == 0) or (minValue > curValue) then
            minValue = curValue
        end
    end
    sumValue = sumValue - maxValue - minValue
    curValue = math.floor(sumValue / (readTimes - 2))

    return curValue
end

服务器上的HTTP服务,文件site.ini

[uwsgi]
socket = 127.0.0.1:8080
processes = 2
threads = 1
plugins = python3
master = true
pythonpath = /opt/work/web_gather
chdir = /opt/work/web_gather
module = site
callable = app
chmod-socket = 777
memory-report = true

服务器上的HTTP服务,文件site.py

#!/bin/python3

from datetime import datetime
from flask import Flask, request, abort, render_template
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy import desc

app = Flask(__name__)
app.config['SECRET_KEY'] = '123456'

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@127.0.0.1/web_gather'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True

app.config['HUMIDITY_MIN'] = 740

db = SQLAlchemy(app)

class Humidity(db.Model):
    __tablename__ = 'humidity'
    id = db.Column('id', db.Integer, primary_key=True)
    createDate = db.Column('create_date', db.DateTime)
    sourceValue = db.Column('source_value', db.Integer)
    value = db.Column('value', db.Integer)

    def __repr__(self):
        return '<Humidity % r>' % self.id

@app.route('/', methods=['GET', 'POST'])
def index():
    key = request.args.get('key', '')
    
    if key == app.config['SECRET_KEY']:
        sourceValue = request.args.get('value', '0')
        value = (1024 - int(sourceValue)) / 1024 * 100
        curTime = datetime.today()
        humidity = Humidity(createDate=curTime, sourceValue=sourceValue, value=value)
        db.session.add(humidity)
        db.session.commit()
        return 'true'
    
    humidities = Humidity.query.order_by(desc(Humidity.createDate)).limit(500)
    return render_template('humidity.html', humidities=humidities)

if __name__ == '__main__':
    app.run(debug=False, host='127.0.0.1', port=8080)
    #app.debug = False
    #app.run()

MySQL的表定义

CREATE TABLE `humidity` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `create_date` datetime DEFAULT NULL,
  `source_value` int(11) DEFAULT NULL,
  `value` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2554 DEFAULT CHARSET=utf8

曾经在“闲鱼”(淘宝二手)上看到有人卖NodeMCU的开发板,查了发现这东西很便宜(30RMB以下可以买到),而且自带WiFi,非常适合打开“物联网”的大门。直到前几天,跟经理说起关于怎样控制窗户的开关,才又提起这个,并买了个来玩。

详细介绍
ESP8266使用
http://suda-morris.github.io/blog/2015/12/06/esp8266/

针脚定义
NodeMCU Pin Map
请输入图片描述

官方文档
NodeMCU的API文档(英文) http://nodemcu.readthedocs.org/en/dev/

入门教程
官方网站(http://www.nodemcu.com/)上没有找到官方的入门教程,但是找这一些比较好的:
1)一个比较全面的教程(针对Windows) http://nodemcu-dev.doit.am/
2)NodeMCU 物联网开发快速上手(适合Linux用户) http://tinylab.org/nodemcu-kickstart/

官方论坛(http://bbs.nodemcu.com/)上也有一个系列的入门教程:
NodeMcu介绍:(一) 概述 http://bbs.nodemcu.com/t/nodemcujie-shao-gai-shu/25
NodeMcu介绍:(二)固件烧写 http://bbs.nodemcu.com/t/nodemcu/22
NodeMcu介绍:(三)启动文件init.lua http://bbs.nodemcu.com/t/nodemcu-init-lua/24
NodeMcu介绍:(四)下载*.lua文件 http://bbs.nodemcu.com/t/nodemcu-lua/26

Lua语言介绍
关于NodeMCU上使用的Lua,这里有个不错的教程
https://moonbingbing.gitbooks.io/openresty-best-practices/content/lua/main.html