マイコンで取得したデータをSQLサーバーに登録する方法

PC/デジモノ

RaspberryPiにNGINX+MariaDB+PHPの環境を構築する方法を紹介しました。今回はこのSQLサーバーにマイコンからデータを登録する方法を紹介します。

概要

SQLサーバー上にSQLにデータを登録するためのPHPを準備します。マイコンや他のPC(ラズベリーパイなど)からこのPHPを叩くことでデータを登録します。PHPの引数として登録したいデータを指定します。

今回紹介するのはあくまで最も簡易的な方法で、認証等はかけていないため限られたネットワーク内のみで使用してください。

データベースの準備

以下の要件をもつデータベース、テーブルを作成します。

  • データベース名:DB_HOGE
  • テーブル名:TB_HOGE
  • カラム:ID(INT型),YDT(DATETIME型),VAL_A(FLOAT型),VAL_B(FLOAT型)
  • キーはID、自動採番とする。

また、このデータベースにアクセスするためのユーザー(hoge@localhost)を作成し、SELECTとINSERTのみの権限を与えます。ユーザー名とパスワードは適宜変更してください。

実際のコマンド操作は以下のようになります。

$sudo mysql
>CREATE DATABASE DB_HOGE;
>USE DB_HOGE;
>CREATE TABLE TB_HOGE(ID INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
YDT DATETIME, 
VAL_A FLOAT,
VAL_B FLOAT);

>CREATE USER hoge@localhost IDENTIFIED BY 'hoge_password';
>GRANT SELECT,INSERT ON DB_HOGE.TB_HOGE TO hoge@localhost;

>exit

PHPの作成

作成したデータベースにアクセスするためのPHPを作成します。ここではnginxのドキュメントルート/var/www/htmlにinsdata.phpを作成します。

$sudo emacs /var/www/html/insdata.php
<?php
  $dsn= 'mysql:host=localhost;dbname=DB_HOGE';
  $user = 'hoge';
  $pass = 'hoge_password';

  try{
    $pdo = new PDO($dsn,$user,$pass);
  }catch(PDOException $e){
    print_r ("データベース接続失敗");
  }

  if(isset($_GET['valA'])) {
    $valueA = $_GET['valA'];
  }
  if(isset($_GET['valB'])) {
    $valueB = $_GET['valB'];
  }

  $now = date('Y-m-d H:i:s');
  $sql = "INSERT INTO TB_HOGE (YDT,VAL_A,VAL_B) values(:dt,:vl_A,:vl_B)";
  $sth = $pdo -> prepare($sql);
  $sth -> bindValue(':dt',$now);
  $sth -> bindValue(':vl_A',$valueA);
  $sth -> bindValue(':vl_B',$valueB);
  $sth -> execute();
  $pdo = null;
?>

ウェブブラウザから以下のアドレスにアクセスしてみましょう。(サーバーのアドレスが192.168.0.121の場合。適宜修正してください。)

!http://192.168.0.121/insdata.php

ブラウザには何も表示されませんが、データベースのテーブル(DB_HOGE.TB_HOGE)にIDと日時のみ記録されていればOKです。VAL_AとVAL_Bに値を入れたい場合は次のようになります。

!http://192.168.0.121/insdata.php?valA=100&valB=200

再度データベースのテーブルを確認し、指定した値が入っていればOKです。

要するにマイコンからhttpアドレスを叩けばデータベースに登録されるわけですね。

引数の取り扱いにはbindValueを使用しています。直接SQLコマンドを叩いてしまうとSQLインジェクションの危険性がありますのでご注意ください。

ESP32でのスケッチ例

ESP32でのスケッチ例は以下のようになります。20秒ごとにBME280で気圧、気温、湿度を読み取り、気圧と気温をSQLサーバーに送信します。

#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_BME280.h>

Adafruit_BME280 bme;
const char* ssid = "your-ssid";
const char* password = "your-password";

void setup() {
  //BME280接続
  bme.begin(0x76);

  // Wi-Fi接続
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
  }
}

void sendRequest(float press, float temp)
{
  HTTPClient http;
  String url = "http://192.168.0.121/insdata.php?valA=" + String(press) + "&valB=" + String(temp);
  http.begin(url);
  int httpCode = http.GET();
  http.end();
}

void loop() {
  //BME280で測定
  float temp, pressure, humid;
  temp = bme.readTemperature();
  pressure = bme.readPressure() / 100.0F;
  humid = bme.readHumidity();
  // データ送信
  sendRequest(pressure, temp);
  delay(20000);
}

まとめ

データの管理にSQLを利用すると後々データを再利用するのが簡単になります。

とりあえずデータを保存・可視化したい場合にはAmbientのようなサービスが便利ですが、無料プランではデータ数や保存期間に制限があります。一方、自前のサーバーであれば制限なく使用できます。HTTPのアドレスを叩くだけで済むので汎用性も高く、マイコンに限らず他のPCなどからのデータ収集にも役立ちますね。

コメント