Como ya sabemos, el bloque de percepción nos permite introducir información al sistema IA mediante la codificación de las magnitudes obtenidas de los sensores. En este caso he optado por usar módulos de infrarrojos TCRT5000. Dichos módulos resultan ser una opción más que asequible, con muchísima literatura al respecto y de funcionamiento realmente sencillo. Aparte de los pines de alimentación, proporcionan dos salidas; una analógica con la medición del nivel de luz recibida tras el rebote en la superficie, y una información ya codificada digitalmente que diferencia entre superficies claras y oscuras para poder llevar a cabo el siguelineas. Esta es la diferencia entre sistema de sensorizado y sistema de percepción. Y es ésta la salida del módulo que vamos a utilizar.
De modo que, para la aplicación que nos ocupa he utilizado estos 3 pines; Vcc y GND para alimentar el módulo con 5V y el pin digital D0 como entrada de datos en nuestro sistema IA. A continuación muestro un pequeño código que nos permite probar qué tal funciona nuestro sensor. Si grabamos en Arduino el código siguiente y ejecutamos veremos que el sensor sobre una cinta aislante negra marcará un HIGH y sobre una superficie blanca marcará LOW.
NOTA: Es posible que tengamos que ajustar la altura del sensor, pues si este se situara muy cerca de la cinta podría registrar reflexión de la luz, y si se colocara muy lejos podría no registrarla nunca. Para ello disponemos de un potenciómetro y un segundo led en el módulo. Mi recomendación es situarlo un par de centímetros y girando el potenciómetro, hacer que se apague ese segundo led cuando pasemos de zona clara a zona oscura. De este modo, si estamos en zona clara veremos dos leds encendidos (el que dice que el módulo está conectado y ese segundo que nos informa de la zona) y cuando estemos en zona oscura sólo veremos que se enciende el led de módulo conectado.
Curiosamente la señal digital que nos proporciona el módulo nos dará un LOW en zona clara y un HIGH en zona oscura, de modo que el código queda tal y como se muestra a continuación.
#define PIN_Sensor 2
void setup() {
Serial.begin(9600); //iniciar puerto serie
pinMode(PIN_Sensor,INPUT); //definir pin como entrada
}
void loop(){
int Valor_Sensor = 0;
Valor_Sensor = digitalRead(PIN_Sensor); //lectura digital de pin
if (Valor_Sensor == LOW) {
Serial.println("TCRT5000 Zona Clara");
}
if (Valor_Sensor == HIGH) {
Serial.println("TCRT5000 Zona Oscura");
}
delay(1000);
}
De igual manera que en el sistema de percepción, un sistema actuador es el responsable del control y movimiento de nuestro sistema IA. Para la elección de los actuadores vamos a utilizar un módulo L298N y dos motores de corriente continua. Os muestro unas fotos de los mismos.
Como podemos ver tenemos las conexiones siguientes:
Dos conexiones laterales mediante clemas para los motores
Dos conexiones frontales para una fuente de alimentación como pilas o baterias LiPo. Yo en mi caso usé una bateria de 7.4V y 2800mAh.
Seis conexiones frontales, 3 para el control de cada uno de los motores. Las conexiones externas (en color verde) controlan la velocidad mientras que las otras controlan el sentido de giro.
A continuación os muestro un código que va a testear el funcionamiento de los motores:
#define MotorDA 6
#define MotorDB 7
#define MotorDEn 5
#define MotorIA 8
#define MotorIB 9
#define MotorIEn 10
#define Speed 125
Estas etiquetas nos permiten luego trabajar mejor pues no tenemos que recordar el puerto en el que está conectado cada dispositivo. Seguimos con el programa y a continuación en el setup le hacemos saber a Arduino que todas esas conexiones son puertos de salida pues controlan los motores:
void setup() {
pinMode(MotorDA, OUTPUT);
pinMode(MotorDB, OUTPUT);
pinMode(MotorDEn, OUTPUT);
pinMode(MotorIA, OUTPUT);
pinMode(MotorIB, OUTPUT);
pinMode(MotorIEn, OUTPUT);
}
A continuación he decidido crear unas funciones que nos permitirán controlar los motores:
void pararMotorD() {
digitalWrite(MotorDA, LOW);
digitalWrite(MotorDB, LOW);
}
void adelanteMotorD() {
analogWrite(MotorDEn, Speed);
digitalWrite(MotorDA, HIGH);
digitalWrite(MotorDB, LOW);
}
void atrasMotorD() {
analogWrite(MotorDEn, Speed);
digitalWrite(MotorDA, LOW);
digitalWrite(MotorDB, HIGH);
}
void pararMotorI() {
digitalWrite(MotorIA, LOW);
digitalWrite(MotorIB, LOW);
}
void adelanteMotorI() {
analogWrite(MotorIEn, Speed);
digitalWrite(MotorIA, HIGH);
digitalWrite(MotorIB, LOW);
}
void atrasMotorI() {
analogWrite(MotorIEn, Speed);
digitalWrite(MotorIA, LOW);
digitalWrite(MotorIB, HIGH);
}
Por último, dentro del loop definimos algunos movimientos para testear que todo funciona bien, por ejemplo:
void loop() {
adelanteMotorD();
adelanteMotorI();
delay(2000);
adelanteMotorD();
atrasMotorI();
delay(2000);
adelanteMotorI();
atrasMotorD();
delay(2000);
atrasMotorI();
atrasMotorD();
delay(2000);
}