Spresenseソースコードその2(鉢底面ヒーター温度測定部)

今回、温度センサーにテキサスインスツルメンツのLMT01LPG(秋月電気で一個150円。秋月サイトだと生産中止サインがでてるけどTiのサイトだと普通に生産中の扱いなんだよなぁ)を使用しています。このセンサーはTO-92パッケージにリード線2本が出てるタイプで出力は温度に比例したパルス数で出力されます。電源を接続すれば動作しますが、繰り返しで延々と温度信号パルスが出るだけなのでパルス数の検出が面倒っぽい。同じセンサーを使った前例を探したところいろんな方がいろんな工夫でひと塊のパルスが出終わったところを検出していました。今回の用途的に水温や気温は数秒おき、底面ヒーターはもっと短い周期が欲しいもののそれでも1秒周期もあれば良いので割り切ってこうなりました。

#include <sdk/config.h>
#include <stdio.h>
#include <stdlib.h>
#include <arch/board/board.h>
#include <arch/chip/pin.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <pthread.h>
#include <unistd.h>
#include "heattemp.h"

float temp_h = 0; //ヒーター温度
int heat_err = 1 ,heat_avgerr = 1; //ヒーター測定エラー
int hold_tmp = 0; //停止ボタン押下信号
pthread_mutex_t mutex_ht = PTHREAD_MUTEX_INITIALIZER;

static int pls_temp1 = 0; //温度センサーパルス計測用1


//PIN_UART2_RXDの割り込みが有効な間、パルスが入力されると
//入力されたパルス数を数えます
void plscount1(void)
{
pls_temp1++;
}

void stpbtn(void)
{
if(hold_flg == 0)
{
hold_tmp = 1;
}else
{
hold_tmp = 0;
}
board_gpio_int(PIN_SPI2_MISO, true); //停止ボタン割り込み無効
}

void* heattemp(void *arg) //ヒーター温度測定、動作
{
board_gpio_config(PIN_UART2_RXD, 0, 1, 0, 0); //D00 センサー入力
board_gpio_config(PIN_UART2_TXD, 0, 0, 1, 0); //D01 センサー制御
board_gpio_config(PIN_SPI2_MISO, 0, 1, 0, 1); //D08 非常停止端子
board_gpio_intconfig(PIN_UART2_RXD, INT_FALLING_EDGE, false, plscount1); //D00 パルス計測割り込み設定
board_gpio_intconfig(PIN_SPI2_MISO, INT_FALLING_EDGE, true, stpbtn); //D08 停止ボタン割り込み設定
board_gpio_write(PIN_UART2_TXD, 0); //ヒーター温度センサー停止

int pls_htadd0 = 0, pls_htadd1 = 0; //ヒーター温度測定異常検知用
int pls_avgerr = 0;

usleep(500*1000); //メインの初期設定待ち

while(1){

_strt:

for(int k0 = 0; k0 < 30; k0++)
{

//計測開始//
board_gpio_write(PIN_UART2_TXD, 1); //ヒーター温度センサー有効
usleep(40*000); //センサー電源ONまで待つ(20ms)
board_gpio_int(PIN_UART2_RXD, true); //センサー計数割り込み有効
board_gpio_int(PIN_SPI2_MISO, true); //停止ボタン割り込み有効

usleep(260*1000); //計測時間指定(3回分)

board_gpio_int(PIN_UART2_RXD, false); //センサー計数割り込み無効
board_gpio_write(PIN_UART2_TXD, 0); //ヒーター温度センサー無効

pls_htadd0 += pls_temp1;

#ifndef NOLOCK //変数ロック
pthread_mutex_lock(&mutex_ht);
#endif
if(pls_temp1 < 100) //測定結果フラグ
{
heat_err = 1;
}
else{
heat_err = 0;
}

if(abs(pls_htadd1 - pls_temp1 * 30) > 7000)
{
heat_avgerr = 1;
}else
{
heat_avgerr = 0;
}

temp_h = pls_temp1 / 48.48 - 50.0; //温度計算

#ifndef NOLOCK //変数ロック解除
pthread_mutex_unlock(&mutex_ht);
#endif

pls_avgerr = 0;
pls_temp1 = 0; //パルス数クリア
usleep(100*1000); //計測間隔を0.4秒に調整

if(hold_tmp == 1) //停止ボタン対応
{
#ifndef NOLOCK //変数ロック
pthread_mutex_lock(&mutex_ht);
#endif

hold_flg = 1;

#ifndef NOLOCK //変数ロック解除
pthread_mutex_unlock(&mutex_ht);
#endif
usleep(400*1000);

if(board_gpio_read(PIN_SPI2_MISO) == 1)
{
goto _strt;
}

usleep(1100*1000);

if(board_gpio_read(PIN_SPI2_MISO) == 0) //ボタン長押しで非常停止処理
{
board_gpio_int(PIN_SPI2_MISO, false);
usleep(1000);

#ifndef NOLOCK //変数ロック
pthread_mutex_lock(&mutex_ht);
#endif

emstp = 1;

#ifndef NOLOCK //変数ロック解除
pthread_mutex_unlock(&mutex_ht);
#endif
}

} else{
#ifndef NOLOCK //変数ロック
pthread_mutex_lock(&mutex_ht);
#endif

hold_flg = 0;

#ifndef NOLOCK //変数ロック解除
pthread_mutex_unlock(&mutex_ht);
#endif
}

if(emstp == 1) //非常停止処理
{
board_gpio_int(PIN_UART2_RXD, false);
board_gpio_write(PIN_UART2_TXD, 0);
break;
}
}
pls_htadd1 = pls_htadd0;
pls_htadd0 = 0;
}
return NULL;
}

ヘッダファイルの中身

#ifndef _INCLUDE_HEATTEMP_
#define _INCLUDE_HEATTEMP_
void* heattemp(void *arg);
#endif

float temp_h; //ヒーター温度
int heat_err; //ヒーター測定エラー
int heat_avgerr;
int emstp; //非常停止フラグ
int hold_flg; //一時停止フラグ

このコードでは3回分のパルス数をカウントし、その平均で温度を算出しています。計測間隔は0.5秒です。これ以外に

  1. 測定エラー検出(パルス数が100未満の時にフラグ立て)
  2. 平均エラー検出(前30回分の平均に対して約15℃分ズレている時にフラグ立て)
  3. 一時停止機能(停止ボタンを短く押すと計測を一時中断。もう一回押すと再開)
  4. 非常停止機能(停止ボタン長押しで計測を停止し数値等全部クリア)

の機能があります。鉢底ヒーターの温度を管理するためのものなので、計測値自体は特に加工せず0.4秒おきに淡々と数値を更新します。

実際の鉢底ヒーターはこんなふうに作っています。

①ヒーターそのものはシートヒーターをA4サイズのアルミ板(1.5mm厚)で挟んでいます
②LMT01LPGを熱伝導性両面テープで貼り付けた上でエポキシでポッティング
③シールド線を接続し熱収縮チューブで保護しました
このヒーターをトロ箱の底に配置、断熱材で覆いました。

This entry was posted in プログラミング, ベランダビオトープ, 園芸, 睡蓮水槽管理装置, 電子工作 and tagged , , . Bookmark the permalink.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA