LoginSignup
1
1

More than 3 years have passed since last update.

2020 夏休みの工作特別企画 wifi 温度計を作る。

Last updated at Posted at 2019-08-17

夏休みの工作特別企画 wifi 温度計を作る。

ソースの場所

image.png

携帯に自分の部屋の温湿度を表示

image.png

1000円以下で

image.png

image.png

資料

image.png

Arduino
のIDEを準備する。
image.png
環境設定のメニューから
image.png
追加のボードマネージャのURLに

https://arduino.esp8266.com/stable/package_esp8266com_index.json

設定すると
image.png
Generic ESP8266が選択できるようになる。
先ほどダウンロードしたESP-01S-DHT11-v1.0-master\ESP-01S-DHT11-v1.0-master\ESP01 01S DHT11 Arduino demo code\ESP01 01S DHT11 Arduino demo code\demo\Arduno_DHT11の中のArduno_DHT11.inoをIDEに読み込む。


```Arduno_DHT11.ino
/* DHTServer - ESP8266 Webserver with a DHT sensor as an input

   Based on ESP8266Webserver, DHTexample, and BlinkWithoutDelay (thank you)

   Version 1.0  5/3/2014  Version 1.0   Mike Barela for Adafruit Industries
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <DHT.h>
#define DHTTYPE DHT11
#define DHTPIN  2
// Replace with your network details
const char* ssid     = "自分のSSID";
const char* password = "自分のパスワード";
ESP8266WebServer server(80); 
// Initialize DHT sensor 
// NOTE: For working with a faster than ATmega328p 16 MHz Arduino chip, like an ESP8266,
// you need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// This is for the ESP8266 processor on ESP-01 
DHT dht(DHTPIN, DHTTYPE, 11); // 11 works fine for ESP8266

float humidity, temp_f;  // Values read from sensor
String webString="";     // String to display
// Generally, you should use "unsigned long" for variables that hold time
unsigned long previousMillis = 0;        // will store last temp was read
const long interval = 2000;              // interval at which to read sensor

void handle_root() {
  server.send(200, "text/plain", "Hello from the weather esp8266, read from /temp or /humidity");
  delay(100);
}

void setup(void)
{
  // You can open the Arduino IDE Serial Monitor window to see what the code is doing
  Serial.begin(115200);  // Serial connection from ESP-01 via 3.3v console cable
  dht.begin();           // initialize temperature sensor

  // Connect to WiFi network
  WiFi.begin(ssid, password);
  Serial.print("\n\r \n\rWorking to connect");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("DHT Weather Reading Server");
  Serial.print("Connected to ");
  Serial.println(ssid);
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  server.on("/", handle_root);

  server.on("/temp", [](){  // if you add this subdirectory to your webserver call, you get text below :)
    gettemperature();       // read sensor
    webString=String((int)temp_f);   // Arduino has a hard time with float to string
    server.send(200, "text/plain", webString);            // send to someones browser when asked
  });

  server.on("/humidity", [](){  // if you add this subdirectory to your webserver call, you get text below :)
    gettemperature();           // read sensor
    webString=String((int)humidity);
    server.send(200, "text/plain", webString);               // send to someones browser when asked
  });

  server.begin();
  Serial.println("HTTP server started");
}

void loop(void)
{
  server.handleClient();
} 

void gettemperature() {
  // Wait at least 2 seconds seconds between measurements.
  // if the difference between the current time and last time you read
  // the sensor is bigger than the interval you set, read the sensor
  // Works better than delay for things happening elsewhere also
  unsigned long currentMillis = millis();

  if(currentMillis - previousMillis >= interval) {
    // save the last time you read the sensor 
    previousMillis = currentMillis;   

    // Reading temperature for humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
    humidity = dht.readHumidity();          // Read humidity (percent)
    temp_f = dht.readTemperature(false);     // false は、摂氏 ~~Read temperature as Fahrenheit~~
    // Check if any reads failed and exit early (to try again).
    if (isnan(humidity) || isnan(temp_f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }
  }
}

もとのプログラムは、温度データが華氏なので摂氏にするには、

temp_f = dht.readTemperature(false);     // Read temperature as Fahrenheit

dht.readTemperature(true)を上記のように変更する。
プログラムの書き込みには、
image.png

が必要になる。

image.png

→マークで書き込む

esptool.py v2.6
2.6
esptool.py v2.6
Serial port COM4
Connecting....
Chip is ESP8266EX
Features: WiFi
MAC: 84:0d:8e:a7:ea:70
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 1MB
Compressed 295984 bytes to 212035...

Writing at 0x00000000... (7 %)
Writing at 0x00004000... (15 %)
Writing at 0x00008000... (23 %)
Writing at 0x0000c000... (30 %)
Writing at 0x00010000... (38 %)
Writing at 0x00014000... (46 %)
Writing at 0x00018000... (53 %)
Writing at 0x0001c000... (61 %)
Writing at 0x00020000... (69 %)
Writing at 0x00024000... (76 %)
Writing at 0x00028000... (84 %)
Writing at 0x0002c000... (92 %)
Writing at 0x00030000... (100 %)
Wrote 295984 bytes (212035 compressed) at 0x00000000 in 21.5 seconds (effective 110.0 kbit/s)...
Hash of data verified.

確認するために
image.png

image.png

シリアルモニターを立ち上げる
image.png
'HTTP server started'となればOK

もし書き込みを失敗したなら次を試そう。

初期化ツール Download

image.png
image.png
flash_download_tools_v3.6.6.exeを実行する
image.png

ファイル名 アドレス
ESP8266_NONOS_SDK\bin\boot_v1.2.bin 0x00000
ESP8266_NONOS_SDK\bin\at\512+512\user1.1024.new.2.bin 0x010000
ESP8266_NONOS_SDK\bin\esp_init_data_default.bin 0xfc000
ESP8266_NONOS_SDK\bin\blank.bin 0x7e000
ESP8266_NONOS_SDK\bin\blank.bin 0xfe0000

STRTボタンで書き込み出来るはずだ。
ブラウザーにアドレスを入れてみよう。温度

http://192.168.1.13/temp

image.png

ブラウザーにアドレスを入れてみよう。湿度

http://192.168.1.13/humidity

image.png

動作確認終了!!!

import requests
t = requests.post('http://192.168.1.13/temp').text
h = requests.post('http://192.168.1.13/humidity').text
print(t,h)

29 49

それらしい値が出ていますね。

pythonとbottleの組み合わせで温度や湿度を表示するためのガジェットを表示するためには、ちょっと工夫が必要です。

今回は、出来合いのゲージを使用します。

image.png

このキャンバスゲージを用いると簡単に下記のような表示することができる。

image.png

キャンバスゲージのhtml定義

gauges.py
canvas=[
 '''<canvas
        id="tmp1"
        data-type="radial-gauge"
        data-width="300"
        data-height="300"
        data-units="°C"
        data-title="Temperature"
        data-min-value="-50"
        data-max-value="50"
        data-major-ticks="[-50,-40,-30,-20,-10,0,10,20,30,40,50]"
        data-minor-ticks="2"
        data-stroke-ticks="true"
        data-highlights='[
                    {"from": -50, "to": 0, "color": "rgba(0,0, 255, .3)"},
                    {"from": 0, "to": 50, "color": "rgba(255, 0, 0, .3)"}
                ]'
        data-ticks-angle="225"
        data-start-angle="67.5"
        data-color-major-ticks="#ddd"
        data-color-minor-ticks="#ddd"
        data-color-title="#eee"
        data-color-units="#ccc"
        data-color-numbers="#eee"
        data-color-plate="#222"
        data-border-shadow-width="0"
        data-borders="true"
        data-needle-type="arrow"
        data-needle-width="2"
        data-needle-circle-size="7"
        data-needle-circle-outer="true"
        data-needle-circle-inner="false"
        data-animation-duration="1500"
        data-animation-rule="linear"
        data-color-border-outer="#333"
        data-color-border-outer-end="#111"
        data-color-border-middle="#222"
        data-color-border-middle-end="#111"
        data-color-border-inner="#111"
        data-color-border-inner-end="#333"
        data-color-needle-shadow-down="#333"
        data-color-needle-circle-outer="#333"
        data-color-needle-circle-outer-end="#111"
        data-color-needle-circle-inner="#111"
        data-color-needle-circle-inner-end="#222"
        data-value-box-border-radius="0"
        data-color-value-box-rect="#222"
        data-color-value-box-rect-end="#333"
        data-font-value="Led"
        data-font-numbers="Led"
        data-font-title="Led"
        data-font-units="Led"
></canvas>''',
'''<canvas
        id="humid1"
        data-type="radial-gauge"
        data-width="300"
        data-height="300"
        data-units="%"
        data-title="Humidity"
        data-min-value="0"
        data-max-value="100"
        data-major-ticks="[0,10,20,30,40,50,60,70,80,90,100]"
        data-minor-ticks="2"
        data-stroke-ticks="true"
        data-highlights='[
                    {"from": 0, "to": 50, "color": "rgba(0,0, 255, .3)"},
                    {"from": 50, "to": 100, "color": "rgba(255, 0, 0, .3)"}
                ]'
        data-ticks-angle="225"
        data-start-angle="67.5"
        data-color-major-ticks="#ddd"
        data-color-minor-ticks="#ddd"
        data-color-title="#eee"
        data-color-units="#ccc"
        data-color-numbers="#eee"
        data-color-plate="#222"
        data-border-shadow-width="0"
        data-borders="true"
        data-needle-type="arrow"
        data-needle-width="2"
        data-needle-circle-size="7"
        data-needle-circle-outer="true"
        data-needle-circle-inner="false"
        data-animation-duration="1500"
        data-animation-rule="linear"
        data-color-border-outer="#333"
        data-color-border-outer-end="#111"
        data-color-border-middle="#222"
        data-color-border-middle-end="#111"
        data-color-border-inner="#111"
        data-color-border-inner-end="#333"
        data-color-needle-shadow-down="#333"
        data-color-needle-circle-outer="#333"
        data-color-needle-circle-outer-end="#111"
        data-color-needle-circle-inner="#111"
        data-color-needle-circle-inner-end="#222"
        data-value-box-border-radius="0"
        data-color-value-box-rect="#222"
        data-color-value-box-rect-end="#333"
        data-font-value="Led"
        data-font-numbers="Led"
        data-font-title="Led"
        data-font-units="Led"
></canvas>''',
'''<canvas
        id="pressure2"
        data-type="radial-gauge"
        data-width="300"
        data-height="300"
        data-units="hPa"
        data-title="Pressure"
        data-min-value="300"
        data-max-value="1200"
        data-major-ticks="[300,400,500,600,700,800,900,1000,1100,1200]"
        data-minor-ticks="2"
        data-stroke-ticks="true"
        data-highlights='[
                    {"from": 300, "to": 900, "color": "rgba(0,0, 255, .3)"},
                    {"from": 900, "to": 1200, "color": "rgba(255, 0, 0, .3)"}
                ]'
        data-ticks-angle="225"
        data-start-angle="67.5"
        data-color-major-ticks="#ddd"
        data-color-minor-ticks="#ddd"
        data-color-title="#eee"
        data-color-units="#ccc"
        data-color-numbers="#eee"
        data-color-plate="#222"
        data-border-shadow-width="0"
        data-borders="true"
        data-needle-type="arrow"
        data-needle-width="2"
        data-needle-circle-size="7"
        data-needle-circle-outer="true"
        data-needle-circle-inner="false"
        data-animation-duration="1500"
        data-animation-rule="linear"
        data-color-border-outer="#333"
        data-color-border-outer-end="#111"
        data-color-border-middle="#222"
        data-color-border-middle-end="#111"
        data-color-border-inner="#111"
        data-color-border-inner-end="#333"
        data-color-needle-shadow-down="#333"
        data-color-needle-circle-outer="#333"
        data-color-needle-circle-outer-end="#111"
        data-color-needle-circle-inner="#111"
        data-color-needle-circle-inner-end="#222"
        data-value-box-border-radius="0"
        data-color-value-box-rect="#222"
        data-color-value-box-rect-end="#333"
        data-font-value="Led"
        data-font-numbers="Led"
        data-font-title="Led"
        data-font-units="Led"
></canvas>'''
]

テンプレートへの受け渡しと温度、湿度の読み出し

routes.py
from bottle import route, view
from datetime import datetime
import time,requests,json
import gauges
@route('/')
@route('/home')
@view('index')
def home():
    return dict(
        year=datetime.now().year,gauge=gauges.canvas
    )

global temp, humid,temp1,humid1,press1
temp, humid,temp1,humid1,press1=0,0,0,0,0
@route('/temp',method = "GET")
def temp():
    global temp, humid,temp1,humid1,press1
    try:
        r = requests.post('http://192.168.1.13/temp')
        rx = requests.post('http://192.168.1.13/humidity')
        t=int(r.text)
        h=int(rx.text)
        if t==2147483647 or h==2147483647: return dict(text="",text1="",t=temp,h=humid,t1=temp1,h1=humid1,p1=press1)
        temp, humid=t,h
        rxx= requests.get('http://192.168.1.111:8080/BME280')
        j=json.loads(rxx.text)
        print(j)
        temp1,humid1,press1=j['temp'],j['humid'],j['pressure']
    except:
        dict(text="",text1="",t=temp,h=humid,t1=temp1,h1=humid1,p1=press1)
    tmp=str(datetime.now().strftime('%Y/%m/%d %H:%M:%S'))+"<br>温度:%7.2f℃"%temp+"<br>湿度:%7.2f%"%humid
    print(tmp)
    tmp1=str(datetime.now().strftime('%Y/%m/%d %H:%M:%S'))+"<br>温度:%7.2f℃"%temp1+"<br>湿度:%7.2f%"%humid1+"<br>気圧:%7.2fhp"%press1
    print(tmp1)
    return dict(text=tmp,text1=tmp1,t=temp,h=humid,t1=temp1,h1=humid1,p1=press1)

bootle web site 起動ルーチン

app.py
"""
This script runs the application using a development server.
"""
from gevent import monkey
monkey.patch_all()
import bottle
import os
import sys

# routes contains the HTTP handlers for our server and must be imported.
import routes

#if '--debug' in sys.argv[1:] or 'SERVER_DEBUG' in os.environ:
#    # Debug mode will enable more verbose output in the console window.
#    # It must be set at the beginning of the script.
#    bottle.debug(True)

def wsgi_app():
    """Returns the application to make available through wfastcgi. This is used
    when the site is published to Microsoft Azure."""
    return bottle.default_app()

if __name__ == '__main__':
    PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
    STATIC_ROOT = os.path.join(PROJECT_ROOT, 'static').replace('\\', '/')
    HOST = os.environ.get('SERVER_HOST', 'localhost')
    try:
        PORT = int(os.environ.get('SERVER_PORT', '5555'))
    except ValueError:
        PORT = 5555

    @bottle.route('/static/<filepath:path>')
    def server_static(filepath):
        """Handler for static files, used with the development server.
        When running under a production server such as IIS or Apache,
        the server should be configured to serve the static files."""
        return bottle.static_file(filepath, root=STATIC_ROOT)
    HOST,PORT="0.0.0.0",8080
    bottle.run(server='gevent', host=HOST, port=PORT)

実行

console.txt
# python app.py
Bottle v0.12.17 server starting up (using GeventServer())...
Listening on http://0.0.0.0:8080/
Hit Ctrl-C to quit.

{'temp': 25.661778078996576, 'humid': 35.98232774210494, 'pressure': 1090.1052745508491}
2019/08/17 15:34:34<br>温度:  27.00℃<br>湿度:  43.00%
2019/08/17 15:34:34<br>温度:  25.66℃<br>湿度:  35.98%<br>気圧:1090.11hp
192.168.1.10 - - [2019-08-17 15:34:34] "GET /temp HTTP/1.1" 200 413 0.495693

image.png

お試しあれ

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1