X

Python Instrument Panel(10)SampleーTemp & Humidity

Androidアプリ「GUI Maker for ESP8266 & ESP32 – Python Inst. Panel」を使って、温湿度センサーDHT11から取得したデータをグラフに表示します。最後に載せてあるXMLをAndroidのブラウザでコピーしてアプリにペーストすることでインストールできます。

2017/10/17 追記:縦軸を固定レンジにしました。
2017/10/23 追記:mySetup()、myLoop()に独自のコードを追加するようにしました。

先ずは、ESP8266またはESP32のArduinoスケッチを変更します。

スケッチ全体は「Python Instrument Panel(2)Arduinoスケッチ」を見てください。最後にある mySetup()process() を変更します。Androidアプリから”DHT?″の文字列を送ると温度と湿度を測定して”19.0,74.0″のように温度と湿度をカンマで繋いで返します。数値を返せないときは”nan,nan”のように数値の代わりに”nan”を返します。

今回はDHT11用のライブラリを使うので process() 以外にも変更箇所があります。

Arduino IDEのライブラリマネージャを開いてライブラリをインストールします。

“DHT”でフィルターして表示される”DHT sensor library”をインストールします。

“OneWire”でフィルターして表示される”OneWire”もインストールします。

スケッチを変更します。先ずは、Wifi用のinclude文に下に温湿度センサーDHT11用のinclude文を追加します。

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <DHT.h>                // add

次に mySetup() の前に定数、変数を追加し、 mySetup()、process() の内容を変更します。


#define DHTTYPE DHT11
#define DHTPIN 5
DHT dht(DHTPIN, DHTTYPE);

void mySetup() {
  dht.begin();
}

void myLoop() {

}

String process(String str) {
  Serial.println(str);

  if (str == "DHT?") {
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    String ret = String(t, 1) + "," + String(h, 1);
    Serial.println(ret);
    return ret;
  }
    
  return "";
}

では、パネルを作りましょう。

をタップして編集モードにして、をタップして新規パネルを表示します。

パネルに名前を付けておきます。

ExecCodeアイテムを使ってArduinoスケッチの動作を確認しておきます。をタップしてESP8266またはESP32と接続します。下記のPythonコードをExecCodeアイテムに入力してAndroid入力画面から抜けると、ESP8266またはESP32に”DHT?″という文字列が送信され、温度と湿度をカンマで繋いだ文字列が返ります。

ExecCodeアイテムのPythonコードを変更して、文字列から温度と湿度のfloat変数に変換できることを確認しておきます。

if Remote.Writer != None:
	Remote.Writer.WriteLine('DHT?')
	Remote.Writer.Flush()
	ret = Remote.Reader.ReadLine()
	slist = ret.split(',', 1)
	t = float(slist[0])
	h = float(slist[1])
	print '%.1f, %.1f' % (t, h)

次に、パネルにTextアイテム、Dropdownアイテム、Buttonアイテム、2個目のPlotViewアイテムを配置します。

 

Start/Stop ButtonのScriptです。Timerが停止しているときタップされると、2つのPlotViewをクリアしてTimerを開始します。Timerが動作しているときタップされるとTimerを停止します。

if Items[1].Value == 0:
	Items[2].ClearData()
	Items[2].Invalidate()
	Items[3].ClearData()
	Items[3].Invalidate()
	Items[8].Text = 'Running'
	Items[8].B = 0x0000ffff
	Items[1].Value = 1
else:
	Items[8].Text = 'Stopped'
	Items[8].B = 0x000000ff
	Items[1].Value = 0

Interval DropdownのScriptです。

if value == 0:
	Items[1].Interval = 1
elif value == 1:
	Items[1].Interval = 10
else:
	Items[1].Interval = 60

TimerのScriptです。事前にExecCodeアイテムで使ったコードに、表示のためのコードを追加しています。PlotViewの横軸に時刻を表示するため、現在時刻とデータを渡しています。

