5.d Entradas digitales y sensores
El microcontrolador es el corazón del 3pi, un ATmegaxx8 contiene un número de
pins que pueden configurarse como entradas/salidas digitales que leerán desde el
programa los 1 o 0 dependiendo de si el voltaje es alto (hasta 2V) o bajos (0V). Un
circuito de entrada con un pulsador podría ser el de la figura en donde una
resistencia de entre 20 a 50k agarra el voltaje de 5V y lo lee como 1. Al pulsar el
botón, el voltaje va a GND y se lee 0. Quitando la resistencia de pull-up la entrada
quedaría "flotando" mientras el botón no se pulsa y el valor podría quedar alterado
por el voltaje residual de la línea, interfiriendo en las señales que de ahí dependan. Por eso las
resistencias de pull-up son importantes y en este caso la hemos representado en el circuito como
AVR pudiendo reconfigurarse sobre la marcha. Las salidas digitales alternan el voltaje de 5V o
0V y se traducen en 0 y 1 según el programa. El condensador se carga temporalmente si la
entrada lee 1 mientras el voltaje almacenado fluye a través del transistor. Aquí vemos la señal,
en un osciloscopio, del voltaje del condensador (amarillo) pasando al transistor y el resultado
digital de la entrada de valor al pin PC0 (azul). La cantidad de corriente que fluye a través del
fototransistor depende del nivel de luz reflejada, de modo que cuando el robot está en una
superficie blanca brillante, el valor 0 se devuelve con mucha más rapidez que cuando está sobre
una superficie de color negro. La marca mostrada arriba está tomada en el momento en que el
sensor llegaba al punto de separación entre la superficie de color negro y la superficie blanca. El
tiempo en que la señal digital está a 1 es más corto sobre la blanca y más larga cuando está sobre
la negra. La función
cada uno de los cinco sensores. Esta es una versión simple del código:
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;
}
}
Este código se encuentra en el fichero PololuQTRSensors.cpp. El código hace uso del
temporizador TCNT2 en un registro especial del AVR configurado para contar continuamente,
cada 0,4 uS. Cuenta los cambios de valor del sensor durante el tiempo almacenado en la variable
time. (es importante usar variables separadas para contar el tiempo transcurrido, ya que el
TCNT2 periódicamente se rebosa y empieza de 0. Una vez detectada la transición entre 1 y 0 en
uno de lo sensores (midiendo el cambio en la entrada del PINC) el código determina que sensor
a cambiado y almacena el tiempo en la matriz sensor_values[i]. Después de leer el
tiempo limite _maxValue (ajustado a 2000 por defecto en el 3pi que corresponden a 800uS), el
bucle termina y devuelve el valor de los tiempos.
R.Las señales procedentes de los sensores de reflexión son algo
más complicadas. Aquí vemos un circuito del censor de reflexión
conectado al PC0.
El elemento de reflexión del sensor es un fototransistor en U4 que
se conecta en serie con el condensador C21. Una conexión
separada (por luz) del emisor y que va por R12 al pin PC0. Este
circuito tiene la ventaja de aprovechar las señales digitales del
read_line_sensors()
de la librería Pololu AVR devuelve el tiempo de