「IoT」タグアーカイブ

PythonでIoT用ミニマムな簡易APIサーバーを作る

Pythonでミニマム(最小形態)でサーバーを作ってみようと思う。

こんにちは、北神です。

IoTの開発を行う際に、ちょっとテストでサーバーが欲しい!という時に、Linuxを立ち上げアレやコレを入れて、
HTTPのPOSTやGETを取得するサーバーを組むのは時間がかかって仕方がない。

そこで、Pythonでお手軽にAPIサーバーの作り方をまとめていきます。

■ bottleを始めてみる

使うライブラリは「bottle」です。

このbottleは、高性能ではありませんが、数行でサーバーを立ち上げる事ができ、
POSTやGETといったREST-fullの構造を構築する事ができます。
また、HTMLの表示等もできますので、簡易な試験サーバーとして使用する際に重宝します。

早速インストールします

pip3 install bottle

これだけです。
また、bottleは1ソースで構成されたライブラリであることも人気の秘訣であり、以下のULRよりダウンロードすることで使用することも可能です。
https://bottlepy.org/bottle.py

早速、簡単なので以下のソースをテキストに貼り、server.pyと保存してみましょう。

from bottle import Bottle, run , post, get

app = Bottle()

@app.route('/')
def hello():
    return "Hello World!"

run(app, host='localhost', port=8080)

実行してみます。

python3 server.py

すると、コマンドラインには

Bottle v0.12.19 server starting up (using WSGIRefServer())...
Listening on http://localhost:8080/
Hit Ctrl-C to quit.

と表示されますので、試しにブラウザにて

localhost:8080 と入力して表示します。

Hello World! と表示されます。

■ bottleでAPI風を作成

早速API風な機能をつけていきます。

GETの機能は

@app.get('/get')
    def get_acction():
    return "GET Hello!"

で作成でき、

POSTの機能は

@app.post('/post')
    def post_acction():
    return "Post Hello!"

で作成できます。

これで、IoT機器でREST-fullの対応が試せる様になります。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。


まずは、お気軽にお問い合わせください。

ESP32-IDFをWindowsで構築する

ESP32では、公式開発環境のESP32-IDFとAeduinoIDEの二種類の開発環境があります。
今までArduinoで開発してましたが、今回からESP-32-IDFを試してみたいと思います。

■ インストールの方法

 https://dl.espressif.com/dl/esp-idf/?idf=4.4

Online Installerで環境全体のインストールが可能です。

インストール後、デスクトップに「ESP-IDF 4.3 CMD」が登場し、ESP-IDF 4.3 CMDを使用してコマンドを入力します。

■ プロジェクト作成

「ESP-IDF 4.3 CMD」にて、プロジェクトファイルを生成します。
プロジェクトファイルを生成したいディレクトリまでcdコマンドで移動し

idf.py create-project プロジェクト名

例)

idf.py create-project Hello

で、作成ができます。

■ プログラムを編集

プロジェクト名のフォルダにmainフォルダがあり、その中にC言語ソースがあります。
初期では


#include <stadio.h>
void app_main(void)
{

}

が書かれていると思います。

app_mainがmainでない点は、別途Bootloder等があり、app_mainが呼び出されるまで別の処理が先に行われます。

#include <stadio.h>
void app_main(void)
{
    printf("Hello\n");
}

保存し、以下のコマンドを実行します。

idf.py build

最初は時間かかりますが、2回め以降変更がない際は早くコンパイルができます。

※コンパイル中に「FAILED: esp-idf/mbedtls/x509_crt_bundle」というエラーが表示された際

このエラーは、cryptographyがバージョンアップした際に関数の使い方を変更した事が原因です。
問題のバージョンは、cryptographyの35.0.0 – 2021-09-29のものです。
IDF側で対応されてば良いですが、まだ対応されてない際は、以下のコマンドで一つ前のバージョンを使用します。

pip uninstall -y cryptography
pip install cryptography==3.4.8

■ ESP32に書き込む

buildがうまくいったら、以下のコマンドで書き込みます。

idf.py flash -p ポート番号