if Remote.Writer != None:
	Remote.Writer.WriteLine('DHT?')
	Remote.Writer.Flush()
	ret = Remote.Reader.ReadLine()
	now = DateTime.Now
	slist = ret.split(',', 1)
	t = float(slist[0])
	h = float(slist[1])
	print '%s, %.1f, %.1f' % (now, t, h)
	Items[10].Text = '%.1f ℃' % t
	Items[11].Text = '%.1f %%' % h

	points = int(Items[7].Options[Items[7].Value])
	if t != float.NaN and h != float.NaN:
		if Items[2].DataCount > points:
			Items[2].RemoveData()
		Items[2].AddData(now, t)
		Items[2].Invalidate()
		if Items[3].DataCount > points:
			Items[3].RemoveData()
		Items[3].AddData(now, h)
		Items[3].Invalidate()

PlotViewの横軸に時刻を表示するには、Panel setup scriptでStringFormatプロパティを設定します。縦軸は固定レンジにします。

 

完成したパネルのPanel contextは次のようになります。Androidのブラウザでコピーして、で追加した新規パネルのPanel context でペースト、さらにで新規パネルが”Temp & Humidity”パネルになります。

<?xml version="1.0" encoding="utf-8"?>
<PanelContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Id>fb2bdeb2-5fec-4425-a2b6-262bf22ba2c0</Id>
  <PredefinedId>00000000-0000-0000-0000-000000000000</PredefinedId>
  <Name>Temp &amp; Humidity</Name>
  <ItemList>
    <ItemContext>
      <Id>8c81561f-4b2b-4df4-8ff8-f8acbb465bb1</Id>
      <Index>1</Index>
      <ItemType>5</ItemType>
      <X>10</X>
      <Y>-20</Y>
      <TimerValue>true</TimerValue>
      <TimerInterval>1</TimerInterval>
      <TimerScript>if Remote.Writer != None:
	Remote.Writer.WriteLine('DHT?')
	Remote.Writer.Flush()
	ret = Remote.Reader.ReadLine()
	now = DateTime.Now
	slist = ret.split(',', 1)
	t = float(slist[0])
	h = float(slist[1])
	print '%s, %.1f, %.1f' % (now, t, h)
	Items[10].Text = '%.1f ℃' % t
	Items[11].Text = '%.1f %%' % h

	points = int(Items[7].Options[Items[7].Value])
	if t != float.NaN and h != float.NaN:
		if Items[2].DataCount &gt; points:
			Items[2].RemoveData()
		Items[2].AddData(now, t)
		Items[2].Invalidate()
		if Items[3].DataCount &gt; points:
			Items[3].RemoveData()
		Items[3].AddData(now, h)
		Items[3].Invalidate()</TimerScript>
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>2b661516-3dbc-4dcf-9e4c-0cc5237d98ed</Id>
      <Index>2</Index>
      <ItemType>6</ItemType>
      <X>10</X>
      <Y>-80</Y>
      <PlotViewH>200</PlotViewH>
      <PlotViewText>Temperature</PlotViewText>
      <PlotViewScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>0ab1cf7c-4a06-4a8a-b8a1-e1e829b4fc3f</Id>
      <Index>3</Index>
      <ItemType>6</ItemType>
      <X>10</X>
      <Y>-140</Y>
      <PlotViewH>200</PlotViewH>
      <PlotViewText>Humidity</PlotViewText>
      <PlotViewScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>e29b48d1-c69d-4122-b472-a299c9b8443e</Id>
      <Index>4</Index>
      <ItemType>3</ItemType>
      <X>80</X>
      <Y>-20</Y>
      <TextW>100</TextW>
      <TextH>45</TextH>
      <TextText>Interval</TextText>
      <TextFontSize>24</TextFontSize>
      <TextTextAlignment>2</TextTextAlignment>
      <TextF>255</TextF>
      <TextB>0</TextB>
      <TextScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>04c2893f-29a1-4efd-8149-e7a880b07d99</Id>
      <Index>5</Index>
      <ItemType>3</ItemType>
      <X>80</X>
      <Y>-70</Y>
      <TextW>100</TextW>
      <TextH>45</TextH>
      <TextText>Points</TextText>
      <TextFontSize>24</TextFontSize>
      <TextTextAlignment>2</TextTextAlignment>
      <TextF>255</TextF>
      <TextB>0</TextB>
      <TextScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>b369f922-959e-4565-93c1-d854283ec450</Id>
      <Index>6</Index>
      <ItemType>4</ItemType>
      <X>190</X>
      <Y>-20</Y>
      <DropdownW>120</DropdownW>
      <DropdownH>45</DropdownH>
      <DropdownText>1s;10s;60s</DropdownText>
      <DropdownFontSize>24</DropdownFontSize>
      <DropdownValue>0</DropdownValue>
      <DropdownScript>if value == 0:
	Items[1].Interval = 1
