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スケッチの動作を確認しておきます。
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のブラウザでコピーして、
<?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 & 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 > 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()</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>