Windowsの場合、COMポートの指定は以下の例の様にします。

idf.py flash -p COM11

■ ESP32でシリアルモニタを確認する

以下のコマンドでシリアル通信の確認ができます。
デフォルトでは115200bpsになります。

idf.py -p com11 monitor

コマンドを使って、ESP32の開発ができそうです。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

ESP32(Arduino)でタイマー割り込みを使う方法

ESP32(Arduino)でタイマー割り込みが使いたい!定時実行やセンサの状態取得等、一定時間が経過した際に実行させたい場合にタイマー割り込みを使いますが、
そんなタイマー割り込みをArduinoで使う方法をまとめました。

こんにちは、北神です。
ESP32(Arduino)でタイマーが使いたかったので試してみました。
以下のソースを貼り付けるだけで、タイマー割り込みが使用できます。

//===========================================================//
// Timer Interrupt
//===========================================================//
hw_timer_t *timer1 = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR onTimer1()
{
portENTER_CRITICAL_ISR(&timerMux);
// 実行させたい関数をここに記載
example();
portEXIT_CRITICAL_ISR(&timerMux);
}

void Timer1_interrupt_setup(int usec)
{
timer1 = timerBegin(0, getApbFrequency()/1000000, true);
timerAttachInterrupt(timer1, &onTimer1, true);
timerAlarmWrite(timer1, usec, true);
timerAlarmEnable(timer1);
}

実行する際は、
Timer1_interrupt_setup(マイクロ秒) を記述して、その間隔で関数が実行されます。

ESP32では、HTTPの送信や受信で数秒程度、処理に時間がかかりますので、
その間にセンサーやスイッチの立ち上がりだけ見たい! ハードウェア特有の処理を済ませておきたい!という時に割り込みが使用できます。

ただ、何重にも割り込みは発生させることができませんし、割り込み後の処理で時間がかかる処理はご法度ですので、割り込みプログラムには留意が必要です。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

RaspberryPiでプログラムを自動起動する方法

RaspberryPiでせっかく作ったプログラム、毎回コマンドやマウスで動かしてたらキリがない。
まして、電源入れたらひとりでに起動する組み込みで使用したい。自動化どうするんだっけ・・・

こんにちは、北神です。

RaspberryPiで、プログラムを自動起動する方法です。

古きLinuxユーザーの方は、init.dを想像するかもしれませんが、
今ではsystemdという仕組みが物凄く簡単ですので、ぜひsystemdを活用してみてください。

ます、systemdで起動する内容を設定する .serviceというファイルを作成します。
主にテキストのファイルですので、nanoやviで書き込みます。

[Unit]
Description= Custom Service
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/service.py
[Install]
WantedBy=multi-user.target

Sytemdでは、service記述によりたくさんのオプションがあり、細かく設定する事ができます。
上記では、/home/piに保存したservice.pyをPython3で起動する単純な物です。

このファイルを、以下のコマンドでディレクトリにコピーします。
仮に hello.service としましょう。

sudo cp hello.service /etc/systemd/system/
sudo systemctl daemon-reload

これで、Systemdが読みに行けるファイルになりました。

実際に、起動を開始するには

sudo systemctl start hello.service 

終了する際は

sudo systemctl stop hello.service 

で行うだけです。

また、状態の確認は

sudo systemctl status hello.service 

で行えます。

簡単ですね。

最後に、自動起動を設定する際は、

sudo systemctl enable hello.service 

で行い、逆に自動起動を停止する際は

sudo systemctl disable hello.service 

で行えます。

非常に簡単ですので、覚えておいて損はないでしょう。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

RaspberryPiでRAMディスク化する方法

RaspberryPiはLinuxで動いていますが、突然電源を切ってしまうと、ディスクを壊したりOSが起動しなくなる。
そんな問題が起きたりします。

回避のために行った内容をまとめていきます。

こんにちは、北神です。

RaspberryPiは組込み用途を想定された作りをしていない為、所謂「電源のブチ切り」には対応していません。