elif value == 1:
	Items[1].Interval = 10
else:
	Items[1].Interval = 60</DropdownScript>
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>1123d949-d750-4fc4-9743-e6203cf69586</Id>
      <Index>7</Index>
      <ItemType>4</ItemType>
      <X>190</X>
      <Y>-70</Y>
      <DropdownW>120</DropdownW>
      <DropdownH>45</DropdownH>
      <DropdownText>100;200;500;1000;2000;5000</DropdownText>
      <DropdownFontSize>24</DropdownFontSize>
      <DropdownValue>2</DropdownValue>
      <DropdownScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>ce5b3c15-624d-4f00-b22a-1969bb9208b9</Id>
      <Index>8</Index>
      <ItemType>3</ItemType>
      <X>170</X>
      <Y>-140</Y>
      <TextW>140</TextW>
      <TextH>50</TextH>
      <TextText>Running</TextText>
      <TextFontSize>24</TextFontSize>
      <TextTextAlignment>1</TextTextAlignment>
      <TextF>4294967295</TextF>
      <TextB>65535</TextB>
      <TextScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>6123d177-da73-415d-b90a-bb6efa3de905</Id>
      <Index>9</Index>
      <ItemType>0</ItemType>
      <X>170</X>
      <Y>-190</Y>
      <ButtonW>140</ButtonW>
      <ButtonH>80</ButtonH>
      <ButtonText>Start/Stop</ButtonText>
      <ButtonFontSize>24</ButtonFontSize>
      <ButtonTextAlignment>1</ButtonTextAlignment>
      <ButtonScript>if Items[1].Value == 0:
	Items[2].ClearData()
	Items[2].Invalidate()
	Items[3].ClearData()
	Items[3].Invalidate()
	Items[8].Text = 'Running'
	Items[8].B = 0x0000ffff
	Items[1].Value = 1
else:
	Items[8].Text = 'Stopped'
	Items[8].B = 0x000000ff
	Items[1].Value = 0</ButtonScript>
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>0cf2d8bd-16e8-48b8-a6de-1c80d1c50c7c</Id>
      <Index>10</Index>
      <ItemType>3</ItemType>
      <X>320</X>
      <Y>-20</Y>
      <TextW>300</TextW>
      <TextH>120</TextH>
      <TextText>-- ℃</TextText>
      <TextFontSize>60</TextFontSize>
      <TextTextAlignment>1</TextTextAlignment>
      <TextF>4294967295</TextF>
      <TextB>16711935</TextB>
      <TextScript />
      <V1_0_5 />
    </ItemContext>
    <ItemContext>
      <Id>a80d8738-bfa7-46bc-b84f-fbbf460a4111</Id>
      <Index>11</Index>
      <ItemType>3</ItemType>
      <X>320</X>
      <Y>-150</Y>
      <TextW>300</TextW>
      <TextH>120</TextH>
      <TextText>-- %</TextText>
      <TextFontSize>60</TextFontSize>
      <TextTextAlignment>1</TextTextAlignment>
      <TextF>4294967295</TextF>
      <TextB>16711935</TextB>
      <TextScript />
      <V1_0_5 />
    </ItemContext>
  </ItemList>
  <CurrentItemId>a80d8738-bfa7-46bc-b84f-fbbf460a4111</CurrentItemId>
  <SetupScript>Items[2].StringFormat = 'HH:mm:ss'
Items[3].StringFormat = 'HH:mm:ss'
Items[2].FixedRange(-10, 40)
Items[3].FixedRange(0, 100)</SetupScript>
  <TeardownScript />
</PanelContext>

 

snoopy: