土壌湿度センサーのデータも一緒に取り込む
どうも、じぇいかわさきです。
ADCをなんとか使えるようになり、土壌湿度センサーも数字で取り込めるようになりました。
ここまで来たら、やはり温湿度と同じように10分毎に土壌の状態を測定して記録していけるようにしたいと思います。
当然ながら、土壌湿度センサー用のコードを今までの温湿度用のコードにマージしていくわけです。
従来と同じ過ちを侵さないためにも、どの部分が初期設定で、どの部分が実際のデータを扱っているのかということを理解しないといけませんね。
それでは今回も頑張ってやっていきましょう。
初期設定値と測定部分を分離する
ざっともう一度土壌湿度センサーのコードを見ていくと、ほとんどが初期設定値のように思えます。
まず最初に読み込むモジュールですが、このモジュールはすべて温湿度測定側でも使っていますので、特に追加するものはありません。
GPIO.setmodeも同じですね。
という事は、以下のコードがADCの初期値設定コードになります。
#read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, True)
GPIO.output(clockpin, False) # start clock low
GPIO.output(cspin, False) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, True)
else:
GPIO.output(mosipin, False)
commandout <<= 1
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(12):
GPIO.output(clockpin, True)
GPIO.output(clockpin, False)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, True)
adcout >>= 1 # first bit is 'null' so drop it
return adcout
# change these as desired - they're the pins connected from the
# SPI port on the ADC to the Cobbler
SPICLK = 11
SPIMISO = 9
SPIMOSI = 10
SPICS = 8
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
# adc #0
adc_pin = 0;
これってほとんどが初期設定値ということになりますね。
従って、実際にデータを取り込んでいる部分はたったこれだけなんです。
while True:
# read the analog pin
moisture = readadc(adc_pin, SPICLK, SPIMOSI, SPIMISO, SPICS)
print("moisture: {0}".format(moisture))
time.sleep(1)
最初の初期設定は、データベースの接続設定の前辺りにとりあえずコピーします。
問題は、計測部分を修正してwhileのループ内に入れ込まなければいけません。
実際に組み込んでみた
データを組み込むには、CSVファイルへの書き込みとデータベースへの書き込みの2つがあります。
まずは、温湿度データの取込後のあたりに土壌湿度のデータを取り込ませます。
取り込んだデータはintになっておりますので、これを文字列に変換します。
moisture = readadc(adc_pin, SPICLK, SPIMOSI, SPIMISO, SPICS)
moisture = str(moisture)
後は、他の変数と同じよに2文字に変えます。
そしてCSVファイルへの書き込みとして、温湿度データの最後にカンマと一緒に追加します。
ms = moisture
thData.write("," .join(map(str,data)) + "," + ms + '\n')
まずこの状態で、本当にCSVファイルに書き込まれるのかを確認。
2021-03-14,18:06:56,23.8,29.0,1023
問題ないようですね。
ここでデータベースのテーブルに1つ列を加えます。また、新規にデータを取り直すので現状のテーブルは一旦削除します。
MariaDB [iot_data]> drop table temp;
新規にmsを追加したテーブルを作成します。
MariaDB [iot_data]> create table temp(date char(10), time char(8), temp char(4), hmdt char(4), mois char(4), PRIMARY KEY(date,time)) charset=utf8mb4;
今度は、Python側でデータを挿入するためのSQL文を作成します。
sql = "INSERT INTO temp(date, time, temp, hmdt, mois) VALUES(%s,%s,%s,%s,%s)"
val = [ds, ts, tm, hm, ms]
これで問題無いと思われますので、早速実行をしてみましょう。
今回はかなり順調にできました。
予測はしていたがエラーが!
すんなり行くとは思っていませんでしたが、やはりエラーが出ました。
しかし、エラーが出ている割に問題なくデータは採取して書き込んでいるようです。
あれ?なんで????
エラーはこんな表記になっており、4つでております。
RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
GPIO.setup(PIN,GPIO.OUT)
どうやらこれは、GPIOは既に定義して使っているよというワーニングのようです。正確にはエラーではないので、普通に動くようなんです。
4つ有ったのは、SPIで設定しているポートが4つ有ったからですね。
これを回避するには、GPIO.cleanup()というコマンドを最後に追加すれば良いらしいのです。
しかし、自分のコードは既に最後に記述されています。但し、コードを読んで思ったのは、何かキーが押されて中断したときのみこのコマンドが実行されるので、毎回テストでコードを実行させると、既に使っているとのワーニングがでるようなんです。
だったら、初期設定のGPIO.setmode()の前に行えばいいんじゃないかと思い、書いてみましたが変化有りませんでした。
このワーニングに書かれているように、Use GPIO.setwarnings(False) とすればよいのようなので、現在はTrue担っていた部分をFalseに変更したら出なくなりました。
本当にこれでいいんかな?
とりあえず、これでなんとか動くようになり、データにも記録されるようになりました。
今度はこれを実際に鉢植えしているなにかに適用してみたいですね。
これで、また1歩前進しました。