Basic Photoresistorクラス |
---|
package JBot ; import stamp.core.*; /** * Basic Photoresistor Class * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class Photoresistor { public int pin ; public int timeout ; public int chargeTime ; public int bias ; public boolean state ; /** * 8.68μs単位でRCの時間の値を得る * * 入力:int pin: 用いるCPU.pin * 入力:boolean state: 初期のRCの状態 * 入力:int timeout: rcTimeの最大の戻り値 * 入力:int chargeTime: RC回路の充電/放電時間 ミリ秒 * 入力:int bias: */ public Photoresistor ( int pin, boolean state, int timeout, int chargeTime, int bias ) { this.pin = pin ; this.timeout = timeout ; this.chargeTime = chargeTime ; this.state = state ; this.bias = bias ; } /** * 8.68μs単位でRCの時間の値を得る * * @returns RC time */ public int rcTime() { // Measure RC time for photoresistor. CPU.setOutput ( pin ) ; CPU.writePin ( pin, state ) ; // 充電回路を設定する CPU.delay ( chargeTime * 10 ) ; // 回路を充電する int result = CPU.rcTime ( timeout, pin, ! state ) ; return ( result > 0 ) ? ( result - bias ) : bias ; } } |
右の図のような回路を下の図のようにブレッドボード上に作ります。 下図ではP6に配線してありますが、回路図どおりにP5につなげてください。 ![]() |
コンデンサの表面には3桁の数字が書いてあります。例えば471と書いてあった場合は471pFとか471μFではありません。これは47×101pFです。従って、ここで使うコンデンサは104と印字してあるものを用います。★コンデンサの読み方![]() |
Photoresistor1 |
---|
import stamp.core.*; import JBot.* ; /** * 基本的なPhotoresistorのテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class Photoresistor1 { public static void main() { Photoresistor leftPhoto = new Photoresistor ( CPU.pin5, true, 250, 2, 0 ) ; Photoresistor rightPhoto = new Photoresistor ( CPU.pin3, true, 250, 2, 0 ) ; while ( true ) { // 左右のphotoresistorのRC時間を測定する // RC時間の測定値を表示する System.out.print ( "L " ) ; System.out.print (leftPhoto.rcTime()) ; System.out.print ( " R " ) ; System.out.println (rightPhoto.rcTime()) ; } } } |
基本的なPhotoresistorのテストプログラム |
---|
import stamp.core.*; import JBot.* ; /** * 基本的なPhotoresistorのテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class Photoresistor2 { public static void main() { Photoresistor leftPhoto = new Photoresistor ( CPU.pin5, true, 250, 2, 0 ) ; Photoresistor rightPhoto = new Photoresistor ( CPU.pin3, true, 250, 2, 30 ) ; while ( true ) { // 左右のphotoresistorのRC時間を測定する // RC時間の測定値を表示する System.out.print ( "L " ) ; System.out.print ((leftPhoto.rcTime()+5)/10) ; System.out.print ( " R " ) ; System.out.println ((rightPhoto.rcTime()+5)/10) ; } } } |
Photoresistor Sensor クラス |
---|
package JBot ; import stamp.core.*; import java.lang.Math.* ; /** * Photoresistor Sensor クラス * * PhotoresistorTaskを用いてphotoresistorセンサーを用いてテストする * 光強度が閾値以下ならば障害物は無い */ public class PhotoresistorSensor extends BaseSensor { protected PhotoresistorSensorTask sensorTask ; protected int direction ; protected int distance ; protected boolean obstacleDetected = false ; protected int lowerLimit ; protected int deadband ; /** * PhotoresistorSensorオブジェクトを作り、タスクをサポートする * * 入力:int leftPin: 用いるCPU.pin * 入力:int rightPin: 用いる CPU.pin * 入力:boolean state: 初期のRCの状態 * 入力:int timeout: 最大のrcTimeの戻り値 * 入力:int chargeTime: RC回路の充電/放電時間 ミリ秒 * 入力:int bias: bias offset, left side >0から right <0を引いたもの * 入力:int lowerLimit: 障害物がないときの最小距離 * 入力:int deadband: */ public PhotoresistorSensor ( int leftPin , int rightPin , boolean state , int timeout , int chargeTime , int bias , int lowerLimit , int deadband ) { sensorTask = new PhotoresistorSensorTask ( this , leftPin , rightPin , state , timeout , chargeTime , bias ) ; this.lowerLimit = lowerLimit ; this.deadband = deadband ; } /** * 障害物が検出されたかどうかを表す * 通常、ポーリング対イベントの時に用いる * * 戻り:障害物が検出された時true */ public boolean obstacleDetected () { sensorTask.checkSensors() ; return obstacleDetected ; } /** * 障害物の初期位置を示す * 左右にある物体の検出は前方とするシンプルな検出システム * * 戻り: 障害物の相対方向 (left, right, etc.) */ public int obstacleDirection () { return direction ; } /** * 指定された方向の障害物の距離を得る * noneという値は何も検出されなかったことを示す * * 入力: 距離を得る方向 * * 戻り: 指定された方向の障害物の距離 */ public int obstacleDistance ( int direction ) { return distance ; } /** * センサー情報に基づいて結果を更新する * 結果が利用できる時にセンサータスクによって呼ばれる * * 入力:int resultLeft: 左側のphotoresistorのrcTimeの結果 * 入力:int resultRight: 右側のphotoresistorのrcTimeの結果 */ protected void saveResults ( int resultLeft, int resultRight ) { // 現在の結果は有効 // 障害物のステータスを保存する switch ( (( resultLeft > lowerLimit ) ? 1 : 0 ) + (( resultRight > lowerLimit ) ? 2 : 0 )) { default: case 0: obstacleDetected = false ; break; case 1: direction = left ; distance = resultLeft ; obstacleDetected = true ; break; case 2: direction = right ; distance = resultRight ; obstacleDetected = true ; break; case 3: // 両方のセンサーは障害物を示している if ( Math.abs ( resultLeft - resultRight ) < deadband ) { // 両方の距離は接近している direction = front ; distance = ( resultLeft > resultRight ) ? resultLeft : resultRight ; } else if ( resultLeft > resultRight ) { // 左のセンサーは高い値 direction = left ; distance = resultLeft ; } else { // 右のセンサーは高い値 direction = right ; distance = resultRight ; } obstacleDetected = true ; break; } } } |
PhotoresistorSensorTaskクラス |
---|
package JBot ; import stamp.core.*; import stamp.util.os.* ; /** * PhotoresistorSensorTaskクラス * * PhotoresistorSensorをサポートする * 他のオブジェクトから直接呼んではいけない */ public class PhotoresistorSensorTask extends Task { protected PhotoresistorSensor sensor ; protected int leftPin ; protected int rightPin ; protected int timeout ; protected int chargeTime ; protected boolean pinState ; protected int resultLeft ; protected int bias ; final static int startChecking = 1 ; final static int startLeftPin = 2 ; final static int startRightPin = 3 ; protected PhotoresistorSensorTask ( PhotoresistorSensor sensor , int leftPin , int rightPin , boolean pinState , int timeout , int chargeTime , int bias ) { this.sensor = sensor ; this.leftPin = leftPin ; this.rightPin = rightPin ; this.timeout = timeout ; this.chargeTime = chargeTime ; this.pinState = pinState ; this.bias = bias ; } /** * 実行中でないかどうかセンサーをチェックする */ protected void checkSensors() { if ( state == stopped ) { // タスクは終了しているので、再度開始する nextState (startChecking) ; start () ; } } /** * photoresistorセンサーをチェックする * バイアスのために四捨五入して補正する. * 範囲外の条件に対処する * * 入力:int pin: チェックするピン * 入力:int bias:もし正の場合差を取るバイアス値 */ protected int rcTime ( int pin, int bias ) { int result = CPU.rcTime ( timeout, pin, ! pinState ) ; // 範囲外の条件に対処する。 つまりtimeoutを超えた時間 if ( result == -1 ) { result = timeout*2 ; // 大きい数を用いる } else if ( bias > 0 ) { // もし値が正だったらバイアス補正する result -= bias ; } return (result+5)/10 ; } /** *マルチタスクのサポート */ public void execute () { switch ( state ) { case startChecking: // Setup to charge circuit CPU.setOutput ( leftPin ) ; CPU.setOutput ( rightPin ) ; CPU.writePin ( leftPin, pinState ) ; CPU.writePin ( rightPin, pinState ) ; // 充電回路に対してdelayを設定する sleep(chargeTime,startLeftPin); break; case startLeftPin: // photoresistorのRCtimeを測定する resultLeft = rcTime ( leftPin, -bias ) ; nextState(startRightPin); break; case startRightPin: // 結果を報告する sensor.saveResults ( resultLeft, rcTime ( rightPin, bias )) ; // stop()にそのまま行く default: case initialState: stop() ; break; } } } |
基本的なPhotoresistorのテストプログラム |
---|
import stamp.core.*; import stamp.util.os.* ; import JBot.* ; /** * 基本的なPhotoresistorのテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class PhotoresistorSensor1 extends Task { PhotoresistorSensor sensor = new PhotoresistorSensor ( CPU.pin5 // left pin , CPU.pin3 // right pin , true // pin state , 250 // rcTime limit , 2 // timeout , 30 // bias , 3 // lower limit , 5 ) ; // deadband public void execute() { // Only uses one state if ( sensor.obstacleDetected ()) { System.out.print ( "Dir=" ) ; System.out.print (sensor.obstacleDirection()) ; System.out.print ( " Dist=" ) ; System.out.println (sensor.obstacleDistance(sensor.obstacleDirection())) ; } else { System.out.println ( ".") ; } } public static void main() { new PhotoresistorSensor1 () ; Task.TaskManager () ; } } |
基本的なPhotoresistor Compassテストプログラム |
---|
import stamp.core.*; import stamp.util.os.* ; import JBot.* ; /** * 基本的なPhotoresistor Compassテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class PhotoCompass1 extends Task { protected JBotInterface jbot = new BasicJBot ( new MultitaskingJBot()) ; protected PhotoresistorSensor sensor = new PhotoresistorSensor ( CPU.pin5 // left pin , CPU.pin3 // right pin , true // pin state , 250 // rcTime limit , 2 // timeout , 30 // bias , 3 // lower limit , 5 ) ; // deadband public void execute() { // 1つの状態のみ用いる if ( sensor.obstacleDetected ()) { if ( sensor.obstacleDirection() <= 45 ) { // 障害物が左にある。右に回転する。 jbot.pivot(jbot.continuousRight) ; } else if ( sensor.obstacleDirection() >= 135 ) { // 障害物が右にある。左に回転する。 jbot.pivot(jbot.continuousLeft) ; } else { // 直前にある jbot.stop() ; } } else { // 障害物はない jbot.stop() ; } } } |
基本的なPhotoresistor Compassテストプログラム |
---|
import stamp.core.*; import stamp.util.os.* ; import JBot.* ; /** * 基本的なPhotoresistor Compassテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class PhotoCompass2 extends Task { protected JBotInterface jbot = new BasicJBot ( new MultitaskingJBot ()) ; protected PhotoresistorSensor sensor = new PhotoresistorSensor ( CPU.pin5 // left pin , CPU.pin3 // right pin , true // pin state , 250 // rcTime limit , 2 // timeout , 30 // bias , 3 // lower limit , 5 ) ; // deadband public void execute() { // 1つの状態のみ用いる if ( sensor.obstacleDetected ()) { if ( sensor.obstacleDirection() <= 45 ) { // 障害物が左にある。右に回転する。 jbot.pivot(jbot.continuousRight) ; } else if ( sensor.obstacleDirection() >= 135 ) { // 障害物が右にある。左に回転する。 jbot.pivot(jbot.continuousLeft) ; } else if ( sensor.obstacleDistance ( 90 ) > 20 ) { // 暗すぎる。停止して待つ jbot.stop() ; } else { // 直前にある jbot.move(jbot.continuousBackward) ; } } else { // 障害物はない jbot.move(jbot.continuousForward) ; } } public static void main() { new PhotoCompass2 () ; Task.TaskManager () ; } } |
基本的なPhotoresistor Compassテストプログラム |
---|
import stamp.core.*; import stamp.util.os.* ; import JBot.* ; /** * 基本的なPhotoresistor Compassテストプログラム * * CPU.rcTimeを用いてphotoresistor回路をテストする */ public class LineFollower1 extends Task { protected JBotInterface jbot = new RampingJBot ( new MultitaskingJBot ()) ; protected PhotoresistorSensor sensor = new PhotoresistorSensor ( CPU.pin5 // left pin , CPU.pin3 // right pin , true // pin state , 250 // rcTime limit , 2 // timeout , 30 // bias , 1 // lower limit , 2 ) ; // deadband public void execute() { // 1つの状態のみ用いる if ( sensor.obstacleDetected ()) { if ( sensor.obstacleDirection() <= 45 ) { // 障害物が左にある。右に回転する。 jbot.pivot(jbot.continuousRight) ; } else if ( sensor.obstacleDirection() >= 135 ) { // 障害物が右にある。左に回転する。 jbot.pivot(jbot.continuousLeft) ; } else if ( sensor.obstacleDistance ( 90 ) > 20 ) { // 暗すぎる。停止して待つ jbot.stop() ; } else { // 直前にある jbot.move(jbot.continuousForward) ; } } else { // 障害物はない jbot.move(jbot.continuousForward) ; } } public static void main() { new LineFollower1 () ; Task.TaskManager () ; } } |