水耕栽培にプログラムを導入しましょう😀なんといっても便利です。自分で好きなように組めますよー⭐️。水耕栽培のプログラムを書いているサイトがないので参考になると思います!一歩進んだ水耕栽培を始めましょう!
水耕栽培の設定をブラウザで設定します。どこでもアクセスOK !
いろいろ考えていたのですが、結局はどこでもアクセスできるのがいいかなと思ってラズベリーパイにApacheサーバーを入れてPHPで設定画面を表示できるようにしました。下の画面のようになるのですが、結構便利ですよー。
水色の枠で囲んだ部分で設定した”しきい値”に対して現在の明るさ(Lux)を比較しています。今は240Luxで設定しきい値が100LuxなのでLED照明がOFFってるという意味です。
赤のエリアはLEDのセッティングです。赤だけ・青だけ照射したいということを考えてSource #1 / #2を作ってみました。PWM dutyも設定できます。PWM dutyについては以前の記事を参考にしてください。Lux threshが明るさのしきい値を設定します。
緑のエリアはポンプの設定です。下のAddで追加します。追加した設定は上のRemoveで消せます。暑い時期はポンプ起動の時間と回数を増やしてあげて酸素の供給を増やしたい!って場合もすぐ対応できます。
ラズベリーパイの導入方法については別記事でご紹介します。(というのも記事で紹介するために新規インストールしなきゃなので、、)
水耕栽培プログラムの構成
PHPは左のブラウザ画面で表示される設定画面を作ります。真ん中の設定ファイルを編集する役目があります。
右側のプログラムでLEDとPumpを制御します。
プログラムを二つに分けた意味はなくて、ポンプ用のPython programに入れても問題ないです。今のシステムでは先にLEDプログラムのみできていて、その時は設定と実行をPHP同士で統一しました。後から入れたPumpの時には別にこだわる必要ないな、、と感じてMutithreadが簡単に作れるPythonを入れたという感じです。
準備したプログラムはApacheのフォルダにおきます。
ApacheでPHPを動かすためには/var/www/html/の下にファイルを置く必要があります。他のProgramも作るかもしれないのでHomeVegetableフォルダを作りました。
サンプルプログラムです。
Sample Hydroponics program for DIY
※もし使用なさるようでしたら自己責任でお願いします。
ブラウザ用のプログラム
ブラウザに表示させるためにPHPで作成しています。我が家の設定ではpi3.localがラズベリーパイの名前です。setting.phpという名前です。
http://pi3.local/HomeVegetable/setting.php
- LED用のsetting fileはsetting.ini
- Pump用はscheduleWaterCirc.ini
という名前です。
luxByTsl2561()という関数が出てきますがこれは別の記事でご紹介すると思います。Luxを取得するためのI2C moduleです。
upper_red / upper_blueという言葉が出てきますが、最初は赤と青を別々に制御していたのでその名残です。外から見える我の水耕栽培が家が赤と青が混ざってたり、赤のみ・青のみで光っていたりと、規模が大きいシステムなので怪しかったのでやめました。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
<?php require("lib_gpio.php"); require("lib_i2cCmd.php"); define("GPIO_RUN_STATUS", 21); define("GPIO_PWM", 1); define("GPIO_UPPER_RED", 4); define("GPIO_UPPER_BLUE", 17); //setting file read $ini = parse_ini_file('setting.ini'); $setting_pwm_duty = $ini['setting_pwm_duty']; $luxThresh = $ini['setting_lux_threshold']; $upperRedStatus = $ini['setting_upper_red']; $upperBlueStatus = $ini['setting_upper_blue']; // init $systemRunStatus = gpio_read(GPIO_RUN_STATUS); if($systemRunStatus == GPIO_HIGH){ print("initializing process worked\n"); gpio_pwm_init(); gpio_mode(GPIO_UPPER_RED, GPIO_OUT); gpio_write(GPIO_UPPER_RED, $ini['setting_upper_red']); gpio_mode(GPIO_UPPER_BLUE, GPIO_OUT); gpio_write(GPIO_UPPER_BLUE, $ini['setting_upper_blue']); //set initializing process close gpio_write(GPIO_RUN_STATUS, GPIO_LOW); } //Upper Shelf Red if(isset($_POST['upperShelfRed'])){ if($_POST['upperShelfRed'] == 'UpperShelfRedOn'){ $upperRedStatus = GPIO_HIGH; } else { $upperRedStatus = GPIO_LOW; } $ini['setting_upper_red'] = $upperRedStatus; } //Upper Shelf Blue if(isset($_POST['upperShelfBlue'])){ if($_POST['upperShelfBlue'] == 'UpperShelfBlueOn'){ $upperBlueStatus = GPIO_HIGH; } else { $upperBlueStatus = GPIO_LOW; } $ini['setting_upper_blue'] = $upperBlueStatus; } //Lux setting if(isset($_POST['luxThresh'])){ $luxThresh = $_POST['luxThresh']; if(ctype_digit($luxThresh)){ $ini['setting_lux_threshold'] = $luxThresh; } } $currentLux = luxByTsl2561(); if($currentLux > $luxThresh){ $msg = sprintf("Bright Lux:%d", luxByTsl2561()); echo $msg; gpio_write(GPIO_UPPER_RED, GPIO_LOW); gpio_write(GPIO_UPPER_BLUE, GPIO_LOW); } else { $msg = sprintf("Dark Lux:%d", luxByTsl2561()); echo $msg; gpio_write(GPIO_UPPER_RED, $ini['setting_upper_red']); gpio_write(GPIO_UPPER_BLUE, $ini['setting_upper_blue']); } //PWM if(isset($_POST['duty'])){ $duty = $_POST['duty']; if(ctype_digit($duty)){ gpio_pwm_setDuty($duty); //$msg = sprintf("PWM duty ratio is set to %d", $duty); //echo $msg; $ini['setting_pwm_duty'] = $duty; } } //update initial file $fp = fopen('setting.ini', 'w'); foreach($ini as $key => $value) fputs($fp, "$key=$value\n"); fclose($fp); //water circulation $file = fopen('scheduleWaterCirc.ini', 'rb'); flock($file, LOCK_SH); $settings =array(); while($line = fgetcsv($file,1024,":")){ $elements = array(); $elements['HOUR'] = $line[0]; $elements['MIN'] = $line[1]; $elements['RUN'] = $line[2]; array_push($settings, $elements); } fclose($file); if($_POST['action'] == 'remove'){ //if(isset($_POST['schedule'])){ unset($settings[$_POST['scheduleRemove']]); $settings = array_values($settings); $file = fopen('scheduleWaterCirc.ini', 'wb'); flock($file, LOCK_SH); foreach($settings as $elements){ fwrite($file, implode(":", $elements)."\r\n"); } fclose($file); } if($_POST['action'] == 'add'){ // $newAdd = sprintf("At %02d:%02d %02dmin Run",$_POST['scheduleAddHour'],$_POST['scheduleAddMin'],$_POST['scheduleAddRun']); // print $newAdd; $i=0; $j=0; $elements = array(); $elements['HOUR'] = $_POST['scheduleAddHour']; $elements['MIN'] = $_POST['scheduleAddMin']; $elements['RUN'] = $_POST['scheduleAddRun']; array_push($settings, $elements); //sort $sortVal = array(); for($i=0;$i<count($settings);$i++){ array_push($sortVal, ($settings[$i]['HOUR']*100 + $settings[$i]['MIN'])); } for($i=1; $i<count($sortVal);$i++){ $tmp = $sortVal[$i]; for($j=$i-1; $j>=0 && $sortVal[$j] > $tmp; $j--){ $sortVal[$j+1] = $sortVal[$j]; } $sortVal[$j+1] = $tmp; } //print_r($sortVal); //create new array $newSettings = array(); for($i=0; $i < count($sortVal); $i++){ for($j=0; $j < count($settings); $j++){ if($sortVal[$i] == ($settings[$j]['HOUR']*100 + $settings[$j]['MIN'])){ array_push($newSettings, $settings[$j]); } } } // print_r($newSettings); $settings = $newSettings; $file = fopen('scheduleWaterCirc.ini', 'wb'); flock($file, LOCK_SH); foreach($settings as $elements){ fwrite($file, implode(":", $elements)."\r\n"); } fclose($file); } ?> <!DOCTYPE html> <html <head> <meta charset="utf-8"> <title>Hydropnics</title> </head> <body> <header> <div class="header"> </div> </header> <div id="contents"> <section> <div class="wmain"> <form action="" method="POST"> Upper Shelf Red <input type="radio" name="upperShelfRed" value="UpperShelfRedOff" <?php if($upperRedStatus == GPIO_LOW){echo 'checked';} ?>>Off <input type="radio" name="upperShelfRed" value="UpperShelfRedOn" <?php if($upperRedStatus == GPIO_HIGH){echo 'checked';} ?>>On <br> Upper Shelf Blue <input type="radio" name="upperShelfBlue" value="UpperShelfBlueOff" <?php if($upperBlueStatus == GPIO_LOW){echo 'checked';} ?>>Off <input type="radio" name="upperShelfBlue" value="UpperShelfBlueOn" <?php if($upperBlueStatus == GPIO_HIGH){echo 'checked';} ?>>On <br> PWM duty <input type="text" name="duty" value="<?=$ini['setting_pwm_duty'] ?>" size="15"> <br> Lux threshold <input type="text" name="luxThresh" value="<?=$ini['setting_lux_threshold'] ?>" size="15"> <br> <input type="submit" name="setDuty" value="update" /> </form> </div> </section> <form action="" method="POST"> <select name="scheduleRemove" size=<?php print "\"".count($settings)."\">"; ?> <?php for($i=0;$i < count($settings);$i++){ $oneList = sprintf('At %02d:%02d %02dmin Run', $settings[$i]['HOUR'], $settings[$i]['MIN'], $settings[$i]['RUN']); print '<option name="selectSchedule" value='.$i.'>'; print $oneList; print '</option>'; } ?> </select> <br> <input type="submit" name="action" value="remove" /> </form> <form action="" method="POST"> <select name="scheduleAddHour"> <?php for($i=0;$i<24;$i++){ if($i == 12){ print '<option value=12 selected>'; } else{ print '<option value='.$i.'>'; } print $i; print '</option>'; } ?> </select> <select name="scheduleAddMin"> <?php for($i=0;$i<60;$i++){ if($i == 30){ print '<option value=30 selected>'; } else{ print '<option value='.$i.'>'; } print $i; print '</option>'; } ?> </select> <select name="scheduleAddRun"> <?php for($i=1;$i<=10;$i++){ if($i == 5){ print '<option value=5 selected>'; } else{ print '<option value='.$i.'>'; } print $i; print '</option>'; } ?> </select> <br> <input type="submit" name="action" value="add" /> </form> </div> </body> </html> |
LED制御用のプログラム
RunHydroWithLux.phpという名前です。crontabコマンドで定期的に呼び出しています。
1 2 |
# m h dom mon dow command */10 * * * * /usr/bin/php5 /var/www/html/HomeVegetable/RunHydroWithLux.php |
ファイルの中身です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php require("lib_gpio.php"); require("lib_i2cCmd.php"); define("GPIO_RUN_STATUS", 21); define("GPIO_PWM", 1); define("GPIO_UPPER_RED", 4); define("GPIO_UPPER_BLUE", 17); //setting file read $ini = parse_ini_file('setting.ini'); $luxThresh = $ini['setting_lux_threshold']; // init $systemRunStatus = gpio_read(GPIO_RUN_STATUS); if($systemRunStatus == GPIO_HIGH){ print("initializing process worked\n"); gpio_pwm_init(); gpio_mode(GPIO_UPPER_RED, GPIO_OUT); gpio_write(GPIO_UPPER_RED, $ini['setting_upper_red']); gpio_mode(GPIO_UPPER_BLUE, GPIO_OUT); gpio_write(GPIO_UPPER_BLUE, $ini['setting_upper_blue']); //set initializing process close gpio_write(GPIO_RUN_STATUS, GPIO_LOW); } $currentLux = luxByTsl2561(); if($currentLux > $luxThresh){ $msg = sprintf("Bright Lux:%d", luxByTsl2561()); echo $msg; gpio_write(GPIO_UPPER_RED, GPIO_LOW); gpio_write(GPIO_UPPER_BLUE, GPIO_LOW); } else { $msg = sprintf("Dark Lux:%d", luxByTsl2561()); echo $msg; gpio_write(GPIO_UPPER_RED, $ini['setting_upper_red']); gpio_write(GPIO_UPPER_BLUE, $ini['setting_upper_blue']); } ?> |
Pump制御用のProgram
PyWaterCirc.pyです。60秒毎に確認するようになっています。Pumpの制御には自作したACコンセントを使います。作り方はこちらを参照してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
#!/usr/bin/python # config: UTF-8 from datetime import datetime import threading import time import RPi.GPIO as GPIO PORT = 23 print "Start Water Circulation" def init(): GPIO.setmode(GPIO.BCM) GPIO.setup(PORT, GPIO.OUT) GPIO.output(PORT,False) def checkTimer(): f = open('scheduleWaterCirc.ini') lines = f.readlines() f.close() schedule = [] for line in lines: tmp = (line.rstrip('\r\n')).split(":") setting = {} setting['HOUR'] = int(tmp[0]) setting['MIN'] = int(tmp[1]) setting['ONTIME'] = int(tmp[2]) schedule.append(setting) # current time curTime = "%s" % (datetime.now().strftime('%H%M')) # flag to indicate schedule setting is match to current time flgRun = False sleepSec = 0 for setting in schedule: cmprTime = "%02d%02d" % (setting['HOUR'],setting['MIN']) if curTime == cmprTime: print "Scheduled event %s, run %02d min " % (cmprTime, setting['ONTIME']) flgRun = True sleepSec = setting['ONTIME'] * 60 # if scheudled event is found, PORT for water circuration is set to high. if flgRun == True: GPIO.output(PORT, True) time.sleep(sleepSec) GPIO.output(PORT, False) t=threading.Timer(10,checkTimer) t.start() init() t=threading.Thread(target=checkTimer) t.start() |
まとめ
自作の水耕栽培装置に使っているプログラムを紹介しました。ブラウザで確認できる仕様としましたが、他の方法でも内容自体は応用できると思います。
記事を読んでいただいてありがとうございます。この記事がいいなと思ったら下記のSNSボタンのクリックをお願いします。励みになります😁