| 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 () ;
}
}
|