22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonAdvent Calendar 2019

Day 3

Micropythonを使ってお手軽簡単IoT生活!

Last updated at Posted at 2019-12-02

本投稿は

Python Advent Calendar 2019 3日目の投稿となります。

Micropython はいいぞー

Raspberry Piはともかくとして
いわゆるESP32系といわれるものは、Wifiがつかえるけど、Arduinoと同じように、プログラムをROM焼きして実行させるような代物で、基本的にはArduinoのIDEを使ったC言語ライクな感じでプログラムを書くわけです。

・・・が

HTTPリクエストがだるいwwww
エッジポイントのデータをSaaSに連携してこそのIoTというのに
HTTPリクエストがだるいと正直やる気なくしますよね・・・。

Arduinoだとこのように書く

Arduino Http Client のサンプルスケッチ

HTTPPost
#include <ArduinoHttpClient.h>
#include <WiFi101.h>

#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
/////// Wifi Settings ///////
char ssid[] = SECRET_SSID;
char pass[] = SECRET_PASS;


char serverAddress[] = "192.168.0.3";  // server address
int port = 8080;

WiFiClient wifi;
HttpClient client = HttpClient(wifi, serverAddress, port);
int status = WL_IDLE_STATUS;

void setup() {
  Serial.begin(9600);
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to Network named: ");
    Serial.println(ssid);                   // print the network name (SSID);

    // Connect to WPA/WPA2 network:
    status = WiFi.begin(ssid, pass);
  }

  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);
}

void loop() {
  Serial.println("making POST request");
  String postData = "name=Alice&age=12";

  client.beginRequest();
  client.post("/");
  client.sendHeader("Content-Type", "application/x-www-form-urlencoded");
  client.sendHeader("Content-Length", postData.length());
  client.sendHeader("X-Custom-Header", "custom-header-value");
  client.beginBody();
  client.print(postData);
  client.endRequest();

  // read the status code and body of the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();

  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);

  Serial.println("Wait five seconds");
  delay(5000);
}

ただPOSTするだけなのに、まぁだるいwww
まぁ慣れればいいんですけど、本当にヤダ・・・

MicroPython を使うためには・・・

とりあえず、基盤が必要です。

基盤

この辺がよいかと思います。

https://www.switch-science.com/catalog/5448/
https://www.switch-science.com/catalog/3210/

Amazonで売っている格安のESP32系でもいいっちゃいいんですけどね
正直技適の問題がありますし、マークがついてたとしても、それが本当に本物の技適かどうかという問題もありますから、この辺はしっかりとしたところから買いましょう。

インストールのやり方はこちらのマニュアルを見ながら実施。

ESP32 での MicroPython の始め方

書き方

MicroPythonは、電源が入ると、まずboot.pyを実行した後に、main.pyが実行されるようになっています。

boot.py

電源が起動されると呼び出される最初のPythonファイルになります。
基本的にはWifiの接続を行うような処理を組み込むとよいですね。

boot.py

import utime
import network
# ==== connecti to wifi access point ============================================
SSID_NAME = <SSID>
SSID_PASS = <WifiPassword>

def connect_wifi(ssid, passkey, timeout=10):
    wifi= network.WLAN(network.STA_IF)
    if wifi.isconnected() :
        print('already Connected.    connect skip')
        return wifi
    else :
        wifi.active(True)
        wifi.connect(ssid, passkey)
        while not wifi.isconnected() and timeout > 0:
            print('.')
            utime.sleep(1)
            timeout -= 1
    
    if wifi.isconnected():
        print('Connected')
        return wifi
    else:
        print('Connection failed!')
        return null

wifi = connect_wifi(SSID_NAME, SSID_PASS)
if not wifi :
    sys.exit(0)

main.py

boot.pyの実行が正常終了すると実行されるPythonファイルとなります。
Arduinoなどを作ったことがある方はご理解いただけると思いますが
基本的に、本Pythonファイルは 無限ループが前提 となります。

main.py

from m5stack import lcd # m5stack Library
import machine
import time

lcd.setCursor(0, 0)
lcd.setColor(lcd.WHITE)
lcd.font(lcd.FONT_DejaVu24)
rtctime = machine.RTC()

def aaaaaa():
    global rtctime
    prm_year = '{:0=4}'.format(timedata[0])
    prm_month = '{:0=2}'.format(timedata[1])
    prm_day = '{:0=2}'.format(timedata[2])
    prm_hour = '{:0=2}'.format(timedata[3])
    prm_minute = '{:0=2}'.format(timedata[4])
    prm_second = '{:0=2}'.format(timedata[5])
    
    prm_datetime =  prm_year + "-" \
                +   prm_month + "-" \
                +   prm_day + "T" \
                +   prm_hour + ":" \
                +   prm_minute + ":" \
                +   prm_second + "Z"


    lcd.print(prm_datetime,10,10)

while True: # 無限ループ
    aaaaaa()
    time.sleep(1)

注意点

パソコンやRaspberry Piほど、潤沢な記憶領域、実行メモリ領域(ヒープ領域)があるわけではありません。
こちらの記事を見てもらうとわかりますが、ぶっちゃけかなり少ないです。

mgo-tec電子工作:ESP32-WROOM-32 チップ・メモリ・MACアドレス情報取得方法

ガリガリなコーディングすると、あっという間にヒープ領域を使いこなして、GCが頻発したり、そもそも作ったPythonファイルが入らないってことが起きたりもしますのでご注意を。

httpリクエストはどうやるの?

Pythonだと、requestsライブラリを使用すると思いますが
MicroPythonの場合は urequests ライブラリを用います。
機能はrequestsライブラリとほぼ変わりません。

urequests

import ujson
import urequests

    def postpowerbi(self):
        pbheaders = {
            'Content-Type' :'application/json'
        }
        body = [
                {
                    "datetime" : self.datetime,
                    "temp" : float(self.temp),
                    "humi" : float(self.humi),
                    "pres" : float(self.pres)
                }
            ]
        body_json = ujson.dumps(body).encode("utf-8")
        res = urequests.post(
            self.posturl,
            data=body_json,
            headers=pbheaders
        )
        res.close()

ほかのライブラリは??

基本的にこちらを見てもらえればよろしいかと・・・

github MicroPython Lib

IoTデバイスのライブラリはどうしているの?

気温センサーなどを多く作っているAdafruitさんなどは、Python向けのライブラリも用意しています。

github Adafruit

こちらを用いることで簡単にIoTデバイスを制御することが可能になります。

Adafruitさんの高いけど、Amazonで売ってる中華製のやつはダメなの?

非推奨ではありますが、使っているセンサーなどの基盤が一致していれば使うことは可能なものもあります。
ただし、トラップもありますので自己責任で。
ライブラリを一部改造する必要があったりもします。
くれぐれも、自社のプロダクトなんかに使うのはやめて、趣味の範囲内でやりましょう。

まとめ

だらだらと書いてしまいましたが、Pythonでも十分安価にオリジナルなIoTデバイスを簡単に作ることができます!
皆さんもぜひ一度試してみてください!

22
14
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
22
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?