ESP8266の多機能温度/湿度センサーまたは「モノのインターネット」への別のステップ

免責事項:この記事にはエラーが含まれている可能性があります。これは私がESP8266モジュールを使用したのはそれほど前のことではなく、このデバイスの多くのアーキテクチャの側面を完全に理解していないためです。

今日、ほとんどすべての家庭にWi-Fiルーターがあり、特に今日はアイデアを実装するために利用可能なすべての機器が市場にあるため、このデバイスをホームオートメーションに使用しないことは近視眼的です。 以下に、Wi-Fiモジュール-ESP8266に基づいてさまざまなセンサー/アクチュエーターを構築するためのプラットフォームである小型の電子デバイスを作成するオプションを紹介します。

画像

このモジュールの詳細についてこちらこちら 、およびこのサイトを参照してください。ESP8266モジュールについて人類が知っているすべての情報が記載されています。

だから、「デバイス」にできるはずのもの:


デバイス図:

画像

ESP8266モジュールには多くの変更があります(オプションはこちら )が、原則として、サイズ、アンテナタイプ、利用可能な入力/出力ポートの数のみが異なります。 ESP8266 ESP-01モジュールを使用しました:

画像

2つのポート(USARTを除く)-GPIO0、GPIO2のみがありますが、私の目的では、1つのポートはセンサー用で、もう1つのポートは負荷制御用です。

USBインターフェイスは、USB-USART CH340Gコンバーターによって実装されます。

画像

ここでは、3.3および5Bロジックへの接続について説明します 。 チップは非常に安価で使いやすいです。 ストラップのうち、12MHzの水晶発振器と1組のコンデンサのみ。 その結果、一方にUSARTがあり、もう一方にUSBがあります。 PCでは、デバイスは仮想シリアルポートとして表示されます。

負荷を制御するために、トランジスタスイッチのペアを使用しました。 なぜそうなのか- 経験豊富な読者は注意深い読者に尋ねます。 問題は、供給電圧が異なる可能性があることですが、リレーを電圧=供給電圧で制御したかったのです。 pnpトランジスタを使用すると、エミッタ電流(供給電圧> ESP8266モジュールの電圧)がモジュールに流れますが、これはまったく良くありません。 GPIO0ポートは常にマイナスにプルされ、この場合、モジュールを再起動するたびにモジュールがプログラミングモードに入るため、npnトランジスタのみを使用することはできませんでした。 したがって、pnp + npnトランジスタを接続することにより、リレーのマイナスを制御します。

DHT22センサー:

画像

追加のバインディングは不要で、ESPモジュールに直接接続します。 データ交換に必要なポートは1つだけです(1-wireに似たインターフェース)。

ダイアグラムでも:

デバイスは5-12Vで動作します。

それでは、ソフトウェアについて話しましょう。

そのようなNodeMCUプロジェクトがあります。 私の意見では、非常にクールなことです。 ESP8266で直接luaスクリプトを実行できる小さなOS。 NodeMCUは、すぐに使用できるプロトコルの束を処理でき、Webサーバーを持ち上げ、TCP接続を作成できます...

最初に、NodeMCUモジュールにフラッシュします。 ファームウェアの説明

モジュールがフラッシュされたら、スクリプトをロードできます。 多くの方法がありますが、私は個人的にESPlorerユーティリティが好きです。これは、スクリプトのダウンロードだけでなく、スクリプトの開発とデバッグにも非常に便利なソフトウェアです。

より詳細に。 次の3つのスクリプトを入力する必要があります。

dht22.lua-実際にはモジュールはDHT22センサーからデータを読み取ります
-*** ***************************
-nodeMCUを備えたESP8266用のDHT22モジュール
--Javier Yanez著
-ただし、ESP8266.comフォーラムのPigs Flyのスクリプトに基づいています
--MITライセンス、 opensource.org / licenses / MIT
-*** ***************************

ローカルmoduleName = ...
ローカルM = {}
_G [モジュール名] = M

局所湿度
局所温度

関数M.read(ピン)
ローカルチェックサム
ローカルチェックサムテスト
湿度= 0
温度= 0
チェックサム= 0

-Markus Gritschトリックを使用して、GPIOの読み取り/書き込みを高速化
ローカルgpio_read = gpio.read

ローカルbitStream = {}
j = 1、40、1の場合
bitStream [j] = 0
終わり
ローカルビット長= 0
-ステップ1:DHT22に開始信号を送信する
gpio.mode(ピン、gpio.OUTPUT)
gpio.write(ピン、gpio.HIGH)
tmr.delay(100)
gpio.write(ピン、gpio.LOW)
tmr.delay(20000)
gpio.write(ピン、gpio.HIGH)
gpio.mode(ピン、gpio.INPUT)

-ステップ2:DHT22は応答信号を送信します
-バスは最終的には常に停止しますが、タイムアウトに悩まないでください
while(gpio_read(pin)== 0)do end
ローカルc = 0
while(gpio_read(pin)== 1 and c <500)do c = c + 1 end
-バスは最終的には常に停止しますが、タイムアウトに悩まないでください
while(gpio_read(pin)== 0)do end
c = 0
while(gpio_read(pin)== 1 and c <500)do c = c + 1 end

