工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

土壌水分センサ(DFRobot社Gravityシリーズ)の動作電源電圧の下限を調べる

概要

土壌水分センサ(DFRobot社Gravityシリーズ)の動作電源電圧の下限を調べた。


背景と目的

スイッチサイエンスで売っていた土壌水分センサを使用したいと考えている。動作電圧下限は仕様書上3.3Vである。
今回使用を想定する電源は、ソーラーパネルリチウムイオン電池による約4Vの電源からレギュレータで3.3Vに落とした系で、天気が悪いとリチウムイオン電池に充電できず、3.3Vを供給できないだろう。マイコンは3.3Vを下回っても動くので、このセンサも3.3V以下で使えた方が電池の有効利用になる。そこで、下回った場合の挙動を調べ、3.3V以下でも使えないか調べてみる。


詳細

1. 方法

方法は単純に、

電源電圧を上下させて、センサ出力電圧の変化を見る

とする。上下させる範囲は実験しながら適宜。センシング対象は空気中と水中の2種類。


2. 結果

以下の通り、3Vまでは、センサ出力が変わらず、使えそうだということがわかった。

また、それ以下であっても電源電圧に対して直線的に出力が下がっている。ということは、電源電圧を計測して補正するという手もなくはない。使用予定のマイコンは、2.7Vくらいまで動くので、補正をすればマイコンが動く範囲では2.7Vくらいまで使えるといえる。あるいは、そもそもリチウムイオン電池から直接取る(動作電圧最大5Vに対して、電池は最大でも4.2Vなので)方が楽かもしれない。


まとめと今後の課題

土壌水分センサ(DFRobot社Gravityシリーズ)の動作電源電圧の下限がわかったので、これを考慮して回路構成を考えたい。


ApacheでFlask Appをデーモンで動かすためのメモ

ApacheでFlask Appをデーモンで動かすときにつまずいたのでメモしておく。 そもそも、なぜデーモンで動かしたいかというと、

デーモンにしない場合、セッション毎(というかアクセス元IPアドレス?何で判断しているのかよくわからないが)に、アプリが別プロセスで立ち上がって、セッションにかかわらず共有したいデータが共有できなかった。例えば、今何人がログイン済みか、みたいなデータはデータベースを使用する手もあるが、データベースを使用せずとも、アプリ上で保持して共有したい場合に、不便。

なので、デーモンにして、立ち上がるプロセスを1つにして共有したい。

前提条件

  • Apache 2.4
  • mod_wsgiでflaskアプリと連携する
  • Apacheの実行ユーザーはwww-dataとする
  • アプリの実行ユーザー、アプリの実行グループはmyappuserとする
  • /www/myapp に、アプリのソースコード(adopter.wsgiなど)置く。


設定ファイル

.confファイルのWeb上にある情報が非常に雑多で、いろいろなパラメータが書いてあったりなかったりする。なので、どれが正しいのかよくわからず、カットアンドトライになってしまったが、 ハマったポイントとしては、

  • アプリの実行ユーザー名のディレクトリが、home以下にないとだめなので、作成しておく。(ユーザー作成時にディレクトリ作らなかった場合は注意)作成しないと以下のエラーが出る。
Unable to change working directory to home directory '/home/***'
  • WSGIDaemonProcessの各パラメータを忘れない。socket-userなど。
  • WSGIDaemonProcessのプロセスグループ名とWSGIProcessGroupのプロセスグループ名はちゃんと合わせる
  • WSGISocketPrefixを指定する。指定しないとアプリのプロセスが見つからずApacheが通信できない旨のエラーが出る

/etc/apache/conf.d/myapp.conf

LoadModule wsgi_module path/to/mod_wsgi-py35.cpython-35m-arm-linux-gnueabihf.so

WSGIPythonHome Python本体のあるディレクトリパス
WSGIPythonPath Pythonが参照するパス、必要に応じて
WSGISocketPrefix /var/run/wsgi

<VirtualHost *>
    WSGIDaemonProcess プロセスグループ名 user=myappuser group=myappuser threads=整数 socket-user=www-data
    WSGIScriptAlias / /www/myapp
    KeepAliveTimeout 3600 # 必要に応じて

    <Directory /www/myapp>
        WSGIProcessGroup プロセスグループ名
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On
        Require all granted
    </Directory>
</VirtualHost>

LEDバーライトの自動操作

概要

LEDバーライトの自動操作を自動操作するための改造を行った。


背景と目的

最近、LEDバーライトを使用することになった。希望とする仕様としては、

  • 給電直後から点灯する
  • 明るさ、色の調整ができて、給電遮断後も記憶できる

という2点。しかし、購入前にこう言った細かい仕様は書いていないので、とりあえず、手ごろな値段で明るさ、色の調整ができるASSEUI WD-LED-1308Bという製品を買った。

www.amazon.co.jp

入手後、さっそく使ってみたところ、やはり上記の通りの仕様にはなっていなかった。仕方がないので、少し改造を施して自動で設定されるようにする。


詳細

1.改造方法の検討