しかし、次第に組込み用途で使用される事が増え、世界中のエンジニアがアイディアを出し合い、とても良い方法が提案されました。

それは、「overlayfs」です。

この機能は、OSやアプリケーションの設定を変更せずに、起動時は、ディスクをRO(リードオンリー)に設定し、
起動後にアプリが書き込むファイルは、RAM上でRW(リードライト)にする機能です。

もう少し詳しく話しますと、

フォルダのアドレスをRAMやtmpに変更する必要がなく、書き換えや保存も”見かけ上”変更なく同等に実行されます。

しかし、見かけ上問題がないだけで、内部では書き換えや保存はRAM上で行われる為、保存ができたと思っても再起動をしますと保存前に戻ります。

さらに、試して気が付きましたが、書き込みがRAM上で行われる為、起動完了までの時間が少し速くなる事がわかりました。

ただ、ログ等の書き込みがRAMで行われてしまう為、電源を抜くと確認しに行く事ができない事を留意してください。

早速、そのoverlayfsの設定方法ですが

コマンドにて

sudo raspi-config nonint enable_overlayfs

これだけです。
これだけで、Rebootを行うと、起動時にROで立ち上がります。
書き込みや保存は全てRAMに転送されますので、保存されません。
これにより、電源ブチ切りを行っても、SDカードのディレクトリに障害は発生しません。
起動失敗による障害が減ると予想されます。

また、再びディスクに書き込みや保存を行いたい際は

sudo raspi-config nonint disable_overlayfs

を行い、再起動後に書き換えができます。

このoverlayfsに加え、systemd(systemctl)を駆使する事で、組込み用途で使用できるRaspberryPiに変化させる事できます。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

RaspberryPiを用いた組込みや試作にも対応しております。

まずは、お気軽にお問い合わせください。

ESP32でI2Cに接続されたデバイスの一覧を表示する方法(Arduino-IDEを使用)

ESP32でI2Cに接続されたデバイスを確認したい時ありませんか?

どのアドレスにデバイスがつながってるか、一覧で表示して欲しいですよね。

こんにちは、北神です。

RaspberryPiでは、i2cdetectというコマンドがあります。

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- 4a -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

この様な表示のものです。

これを、ESP32でも行いたい。
早速、ESP32(Arduino環境)で行えるライブラリが無いか調べました。

ズバッと、ありました。

https://www.arduinolibraries.info/libraries/i2cdetect

ダウンロードしてライブラリに反映します。

早速サンプルを試してみました。

#include 
#include 
void setup() {
    Serial.begin(115200);
    Wire.begin();
    delay(1000);
}
void loop() {
  i2cdetect();  // default range from 0x03 to 0x77
  delay(2000);
}

試しに、BMX055という9軸加速度センサを試しに接続しました。
このセンサーは、ワンチップですが、それぞれI2Cは3個分(加速度センサ、ジャイロセンサ、磁気センサそれぞれ)あり、
i2cdetectで見ると、3台分のアドレスが表示されました。

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- 13 -- -- -- -- -- 19 -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- 69 -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

これで、センサーのアドレスの確認や状態の認識ができますので、開発もスピーディーに行えると思います。

それでは!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

GPSを使って山手線一周を試してみた

こんにちは、北神です。

今回は「GPS/GLONASS受信機u‐blox M8搭載」を使ってGPSの性能がどの程度かの確認を行いました。

確認を行なった方法は、ノートPCにu‐blox M8を接続しGPSのデータを記録し続けます。簡易的なロガーのような機能です。

この状態で、山手線を一周し、どの程度線路に沿ったデータが取れるかの確認を行いました。

結果はこちら。

GPSで受信したNMEAと呼ばれるメッセージを解析し、緯度と経度をGoogleMapsに反映を行いました。

ドットが細かすぎて潰れた図になっていますが、地図を拡大するとこのように綺麗に線路に沿ったデータが取得できます。

また、GoogleMapsには地図を航空写真に変える機能があり、

こういった地図を見た際に「あれ、山手線ってどこ走っていたっけ?」といった疑問を

こう、実際に乗って見て確認することができました。