-ステップ3:データを送信するDHT22
j = 1、40、1の場合
while(gpio_read(pin)== 1 and bitlength <10)do
ビット長=ビット長+ 1
終わり
bitStream [j] =ビット長
ビット長= 0
-バスは最終的には常に停止しますが、タイムアウトに悩まないでください
while(gpio_read(pin)== 0)do end
終わり

--DHTデータ取得、処理。
i = 1、16、1の場合
if(bitStream [i]> 3)then
湿度=湿度+ 2 ^(16-i)
終わり
終わり
i = 1、16、1の場合
if(bitStream [i + 16]> 3)then
温度=温度+ 2 ^(16-i)
終わり
終わり
i = 1、8、1の場合
if(bitStream [i + 32]> 3)then
チェックサム=チェックサム+ 2 ^(8-i)
終わり
終わり

checksumTest =(bit.band(湿度、0xFF)+ bit.rshift(湿度、8)+ bit.band(温度、0xFF)+ bit.rshift(温度、8))
checksumTest = bit.band(checksumTest、0xFF)

temperature> 0x8000の場合
-負の形式に変換する
温度=-(温度-0x8000)
終わり

-条件互換のcon浮動小数点と整数
if(checksumTest-checksum> = 1)または(checksum-checksumTest> = 1)then
湿度=ゼロ
終わり
終わり

関数M.getTemperature()
戻り温度
終わり

関数M.getHumidity()
戻り湿度
終わり

リターンM


main.lua-メインスクリプト。Wi-Fiネットワークに接続し、データを受信し、mqttを介して送信し、負荷を管理します。
関数サブスクライブ()
m:サブスクライブ( "/ myhome /" .. id .. "/ light"、0、function(conn)print( "Subscribe success")end)
m:on(「メッセージ」、関数(conn、topic、data)
印刷(トピック... ":" ..data)
data ==“ ON”の場合、gpio.write(3、gpio.LOW)end
data ==“ OFF”の場合、gpio.write(3、gpio.HIGH)end
終了)
終わり

関数dht22_get_data()
dht22 = require( "dht22")
dht22.read(4)
ローカルt = dht22.getTemperature()
ローカルh = dht22.getHumidity()
t〜= nilの場合
t =((t-(t%10))/ 10).. "。" .. string.format( "%。i"、(t%10))
それ以外の場合、t = nil
終わり
h〜= nilの場合
h =((h-(h%10))/ 10).. "。" .. string.format( "%。i"、(h%10))
そうでない場合、h = nil
終わり
dht22 = nil
package.loaded ["dht22"] = nil
収集ゴミ()
t、hを返す
終わり
関数post_data()
t、h = dht22_get_data()
t〜= nilの場合
m:publish( "/ myhome /" .. id .. "/ temperature"、t、0,0、function()
print( "温度" ..t)
h〜= nilの場合
m:発行( "/ myhome /" .. id .. "/湿度"、h、0,0、function()print( "湿度" ..h)終了)
終わり
終了)
終わり
終わり

関数init_network()
収集ゴミ()
印刷(id)
wifi.sta.status()〜= 5の場合
印刷(「WIFIの再接続」)
wifi.setmode(wifi.STATION)
wifi.sta.config(「ログイン」、「パスワード」)
wifi.sta.connect()
tmr.alarm(0,5000,0、function()init_network()end)
他に
print( "IP:" ..wifi.sta.getip())
print(「MQTTサーバーへの接続」)
tmr.alarm(0,7000,0、function()init_network()end)
m〜= nilの場合
m:閉じる()
終わり
m = mqtt.Client(id、120)
m:接続( "192.168.0.x"、1883,0、関数(conn)
tmr.stop(0)
印刷(「接続済み」)
サブスクライブ()
tmr.alarm(0、60000、1、function()post_data()end)
m:on(「オフライン」、関数(con)
印刷(「offline.Reconnecting」)
init_network()
終了)
終了)
終わり
終わり

gpio.mode(3、gpio.OUTPUT)
id = "esp _" .. wifi.sta.getmac()
init_network()

init.lua-起動スクリプト。 起動時にNodeMCUを初めて起動した。
印刷( "ESP8266_home_board_v_x.x")
dofile( 'main.lc')

ここにはニュアンスがあります。 残念ながら、モジュールの外部フラッシュメモリはNodeMCUとスクリプトをロードするのに十分ではないため、次の「松葉杖」ソリューションを使用します。1つのスクリプトをロードし、node.compileコマンド(「dht22.lua」)を実行します。その結果、NodeMCUはメインスクリプトの実行中にメモリにロードするため、フラッシュメモリとRAMの両方で占めるスペースが少なくなります。 次に、file.removeコマンド(「dht22.lua」)を使用して、コンパイルされていないスクリプトを削除します。 main.luaでも同じ操作を行います。 init.luaスクリプトを最後にロードしたので、もうコンパイルしません。 モジュールを再起動します。

開始時に、NodeMCUは「init.lua」スクリプトを実行し、次に「main.lua」を実行します。 「main.lua」スクリプトはネットワークに接続し、指定されたmqttブローカーにCOMポートとネットワークにデータを送信します。

スクリプトの詳細については、コメントで回答します。

まあ、すべてがそうです。 トピックが興味深い場合は、次の記事でmqttブローカーについて説明し、このすべてをOpenhabに接続します。

ご清聴ありがとうございました。

Source: https://habr.com/ru/post/J255359/


All Articles