見出し画像

土壌湿度センサーのデータも一緒に取り込む


どうも、じぇいかわさきです。

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歩前進しました。


じぇいかわさきです。生産技術者として35年、今まで培った経験とスキルを元に、ものづくりに関わる世の出来事に対して思ったことをホンネで書いてます。ノウハウやアイデアもありますよ。 また写真も全力で撮っています、気に入った写真があればサポートや感想をぜひお寄せください。