今回試したかったGPSの性能としては、そこそこ実用レベルであり、他の分野でも利用することが可能かと思われます。ただ、何箇所かGPSの情報が取得できなかった箇所もあり、アンテナの設置位置や補正方法等の検討は必要そうです。

今回はノートPCをロガーの代わりに試して見ましたが、RaspberryPiやその他の機器に接続して持ち運びが出来た際は、もっと色々な使い方が出てくるんじゃないかと思った次第です。

では。

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

GPSやセンサー、通信に関わる案件お待ちしております。

まずは、お気軽にお問い合わせください。

Electric Imp でI2C

Electric Imp でI2Cを動かす方法

下記は参考に書いたサンプルソースで実際に動く保証をするものではありません
——————————————————————
[Device]
——————————————————————

//6軸加速度センサMPU-6050の値を想定しています。
i2c <- hardware.i2cQP;

//最初に、I2Cを使うことを宣言します。
//i2cQPは、使用するI2Cのポート番号です。
//imp004m impExplorer Kitで使用できるI2Cは i2cQPの
//みなので問題ありませんが、
//モジュールや基板によってはポート番号が変わる場合
//がありますのでご注意が必要で

i2c.configure(CLOCK_SPEED_400_KHZ);
//I2Cのクロックを設定します。I2Cのクロックはセンサーの
//仕様に合わせて設定しますが、基本は400KHzで動作します。

local address = (0x68<<1);
//I2Cでアクセスするセンサーのアドレスを指定します。
//今回使用するセンサーはMPU-6050です。MPU-6050のアドレス
//は b1101000 であり、
//16進数で記述すると0x68になります。 ここではI2Cのアドレス
//を8ビットで表記するので、1ビット分左にずらして指定します。
//readとwriteを使ってデータのやりとりを行います。

i2c.write(address,"\x6B\x00");
//MPU-6050のデーターシートより、0x6Bに0x00を書き込むことで
//Resetが解除され使用開始することができます。
//I2Cでのデータのやりとりは文字列で行います。16進数のデータ
//を\x00と表記して記述します。癖がありますが、慣れると書き
//易いです。
//続いて、readですが、

local result = i2c.read(address,"\x3b", 14);
//と記述します。"/x3b"は、読み出したいレジスタのアドレスで、
//その次の14で読み出すデータサイズを指定します。
//これにより、3軸の加速度データとジャイロデータを読み出す
//ことができます。
//その後、センサーより受け取ったデータを Agent Codeに転送します。
agent.send("reading.sent", result);

——————————————————————
[Agent]
——————————————————————

device.on("reading.sent",stream);
//で受け取り、指定したstream関数を読み出します。

function stream(data) {
server.log(data);
}

//これにより、センサーを受け取ったデータを確認することができます。

文・ソース:北神

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

ImpにArduinoからデータ送りたい。超簡単サンプル。

Arduinoから生き死をアナログデータで送って、imp で受信する方法
ツイッターに送信するサンプル。
impExplorer Kitを使った場合です。

Arduinoのプログラムは送信アナログで3V程度以内の通信にして下さい。
——————————————————————
Device
——————————————————————


#require "WS2812.class.nut:3.0.0"
// スリ―プタイム
const sleepTime = 60;

//はじから3つ目のポート
pot <- hardware.pinK;

// アナログのポート宣言
pot.configure(ANALOG_IN);

// ledの点滅
led <- null

function flashLed() {
    led.set(0, [0,0,128]).draw();
    // Wait 50 ms
    imp.sleep(0.05);
    led.set(0, [0,0,0]).draw();

}

//サーバ側に送る

function poll() {
    // Read the pin and log its value
    server.log("poll read");
    local pot =pot.read()
    server.log(pot);
    agent.send("analog_reading.sent",pot);
    // 送ったらLED光る
    flashLed();
    //impのサーバ待ち時間を設定
    imp.onidle(function() {
        server.sleepfor(sleepTime);
    });

}

// Start of program
// Configure SPI bus and powergate pin for RGB LED
local spi = hardware.spiAHSR;
spi.configure(MSB_FIRST, 6000);
led <- WS2812(spi, 1);