この製品には、操作ボタンがついているが、試しにボタンのカバーを開けてみると、以下のような基板が出てきた。タクトスイッチが載っており、片側がGND、片側が基板上のマイコンの入力につながっており、操作するとGNDとつながってLOW信号が基板上のマイコンに入力されるようだ。なので、タクトスイッチの代わりに電子的に操作できるように制御信号線を繋いで乗っ取れば操作できそうだ。

f:id:dekuo-03:20200711171726j:plain


2.回路の改造

実現すべきことは、以下。

  • 点灯ボタン、暗くするボタン、調色ボタンを自動操作できる
  • 改造後にもボタン操作は使えるようにする

検討した結果、回路は以下のようにする。外部に操作ボタン乗っ取り用マイコンとしてAttiny85を用意し、電源はLEDバーライト基板からいただく。3本のGPIO出力で3つのタクトスイッチを乗っ取る。また、点灯しているかどうかを知る手段として、LEDの駆動パルス信号を乗っ取り用マイコンに取り込む。(後述のハードウェア実装を参照)今回はやっていないが、この駆動パルス幅を読み取って、明るさ設定値を知ることができるので、将来的に、明るさを自動的に調整するときに役立つ。 なお、乗っ取り用マイコン側のGPIOとタクトスイッチの間に入れているダイオードは、ボタン操作時に、Attiny85側のGPIOがGNDとショートするのを防ぐため。(適当な大きさの抵抗でもいいが)

f:id:dekuo-03:20200711171309p:plain


3.ハードウェア実装

上記の改造を施した結果が以下。基板がむき出しだが、どうせ人の手で操作するわけでもないし、見えるところに出さないので後で適当に養生テープか何かでカバーする。

黄色いリード線は、LEDの駆動パルスのラインから信号をもらってAttinyのPB0に入力している。 ※ダイオードの代わりに抵抗がついているがこれは検討中のもの。

f:id:dekuo-03:20200711171734j:plain f:id:dekuo-03:20200711171741j:plain


4.マイコンソフトウェア

マイコンは、Attiny85の載る以下の小型ボード。

Amazon | HiLetgo® 3個セットDigispark Kickstarter Attiny85 マイクロ USB 開発ボード Arduino ATtiny MCUに対応 [並行輸入品] | ブレッドボード | 産業・研究開発用品 通販

3年近く前に買って、動作確認した程度で、ろくに使わずに眠っていたものだが、ついに日の目を見る時が来た。

blog.livedoor.jp

Arduino環境で開発ができるのだが、3年もたつと以前と同じ環境が使えるのか不安ではあったが、あっさり同じ方法で書き込み出来た。

ソースコードは、以下。 電源投入後、GPIO設定して、点灯、色味、明るさの順で自動操作とやるだけ。

#define GPIO_DRIVE 0 // 出力
#define GPIO_POWER 1 // 電源ボタン
#define GPIO_COLOR 2 // 調色ボタン
#define GPIO_DARK 3 // 暗くするボタン
#define PULSE_WDITH 50 // パルス幅
#define DELAY_WAIT 100 // 待ち時間
#define DELAY_BOOT 1000 // 起動後待ち時間
#define DELAY_CHECK 10 // usec

// パルス出力
void pulse(int gpio) {
  digitalWrite(gpio, LOW);
  delay(PULSE_WDITH);
  digitalWrite(gpio, HIGH);
}

// 出力のチェック
int check_output(int n) {

  int k = 0;
  int c = 0;

  for (k = 0; k < n; k++) {
    if (digitalRead(GPIO_DRIVE) == HIGH) {
      c++;  
    }
    delayMicroseconds(DELAY_CHECK);
  }

  return c;
  
}

// 電源ON
void power_on() {

  // 出力が0ならパルス出力
  while (check_output(100) == 0) {
    pulse(GPIO_POWER);
    delay(DELAY_WAIT);
  }

}

// 色
void set_color() {
  
  pulse(GPIO_COLOR);
  
}

// 明るさをn段下げる
void darken(int n) {
  int i;
  for (i = 0; i < n; i++) {
    pulse(GPIO_DARK);
    delay(DELAY_WAIT);
  }
}

void setup() {
  
  // GPIO設定
  digitalWrite(GPIO_POWER, HIGH);
  pinMode(GPIO_POWER, OUTPUT);
  digitalWrite(GPIO_POWER, HIGH);
  pinMode(GPIO_COLOR, OUTPUT);
  digitalWrite(GPIO_COLOR, HIGH);
  pinMode(GPIO_DARK, OUTPUT);
  digitalWrite(GPIO_DARK, HIGH);
  pinMode(GPIO_DRIVE, INPUT);

  // 点灯
  power_on();
  delay(DELAY_WAIT);

  // 明るさを下げる
  darken(5);
  delay(DELAY_WAIT);

  // 色を変える
  set_color();
  
}

void loop() {
                     
}


5.動作確認

以下のように、ちゃんと動いた。電源投入後、少し時間がかかるのは、Attiny85の起動に時間がかかっているせいと思われる。(Arduinoブートローダって重いのかな?)

www.youtube.com


まとめと今後の課題

無事、自動操作できるようになった。これで、ちゃんと使えそう。