これは Pololu 3pi Robot User’s Guide ≫ 5.d. Digital inputs and sensors の非公式日本語訳です。
目次
前: 5.c. Motors and Gearboxes
次: 5.e. 3pi Simplified Schematic Diagram
5.d. Digital inputs and sensors
The microcontroller at the heart of the 3pi, an Atmel AVR mega168 or mega328, has a number of pins which can be configured as digital inputs: they are read by your program as a 1 or a 0 depending on whether the voltage is high (above about 3 V) or low (below about 1.5 V). Here is the circuit for one of the pushbutton inputs:
3piの心臓部であるマイコン Atmel AVR mega168 または mega328 にはデジタル入力として構成できるピンがいくつかあります。それらは電圧がHigh(約3V以上)かLow(約1.5V以下)かによって、プログラムからは1または0として読み取られます。1つのプッシュボタン入力の回路を次に示します。
Normally, the pull-up resistor R (20-50 k) brings the voltage on the input pin to 5 V, so it reads as a 1, but pressing the button connects the input to ground (0 V) through a 1 k resistor, which is much lower than the value of R. This brings the input voltage very close to 0 V, so the pin reads as a 0. Without the pull-up resistor, the input would be “floating” when the button is not pressed, and the value read could be affected by residual voltage on the line, interference from nearby electrical signals, or even distant lightning. Don’t leave an input floating unless you have a good reason. Since the pull-up resistors are important, they are included within the AVR – the resistor R in the picture represents this internal pull-up, not a discrete part on the 3pi circuit board.
通常、プルアップ抵抗R(20~50k)が入力ピンの電圧を5Vにするため、1として読み取れますが、ボタンを押すことで、入力ピンは抵抗Rよりもはるかに小さい1kの抵抗を経由してグラウンド(0V)に接続されます。これにより入力電圧は限りなく0Vに近づき、入力ピンは0として読み取れます。プルアップ抵抗が無いと、入力はボタンが押されていないときに"フローティング"になり、信号線上の残留電圧、近くの電気信号からの干渉、または遠く離れた雷でさえ値の読み取りに影響します。正当な理由が無い限り、入力をフローティングのままにしないでください。プルアップ抵抗は重要であるため、AVRマイコンの内部に含まれています。図中の抵抗Rは、3piの回路上にある個別の部品ではなく、この内部プルアップを表しています。
A more complicated use for the digital inputs is in the reflectance sensors. Here is the circuit for the 3pi’s leftmost reflectance sensor, which is connected to pin PC0:
デジタル入力のもっと複雑な使い方は反射率センサーです。PC0ピンに接続された、3piの左端の反射率センサの回路図を次に示します。
The sensing element of the reflectance sensor is the phototransistor shown in the left half of U4, which is connected in series with capacitor C21. A separate connection leads through resistor R12 to pin PC0. This circuit takes advantage of the fact the digital inputs of the AVR can be reconfigured as digital outputs on the fly. A digital output presents a voltage of 5 V or 0 V, depending on whether it is set to a 1 or a 0 by your program. The way it works is that the pin is set to an output and driven high (5 V) to charge the output node. The pin is then set to an input, and the voltage falls as current flows through the phototransistor. Here is an oscilloscope trace showing the voltage on the capacitor (yellow) dropping as current flows through the phototransistor, and the resulting digital input value of pin PC0 (blue):
反射率センサのセンサ素子はU4の左半分に示してあるフォトトランジスタで、コンデンサC21と直列に接続されています。別の接続は、抵抗R12を経由してピンPC0に接続されています。この回路はAVRのデジタル入力がその場でデジタル出力として再構成できることを利用しています。デジタル出力は、プログラムが1または0のどちらをセットしているかによって5Vまたは0Vの電圧を示します。動作方法は、ピンを出力にセットしてHigh(5V)に駆動し、出力ノードを充電します。その後ピンを入力にセットして、電流がフォトトランジスタに流れると電圧が低下します。オシロスコープの軌跡は、電流がフォトトランジスタに流れるとコンデンサの電圧(黄色)が下がることと、PC0ピンのデジタル入力の結果(青色)を示しています。
The rate of current flow through the phototransistor depends on the light level, so that when the robot is over a bright white surface, the value returns to 0 much more quickly than when it is over a black surface. The trace shown above was taken when the sensor was on the edge between a black surface and a white one – this is what it looks like on pure white:
フォトトランジスタを流れる電流の割合は光のレベルに依存するため、ロボットが明るい白い路面上にいるときは黒い路面上にいるときよりもはるかに速く0に戻ります。上記の軌跡は黒い路面と白い路面の境界上にセンサがあるときに撮られました。次の軌跡は、真っ白な路面上にいるようにみえます。
The length of time that the digital input stays at 1 is very short when over white, and very long when over black. The function read_line_sensors()
in the Pololu AVR Library switches the port as described above and returns the time for each of the five sensors. Here is a simplified version of the code that reads the sensors:
デジタル入力が1を保持する時間は白い路面上のときはとても短く、黒い路面上のときはとても長くなります。Pololu AVR Library のread_line_sensors()
関数は、前述のようにポートを切り替えて5つのセンサー毎に時間を返します。次は、センサーを読み取るコードを簡易化したものです。
time = 0;
last_time = TCNT2;
while (time < _maxValue)
{
// Keep track of the total time.
// This implicity casts the difference to unsigned char, so
// we don't add negative values.
unsigned char delta_time = TCNT2 - last_time;
time += delta_time;
last_time += delta_time;
// continue immediately if there is no change
if (PINC == last_c)
continue;
// save the last observed values
last_c = PINC;
// figure out which pins changed
for (i = 0; i < _numSensors; i++)
{
if (sensor_values[i] == 0 && !(*_register[i] & _bitmask[i]))
sensor_values[i] = time;
}
}
This piece of code is found in the file src\PololuQTRSensors\PololuQTRSensors.cpp
. The code makes use of timer TCNT2, which is a special register in the AVR that we have configured to count up continuously, incrementing every 0.4 μs. Basically, the code waits until one of the sensors changes value, counting up the elapsed time in the variable time
. (It is important to use a separate variable for the elapsed time since the timer TCNT2 periodically overflows, dropping back to zero.) Upon detecting a transition from a 1 to a 0 on one of the sensors (by measuring a change in the input port PINC), the code determines which sensor changed and records the time in the array sensor_values[i]
. After the time limit _maxValue
is reached (this is set to 2000 by default on the 3pi, corresponding to 800 μs), the loop ends, and the time values are returned.
このコードスニペットはファイルsrc\PololuQTRSensors\PololuQTRSensors.cpp
の中にあります。このコードはタイマTCNT2を使います。TCNT2はAVRの特殊レジスタであり、0.4us毎に連続的にカウントアップするように構成しています。基本的に、このコードはセンサーの1つが値を変えるまで待ち、変数time
の経過時間をカウントアップします。タイマーTCNT2は周期的にオーバーフローして0に戻るため、経過時間の変数を使うことが重要です。センサの1つで1から0への遷移を(入力ポートPINCの変化の測定によって)検出すると、コードはどのセンサが変化したかを判断し、配列sensor_values[i]
に時間を記録します。制限時間_maxValue
(3piではデフォルトで2000にセットされ、800usに相当します)に達した後は、ループを終了して時間を返します(訳注:配列に記録したセンサ毎の値を返します)。