poll();

——————————————————————
Agent
——————————————————————

// ツイッターにクラス
#require "Twitter.class.nut:1.2.1"

// ツイッターの送信
tweeter <- null;
// Define functions

function tweetback(data) {
// ツイッター送った表示
server.log("Tweet tweeted");
}
function motion(data) {
server.log(data);
if(data&amp;amp;gt;100){
local message = format("まだ生きてるぜ[アナログ: %5u]",data);
tweeter.tweet(message, tweetback);
server.log(message);
}
else{
local message = format("死んだぜ[アナログ: %5u]",data);
tweeter.tweet(message, tweetback);
server.log(message);
}

}

// Twitter の own access credentials
// apps.twitter.comでキーをゲットしてね。
tweeter = Twitter("Consumer Key (API Key)***********",
"Consumer Secret (API Secret)***********",
"Access Token***********",
"Access Token Secret***********");

// デバイスから受ける指定
device.on("analog_reading.sent", motion);

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。

第1回高尾山IoT 月刊I/Oとの共同企画

7月某日 月刊I/Oとの共同企画が突然実施された!そう、高尾山IoTです。
月刊I/OのFさんとアバンド代表青木が高尾山に登り、頂上でなんか開発して、下山しながら稼働されるというイベント。

ひとまず登る。

登山中、なぜか、蝶に好かれる。ずーーーーと手に腰に蝶がへばりつく。
チューチュー吸われるw

さくっと山頂と行きたかったが、やはり最後の階段がキツイ。それ以外は楽勝なのでけど。
ひとまず、お決まりの写真

涼しいところを探し、開発開始!灼熱で死ぬ~とか、水曜どうでしょ?的展開を期待したが、心地いい涼しさ。
周囲から変な視線を感じつつ・・・

今回は、ソフトバンク提供の米Electric Impの開発キット!
説明ページコピペw
———————————————————-
「impExplorer Developer Kit」は、「imp004m Breakout Board」の持つ機能に加えて、温度、湿度、気圧、3軸加速度の4つのセンサーを搭載した開発ボードです。本製品は、「imp004m Breakout Board」とは異なり、単3電池3本で稼動し、センサーの設計や組み込み作業を行わずにプログラミングを始めることが可能です。
———————————————————-

さて、さて、まず、あれ、IoTだから、通信から、あれ、WiMAXが入らん!うわーーーーー!
ということで、Fさんのキャリアを借りて、開発・・・・

そして問題発生!
impExplorer Developer Kitのネットワーク設定は、スマフォで設定して、それをimpExplorer Developer Kitにスマフォの画面をかざすと
スマフォの画面点滅により、impExplorer Developer Kitにネットワーク設定ができるという、超親切設計なのですが、
何度やっても、ネットワーク設定ができない。

これでこの企画終わったか?・・・・・・あああ・あああ・・・・
もしっや、明るい?外でやっていて、お日様の光りが明るい?
ということで、手で影を作り、再度挑戦、あ、あ、あ、設定できた。

あとは開発のサンプルを見ながら開発!プラウザー上で開発出来ると結構簡単。

ハマるところサンプルコピペでは動きません
各端末でソースコード内の「hardware.***」を合わせないと動きません。
下記がその一覧に一部です。
https://electricimp.com/docs/api/hardware/spi/
https://electricimp.com/docs/api/hardware/i2c/

温度、湿度、気圧のセンサーで暑いときは「暑い」というメッセージと温度湿度、そして気圧から計算した大まかな高度をツイッターで表示。
https://twitter.com/takaosaniot

impExplorer Developer Kitに電池を入れて、特製wの箱に入れて、IoTデバイス完成!

そして、下山。
谷間等では通信できませんでしたが、温泉までしっかりデータが取れた。


そして、温泉入って、そば食べて終了!

月刊I/Oもあわせて読むとオモロイよ!

株式会社アバンドでは、IoTに関するネットワーク開発、ハードウエア開発を行っております。

まずは、お気軽にお問い合わせください。