' ' ************************************* ' * Arduino LCD Keypad Shield * ' * 初期設定 Ver. 0.01 * ' * * ' * AVR is ATmega328P * ' * Basic Compiler is BASCOM-AVR * ' * Copyright O-Family 2018. 9.18 * ' ************************************* ' $regfile = "m328pdef.dat" '使用するAVRを設定。 $crystal = 16000000 'AVRクロックを設定。 ' $hwstack = 64 'ハードウェア・スタックの容量を設定。 $swstack = 10 'ソフトウェア・スタックの容量を設定。 $framesize = 24 'フレーム領域の容量を設定。 ' ' * ポート名の定義 * ' Lcd_bkl Alias Portb.2 'LCDのバックライト制御の接続ポート。 ' ' * 変数の宣言 * ' Dim Keydata As Byte 'キー(スイッチ)の入力データ。(押された場合にコードが入る) Dim Keyadcode As Byte 'キー(スイッチ)をA/D変換したコード。(押されている状態のコードが入る) Dim Keystat As Byte , Keyw1 As Word 'キー(スイッチ)の検出状態フラグ。内部で使用する変数。 ' ' * ポートの初期設定 * ' Config Lcd_bkl = Output 'LCDのバックライト制御の接続ポートを出力に設定する。 Set Lcd_bkl 'LCDのバックライトを点灯する。 ' ' * LCDの初期設定 * ' Config Lcdmode = Port 'LCDを4ビットのポートモードに設定。 Config Lcdbus = 4 'LCDデータバスを4bitに設定。 Config Lcdpin = Pin , Db4 = Portd.4 , Db5 = Portd.5 'LCDのポート割り当て。 Config Lcdpin = Pin , Db6 = Portd.6 , Db7 = Portd.7 Config Lcdpin = Pin , E = Portb.1 , Rs = Portb.0 Config Lcd = 16 * 2 'LCD表示を16文字2行に設定。 Cls 'LCD表示をすべて消去。 ' ' * A/Dコンバータの初期設定 * ' Config Adc = Single , Prescaler = Auto , Reference = Avcc 'A/Dコンバータの設定。 Start Adc 'A/Dコンバータに電源を供給する。 Didr0 = &B0011_1111 'デジタル入力禁止レジスタの設定。(アナログ入力ピンをデジタル入力禁止にする) ' ' * シリアルポートの設定 * ' Config Com1 = 9600 , Parity = None , Stopbits = 1 , Databits = 8 'ハードウェアUARTの設定。 '-------------------------------------------------------------------------------------------------- ' ' ******************************************* ' * SEN0193 (静電容量式 土壌水分センサー) * ' * テスト・プログラム * ' * Arduino LCD Keypad Shield 版 * ' * Copyright O-Family 2018.11.27 * ' ******************************************* ' ' Ver A0.01 初回公開バージョン。 2018.11.27 Const Prgver = "A0.01" 'プログラム・バージョン。 ' ' * 変数の宣言 * ' Dim Advalue As Word 'SEN0193センサーの出力A/D変換値。 Dim Voltage As Word 'SEN0193センサーの出力電圧。(x0.01) Dim Threshdry As Word '乾燥時のしきい値。 Dim Threshwater As Word '水中時のしきい値。 Dim Moisture As Byte '水分量の百分率。(0〜100%) ' Dim Temp1 As Byte '汎用テンポラリ変数 Byte型 No.1 Dim Tempw1 As Word '汎用テンポラリ変数 Word型 No.1 Dim Tempw2 As Word '汎用テンポラリ変数 Word型 No.2 Dim Templ1 As Long '汎用テンポラリ変数 Long型 No.1 Dim Tempstr As String * 10 '汎用テンポラリ変数 String型 No.1 Dim Tempstr2 As String * 20 '汎用テンポラリ変数 String型 No.2 ' Dim Dummy As Eram Long 'EEPROM 4バイトのダミーエリア。 Dim Eepprgid As Eram Long 'EEPROM プログラムのID。 Dim Eepthreshdry As Eram Word 'EEPROM 乾燥時のしきい値。 Dim Eepthreshwater As Eram Word 'EEPROM 水中時のしきい値。 ' ' * EEPROMのデータを確認する * ' If Eepprgid <> &H33393130 Then 'If EEPROMが初期値か? Then Eepprgid = &H33393130 'EEPROM プログラムのID。[0193] Eepthreshdry = 1023 'EEPROM 乾燥時のしきい値。 Eepthreshwater = 0 'EEPROM 水中時のしきい値。 End If Threshdry = Eepthreshdry Threshwater = Eepthreshwater ' ' * カスタム文字をLCDに設定する * ' Deflcdchar 0 , &H11 , &H11 , &H11 , &H11 , &H11 , &H11 , &H11 , &H1F 'カスタム文字[カップ1bit]をLCDへ書き込む。 Deflcdchar 1 , &H11 , &H11 , &H11 , &H11 , &H11 , &H11 , &H1F , &H1F 'カスタム文字[カップ2bit]をLCDへ書き込む。 Deflcdchar 2 , &H11 , &H11 , &H11 , &H11 , &H11 , &H1F , &H1F , &H1F 'カスタム文字[カップ3bit]をLCDへ書き込む。 Deflcdchar 3 , &H11 , &H11 , &H11 , &H11 , &H1F , &H1F , &H1F , &H1F 'カスタム文字[カップ4bit]をLCDへ書き込む。 Deflcdchar 4 , &H11 , &H11 , &H11 , &H1F , &H1F , &H1F , &H1F , &H1F 'カスタム文字[カップ5bit]をLCDへ書き込む。 Deflcdchar 5 , &H11 , &H11 , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F 'カスタム文字[カップ6bit]をLCDへ書き込む。 Deflcdchar 6 , &H11 , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F 'カスタム文字[カップ7bit]をLCDへ書き込む。 Deflcdchar 7 , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F , &H1F 'カスタム文字[カップ8bit]をLCDへ書き込む。 ' Cursor Off 'LCDのカーソルをオフにする。 '-------------------------------------------------------------------------------------------------- ' ' ******************* ' * メイン ルーチン * ' ******************* ' Main: ' ' * センサーの出力電圧をA/D変換する * ' Advalue = Getadc(2) 'アナログ入力A2(PC2)をA/D変換する。 Templ1 = 500 * Advalue '5.00V÷1024×10000000(有効5桁*小数点以下2桁)×[A/D値]÷100000 Shift Templ1 , Right , 10 '式を変えて 5.00V×100倍×[A/D値]÷1024 Voltage = Templ1 'SEN0193センサーの出力電圧。(0〜500 x0.01) ' ' * センサーのA/D変換値と出力電圧値をLCDに表示する * ' Tempstr = Str(advalue) '数値変数を文字変数に変換する。 Tempstr2 = "AD:" + Format(tempstr , " 0") Locate 1 , 1 'LCDにA/D値を表示する。 Lcd Tempstr2 Print Tempstr2 ; 'シリアル・ターミナルにA/D値を表示する。 ' Tempstr = Str(voltage) '数値変数を文字変数に変換する。 Tempstr2 = "OV:" + Format(tempstr , "0.00") + "v" Locate 1 , 9 'LCDに電圧値を表示する。 Lcd Tempstr2 Print " " ; Tempstr2 ; 'シリアル・ターミナルに電圧値を表示する。 ' ' * しきい値から水分量を換算してLCDに表示する * ' Tempstr2 = "Moisture:" If Threshdry =< Threshwater Then 'If 乾燥時と水中時のしきい値設定が異常か? Then Tempstr2 = Tempstr2 + "Error!" 'しきい値設定が異常な場合。 ' Else 'しきい値設定が正常な場合。 If Advalue < Threshwater Then 'If A/D値が水中時のしきい値より低いか? Then Tempstr2 = Tempstr2 + "WetOvr" '水中時のオフセット設定が異常な場合。 ' Else 'A/D値の下限が正常な場合。 If Advalue > Threshdry Then 'If A/D値が乾燥時のしきい値より高いか? Then Tempstr2 = Tempstr2 + "DryOvr" '乾燥時のオフセット設定が異常な場合。 ' Else 'A/D値の上限が正常な場合。 Tempw1 = Advalue - Threshwater 'A/D値から水中時のオフセットを差し引く。 Tempw2 = Threshdry - Threshwater '乾燥時と水中時のしきい値の差分を求める。 Templ1 = Tempw1 * 100 '水分量の百分率を求める。 Templ1 = Templ1 / Tempw2 Moisture = Templ1 Moisture = 100 - Moisture '水分量を逆比例に変換する。 ' Tempstr = Str(moisture) '数値変数を文字変数に変換する。 Tempstr2 = Tempstr2 + Format(tempstr , " 0") + "% " ' Locate 2 , 16 'LCDに水分量の絵図を表示する。 Select Case Moisture Case Is < 10 : Lcd "D" '[0〜9%] Case Is < 20 : Lcd Chr(0) '[10〜19%] Case Is < 30 : Lcd Chr(1) '[20〜29%] Case Is < 40 : Lcd Chr(2) '[30〜39%] Case Is < 50 : Lcd Chr(3) '[40〜49%] Case Is < 60 : Lcd Chr(4) '[50〜59%] Case Is < 70 : Lcd Chr(5) '[60〜69%] Case Is < 80 : Lcd Chr(6) '[70〜79%] Case Is < 90 : Lcd Chr(7) '[80〜89%] Case Else : Lcd "W" '[90〜100%] End Select End If End If End If ' Locate 2 , 2 'LCDに水分量を表示する。 Lcd Tempstr2 Print " " ; Tempstr2 'シリアル・ターミナルに水分量を表示する。 ' Waitms 500 '表示間隔の待ち時間。 ' ' * スイッチの検出 * ' Gosub Getkey 'キー(スイッチ)を検出する。 If Keydata = 1 Then Goto Threshset 'If [SELECT]が押されたか? Then Keydata = 0 'キー(スイッチ)の入力をクリアする。 Goto Main '================================================================================================== ' ' * しきい値の設定 * ' Threshset: Cls 'LCDの全画面を消去する。 Lcd "Threshold Set" Do Gosub Getkey 'キー(スイッチ)を検出する。 Loop Until Keyadcode = 0 '全てのキーが離されるまで待つ。 Waitms 30 'チャタリング除去の待ち時間。 Keydata = 0 'キー(スイッチ)の入力をクリアする。 ' Threshset1: Locate 1 , 7 'しきい値をLCDに表示する。 Lcd " Dry:" ; Tempstr = Str(threshdry) '数値変数を文字変数に変換する。 Lcd Format(tempstr , " 0") Locate 2 , 7 Lcd "Water:" ; Tempstr = Str(threshwater) '数値変数を文字変数に変換する。 Lcd Format(tempstr , " 0") ' Threshset2: Tempw1 = Getadc(2) 'アナログ入力A2(PC2)をA/D変換する。 Tempstr = Str(tempw1) '数値変数を文字変数に変換する。 Locate 2 , 1 'LCDにA/D値を表示する。 Lcd Format(tempstr , " 0") ' Gosub Getkey 'キー(スイッチ)を検出する。 If Keydata = 4 Then Goto Swupon 'If [UP]が押されたか? Then If Keydata = 3 Then Goto Swdownon 'If [DOWN]が押されたか? Then If Keydata = 1 Then Goto Swselecton 'If [SELECT]が押されたか? Then Keydata = 0 'キー(スイッチ)の入力をクリアする。 Goto Threshset2 ' ' * 乾燥時のしきい値を設定する * ' Swupon: Threshdry = Tempw1 Keydata = 0 'キー(スイッチ)の入力をクリアする。 Goto Threshset1 ' ' * 水中時のしきい値を設定する * ' Swdownon: Threshwater = Tempw1 Keydata = 0 'キー(スイッチ)の入力をクリアする。 Goto Threshset1 ' ' * しきい値の設定終了 * ' Swselecton: Keydata = 0 'キー(スイッチ)の入力をクリアする。 Eepthreshdry = Threshdry 'EEPROMに保管する。 Eepthreshwater = Threshwater 'EEPROMに保管する。 Do Gosub Getkey 'キー(スイッチ)を検出する。 Loop Until Keyadcode = 0 '全てのキーが離されるまで待つ。 Waitms 30 'チャタリング除去の待ち時間。 Cls 'LCDの全画面を消去する。 Goto Main '################################################################################################## ' ' *********************************************************** メイン・ルーチンで定期的に呼び続けること。 ' * キー(スイッチ)を検出するサブルーチン (抵抗値のA/D変換) * Keydata = キー(スイッチ)の入力データ。(押された場合にコードが入る) ' *********************************************************** Keyadcode = キー(スイッチ)をA/D変換したコード。(押されている状態のコードが入る) ' (0:押されていない, 1:[SELECT] , 2:[LEFT], 3:[DOWN], 4:[UP], 5:[RIGHT]キー) Getkey: Gosub Keyadconv 'キー(スイッチ)の分圧抵抗値をA/D変換する。 If Keyadcode <> 0 Then 'If いずれかのキーが押されているか? Then If Keystat = 0 Then 'If キー入力の検出中か? Then Waitms 30 'チャタリングを除去する待ち時間。 Gosub Keyadconv 'キー(スイッチ)の分圧抵抗値をA/D変換する。 If Keyadcode <> 0 Then 'If いずれかのキーが押されているか? Then Keydata = Keyadcode 'キーが押されたことを通知する。 Keystat = 1 'キーの解放待ちにする。 End If End If Else 'キーが押されていない場合。 If Keystat <> 0 Then 'If キーの解放待ちか? Then Waitms 30 'チャタリングを除去する待ち時間。 Gosub Keyadconv 'キー(スイッチ)の分圧抵抗値をA/D変換する。 If Keyadcode = 0 Then 'If キーが離されているか? Then Keystat = 0 'キー入力の検出中にする。 End If End If End If Return ' ' * キー(スイッチ)の分圧抵抗値をA/D変換するサブルーチン * ' Keyadconv: Keyw1 = Getadc(0) 'キー(スイッチ)の分圧抵抗値をA/D変換する。 Select Case Keyw1 '分圧抵抗のA/D値から押されたキーを判別する。 Case Is > 950 : Keyadcode = 0 'キーが押されていない場合。 Case Is < 50 : Keyadcode = 5 '[RIGHT] キー。 Case Is < 195 : Keyadcode = 4 '[UP] キー。 Case Is < 380 : Keyadcode = 3 '[DOWN] キー。 Case Is < 555 : Keyadcode = 2 '[LEFT] キー。 Case Else : Keyadcode = 1 '[SELECT] キー。 End Select Return ' ' End