I'm giving you the content of the .ino file, but as mentioned in my post, this project is not mine - everything I posted comes from the creator's link, who I assume is Spanish
[code]
/* --------------- LOCOMOTORA "SOFIA" COMPATIBLE CON PISTAS DE TREN DE LEGO DUPLO, CONTROLADO POR MANDO INFRARROJO, CON CONTROL DE VELOCIDAD POR SENSOR DE ULTRASONIDOS Y CON UN SEGUNDO MOTOR PORTA IMANES USO VARIADO -----------------
MATERIAL NECESARIO :
- Arduino Nano v3.0 - Interruptor de Encendido - 1 Led Verde - 2 Leds Blancos - Sensor de Ultrasonidos "HC-SR04" - 1 Motor CC para las ruedas con engranaje (con eje para las 2 ruedas)
- Un mini motor de engranajes (30 r.p.m) para colación de los imanes - 1 ALTAVOZ (Activo)5V 12mm - Resistencias 47 Y 150 OHMS(para los Leds) - 1 Controlador de Motores de CC don doble salida "HG7881"(L9110S)
- Terminales (muelles) para la caja de baterías) - 2 Baterias 18650 - Varilla de 2mmx51mm (bisagra) y otra de 3mmx48 para el eje de las ruedas - 1 kit Infrarojo (mando y receptor) modelo VS1838
- 4 Imanes de neodimio cilindricos 4mmx4mm para cierre magnético de tapa - 6 imanes de neodimio redondos de 10mmx3mm para juegos magnéticos. - Cables tipo Dupont Hembra-Hembra de 10cm y 20cm para el conexionado.
FUNCIONAMIENTO: Mediante un mando por Infrarrojos y un Arduino Nano controlamos La Locomotora "SOFIA", es compactible con las vias del TREN DE LEGO DUPLO.
Este tiene un sensor de Ultrasonidos para reducir la velocidad o frenar antes de colisionar en el sentido de avance del tren, que podemos habilitar o deshabilitar.
Señalizado por el led "verde" de Activado/Desactivado Ultrasonido (Led "Verde" encendido --> Trabajo con Ultrasonidos Activado), (Led "Verde" Apagado --> Trabajo con Ultrasonidos Desactivado)
Tambien se puede subir la velocidad manualmente pulsado la tecla de "CH+" (marcha adelante) o "CH-" (marcha atrás) del mando de infrarojos varias veces (motor de las Ruedas) hasta llegar a su velocidad máxima (con Ultrasonidos Desactivado)
Tiene un motor extra en el interior para el montaje de una rueda con imanes de neodimio para futuros proyectos, y podemos subir su velocidad de giro con las teclas "-" y "+", (no le influye la habilitación o no de los Ultrasonidos).
Podemos encender/apagar las "luces delanteras" para una mayor visibilidad en la conducción nocturna, jeje.
Podemos dar "bocinazos" para pedir paso en un cruze mediante el altavoz. También se le ha añadido, un parpadeo en las luces delanteras cuando seleccionamos alguna de las opciones o cuando el coche ha llegado a su velocidad máxima.
MAS INFORMACIÓN EN: https://www.thingiverse.com/thing:4012245
*/
//NOTA: Puede suceder que dependiendo como conectamos la alimentación de los motores (van través del Modulo HG7881 (L9110S)) nos girarían en sentido contrario, para solucionar ésto, simplemente intercambiar los cables que van al motor.
//NOTA 2: Dependiendo del fabricandte del Sensor de Ultrasonidos del modelo "HC-SR04" algunos pueden tener mejor sensibilidad o peor sensibilidad, quizás tengamos que ajustar dentro de la rutina "Ultrasound()" los valores de distancia (dentro de los "if")
// para mejorar su funcionamiento. También dentro de la función "Distancia_test()" podemos variar algo los "delayMicroseconds" para mejorar su funcionamiento.
#include "IRLibAll.h"
// Variables usadas para el control del programa.
int VLed; // Variable "VLed" usada para el estado de Activado o Desactivado trabajo con sensor de Ultrasonido (1 LED Verde)
int VLuz; // Variable "VLuz" usada para el estado de las luces delanteras (2 LEDs Blancos)
int VMotB; // Variable "VMotB" usada para el estado del Motor de las Ruedas motrices (MOTOR B)
int VMotA; // Variable "VMotA" usada para el estado del motor portaimanes (MOTOR A)
int Vdistancia; // Variable "Vdistancia" usada para el valor del Sensor de Ultrasonidos
int VStopGo; // Variable para arrancar automáticamente después de producirse una parada debido a que el sensor ultrasonido para antes de colisionar (distancia muy corta)
int NOSound; // Variable para habilitar o deshabilitar los sonidos
//Constantes con su valor de pin de conexionado para una mejor identificación y control del programa.
const int RECV_PIN = 2; // Constante "RECV_PIN" con valor "2" (Pin "D2" usado para el Receptor de infrarojos)
const int Led1 = 4; // Constante "Led1" con valor "4" (Pin "D4" usado para el led verde de "Encendido/Apagdo el Sensor de Ultrasonido")
const int Altavoz_Pin = 3; // Constante "Altavoz_Pin" con valor "3" (Pin "D3" usado para conexionado del Altavoz)
const int trigger = 5; // Constante "trigger" con valor "5" (Pin "D5" usado para Sensor de ultrasonido (patilla trigger)
const int echo = 7; // Constante "echo" con valor "7" (Pin "D7" usado para el Sensor de ultrasonido (patilla echo)
const int luz = 8; // Constante "luz" con valor "8" (Pin "D8" usado para las Luces delanteras. Lleva 2 led blancos)
// Conexiones cableadas, Usando el controlador de motores "HG7881" (voltaje de trabajo 2,5v a 12V)
#define HG7881_B_IA 10 // Pin "D10" --> Motor B Input B-IA --> MOTOR B + (MOTOR DE RUEDAS)
#define HG7881_B_IB 11 // Pin "D11" --> Motor B Input B-IB --> MOTOR B - (MOTOR DE RUEDAS)
#define HG7881_A_IA 6 // Pin "D6" --> Motor A Input A-IA --> MOTOR A + (MOTOR PORTAIMANES)
#define HG7881_A_IB 9 // Pin "D9" --> Motor A Input A-IB --> MOTOR A - (MOTOR PORTAIMANES)
// Conexiones funcionales
#define MOTOR_B_PWM HG7881_B_IA // Motor B PWM Speed (MOTOR RUEDAS VELOCIDAD) (PIN D10)
#define MOTOR_B_DIR HG7881_B_IB // Motor B Direction (MOTOR RUEDAS DIRECCION) (PIN D11)
#define MOTOR_A_PWM HG7881_A_IA // Motor A PWM Speed (MOTOR PORTAIMANES VELOCIDAD) (PIN D6)
#define MOTOR_A_DIR HG7881_A_IB // Motor A Direction (MOTOR PORTAIMANES DIRECCIÓN) (PIN D9)
//Los valores reales de "rápido" (FAST) y "lento" (SLOW) dependen de cada motor (rpm). Variar, ajustando a sus valores para una velocidad adecuada.
#define PWM_SLOW_A 100 // Ciclo de trabajo PWM arbitrario de velocidad lenta (MOTOR A -> "MOTOR PORTAIMANES")
#define PWM_FAST_A 150 // Ciclo de trabajo PWM arbitrario de velocidad rápida (MOTOR A -> "MOTOR PORTAIMANES")
#define DIR_DELAY_A 1000 // Retardo para evitar cambios brucos de velocidad en inversiones de giro del Motor A Portaimanes
#define PWM_SLOW_B 150 // Ciclo de trabajo PWM arbitrario de velocidad lenta (MOTOR B -> "MOTOR RUEDAS")
#define PWM_FAST_B 200 // Ciclo de trabajo PWM arbitrario de velocidad rápida (MOTOR B -> "MOTOR RUEDAS")
#define DIR_DELAY 1000 // Retardo para evitar cambios brucos de velocidad en inversiones de giro del Motor B RUEDAS
// Variables usadas para el control de velocidad del motor de ruedas mediante pulsaciones en mando infrarojo. También motor portaimanes con valor fijo.
int Speed = 150; // Variable "speed" con valor inicial de velocidad (usado en motor B -> RUEDAS)
int SpeedStep = 50; // Variable "SpeedStep" usada para los pasos de cambios de velocidad (mediante pulsaciones en mando infarojo al mismo botón de avance/retroceso) (usado en Motor B -> RUEDAS)
int Speed_MA = 100; // Variable "Speed_MA", velocidad para Motor A (Portaimanes), este motor trabaja con pocas rmp (30rpm)
int SpeedStep_MA = 50; // Variable "SpeedStep_MA" usada para los pasos de cambios de velocidad (mediante pulsaciones en mando infrarojo al mismo botón de avance/retroceso) (usado en Motor A -> PORTAIMANES)
//Crea un objeto receptor para "escuchar" el pin "D2" (Receptor de infrarojos)
IRrecvPCI myReceiver(RECV_PIN);
//Crea un objeto decodificador
IRdecodeNEC myDecoder;
void setup() {
// Inicializa los pines digitales como "salida" (OUTPUT), tambien alguno como "entrada" (INPUT)
VLed = 1; //LED de "Encendido el ultrasonido" comienza en estado ON (Activado)
VLuz = 0; //Luces Led delanteras comienza en estado OFF (Apagadas)
Vdistancia = 0; // Valor inicial variable "Vdistancia" para sensor de ultrasonido
VStopGo = 0; // Valor inicial variable "VStopGo" para el arranque automático después de una parada por distancia muy corta del sensor de ultrasonidos.
NOSound = 0; // Valor inicial de variable "NOSound" apagado. Se deshabilitan todos los sonidos. Ah... el silencio es precioso....
pinMode(Led1, OUTPUT); //Se configura Led1 como salida (pin D4)(Led "Habilitado o Deshabilitado trabajo con Ultrasonidos")
pinMode(luz, OUTPUT); //Se configura el pin luz como salida (pin D5)(Leds Luces delanteras)
pinMode( MOTOR_B_DIR, OUTPUT ); //Se configura el pin D11 como salida (Motor B Direction)
pinMode( MOTOR_B_PWM, OUTPUT ); //Se configura el pin D10 como salida (Motor B PWM Speed)
pinMode( MOTOR_A_DIR, OUTPUT ); //Se configura el pin D6 como salida (Motor A Direction)
pinMode( MOTOR_A_PWM, OUTPUT ); //Se configura el pin D9 como salida (Motor A PWM Speed)
pinMode( Altavoz_Pin, OUTPUT ); //Se configura el pin D3 como salida (Altavoz)
pinMode(trigger, OUTPUT); //Se configura el pin D5 como salida (patilla "trigger" del Sensor Ultrasonidos)
pinMode(echo, INPUT); //Se configura el pin D7 como entrada (patilla "echo" del Sensor Ultrasonidos)
digitalWrite( Led1, HIGH); //Se activa "Led1" "Habilitado trabajo con Ultrasonidos" (PIN D4)
digitalWrite( luz, LOW); //Se desactiva "luz" (PIN D8) LUCES DELANTERAS (2 Leds) Comienzan Apagadas
digitalWrite( MOTOR_B_DIR, LOW ); //Se desactiva Motor B "RUEDAS" (SENTIDO DE GIRO)
digitalWrite( MOTOR_B_PWM, LOW ); //Se desactiva Motor B "RUEDAS" (VELOCIDAD)
digitalWrite( MOTOR_A_DIR, LOW ); //Se desactiva Motor A "PORTAIMANES" (SENTIDO DE GIRO)
digitalWrite( MOTOR_A_PWM, LOW ); //Se desactiva Motor A "PORTAIMANES" (VELOCIDAD)
Serial.begin(9600); // Abre el puerto Serie, configura los datos a 9600 bps
myReceiver.enableIRIn(); // Enciende el receptor
Serial.println(F("Ready to receive IR signals"));
}
void loop() { //Se inicia la rutina Principal "loop" (Bucle)
if (VLed == 1) { // Con el VLed activo "Encendido el Ultrasonido" (led verde) trabaja con el control de velocidad por ultrasonidos.
Ultrasound(); // Se lanza la rutina de Ultrasonidos para el control de velocidad del tren
}
if (myReceiver.getResults()) { //Continúe en bucle hasta que una señal sea completamente recibida por mando infrarrojo.
myDecoder.decode(); //Decode it
myDecoder.dumpResults(true); //Now print results. Use false for less detail
translateIR();
myReceiver.enableIRIn(); //Restart receiver
}
} // Fin de rutina Loop (Bucle)
// CONTROL DE VELOCIDAD MEDIANTE SENSOR DE ULTRASONIDOS
// - Dependiendo de la distancia varía la velocidad:
// - Si está a menos de 15cm manda parar, también si llega a dar un valor por encima de 601cm cosa que puede suceder cuando tiene un objeto muy cercano,(nos da valores superiores a 2000cm, al menos en el modelo chino que tengo).
// - Entre 16cm y 22cm va a una velocidad 50
// - Entre 23cm y 25cm va una velocidad 60
// - Entre 26cm y 29cm va a una velocidad 100
// - Entre 30cm y 32cm va una velocidad 120
// - Entre 33cm y 35cm va a una velocidad 140
// - Entre 36cm y 45cm va una velocidad 150
// - Entre 46cm y 600cm va una velocidad 150 (Velocidd estandar cuando trabaja con el sensero de ultrasonidos activo)
void Ultrasound()
{
Distancia_test(); //LLamada a la función de Sensor de Ultrasonido
Vdistancia = Distancia_test(); //Asignamos el valor leído por el Sensor de ultrasonidos a la variable "Vdistancia"
Serial.print("DISTANCIA INICIO RUTINA ULTRASOUND =");
Serial.println(Vdistancia);
Serial.print ("VELOCIDAD INICIO RUTINA ULTRASOUND = ");
Serial.println (Speed);
//Serial.print ("El estado de la variable MOTOR_B_DIR inicio rutina Ultrasound = ");
//Serial.println (MOTOR_B_DIR);
//Serial.print ("El estado de la variable MOTOR_B_PWM inicio rutina Ultrasound = ");
//Serial.println (MOTOR_B_PWM);
//Serial.print ("Variable VStopGo = ");
//Serial.println (VStopGo);
if ((Vdistancia >= 0) && (Vdistancia <= 18) && (VMotB == 1) || (Vdistancia >= 601) && (Vdistancia <= 4000) && (VMotB == 1)) { // Cuando la distancia está entre 0cm y 15cm o entre 601 y 400 manda parar. NOTA: Filtra valores erróneos de sensor de
if (VStopGo == 1) { // ultrasonidos que da cuando tiene un objeto muy cercano, da valores erróneos de distancia superiores a 2000cm.
Stop_MB(); //Con "VStopGo" a "1" cada vez que se produce una parada por un objeto muy cercano, no vuelve a arrancar automáticamente.
}
else if (VStopGo == 0) { //Con "VStopGo" a "0" arranca automáticamente cuando el objeto cercano se ha retirado.
Speed = 0; //La variable "VStopGo" la podemos variar manualmente pulsadon la tecla "1" del mando a distancia.
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 0 y 15 O ENTRE 601 Y 4000 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
}
else if ((Vdistancia >= 19) && (Vdistancia <= 25) && (VMotB == 1)) { // Distancia entre 16cm y 22cm damos una velocidad de 50. (tenemos algún obstáculo cercano velocidad inicial muy baja.
Speed = 50; // Para éste tipo de motor con pocas revoluciones (Relación de Reductora 1:48) si bajamos de éste valor mínimo de 50 no será capaz de mover el coche.
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 16 y 22 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 26) && (Vdistancia <= 30) && (VMotB == 1)) { // A PARTIR DE AQUÍ VAMOS SUBIENDO LA VELOCIDAD DEPENDIENDO SI NOS ALEJAMOS DEL OBJETO DE POSIBLE COLISIÓN....:
Speed = 60; //Distancia entre 23cm y 25cm velocidad 60
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 23 y 25 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 31) && (Vdistancia <= 36) && (VMotB == 1)) { // Distancia entre 26cm y 29cm velocidad 100
Speed = 100;
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 26 y 29 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 37) && (Vdistancia <= 42) && (VMotB == 1)) { // Distancia entre 30cm y 32cm velocidad 120
Speed = 120;
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 30 y 32 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 43) && (Vdistancia <= 48) && (VMotB == 1)) { // Distancia entre 33cm y 35cm velocidad 140
Speed = 140;
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 33 y 35 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 48) && (Vdistancia <= 55) && (VMotB == 1)) { // Distancia entre 36cm y 45cm velocidad 150
Speed = 150;
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast
//Serial.print("DISTANCIA ENTRE 36 y 45 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
else if ((Vdistancia >= 56) && (Vdistancia <= 600) && (VMotB == 1)) { // Distancia entre 46cm y 600cm velocidad 150
Speed = 150; // 400cm valores máximos que mide más o menos fiables sensor ultrasonidos, por encima de esa distancia los valores pueden no ser fiables.
analogWrite( MOTOR_B_PWM, 255 - Speed ); // PWM speed = fast // Llega a medir hasta 600cm según fabricante...
//Serial.print("DISTANCIA ENTRE 46 y 600 = ");
//Serial.println(Vdistancia);
//Serial.print ("VELOCIDAD = ");
//Serial.println (Speed);
}
}
//MANDO DE INFRAROJOS
// Dependiendo del código recibido por infrarrojo se ejecuta las diversas acciones:
// - Activación/Desactivación de la Luz de encendido,(led verde) que señaliza que el control de velocidad mediante el sensor de ultrasonidos está activado/desactivado.
// - Activación/Desactivación de las Luces delanteras (2 leds blancos)
// - Motor A (Portaimanes) Giro a derechas o izquierdas (Varias Velocidades, si pulsamos varias veces en el mismo sentido sube de velocidad hasta velocidad máxima.
// - Motor B (Ruedas) Adelante/Atrás (Si pulsamos varias veces en el mismo sentido sube de velocidad hasta velocidad máxima), (Sólo con Ultrasonidos Desactivados "led verde apagado")
// - Sonidos Activados/Desactivados (trabaja el altavoz activo para señalizar diversas acciones,(también el parpadeo de las luces delanteras): Como activación/desactivación ultrasonidos, velocidad máxima alcanzada, habilitación de arranque automático,Claxon.
// - NOTA: En caso de querer utilizar un mando infrarojo diferente (quizás valdría uno de una televisión) tendreis que usar el "Monitor Serie" dentro de la pestaña "Herramientas" y al pulsar una tecla examinar la primera linea y donde sale
// la palabra "Value:FFFFFF". Estas "FFFFFF" es el código que tendréis que poner a continuación de los "case" para realizar la opción deseada (Se pondría de ésta forma-> case 0xFFFFFF: (Se añade el "0x" sin las comillas antes del valor obtenido)
// Nota al estar activo el Sensor de Ultrasonido para poder observar el código obtenido deshabilitar el "Autoscroll" en monitor serie.
// - Códigos de cada tecla del Mando Infrarrojo (modelo VS1838): ("CH-"= FFA25D), ("CH"= FF629D), ("CH+"= FFE21D), ("PREV"= FF22DD), ("NEXT"= FF02FD), ("PLAY/PAUSE"= FFC23D), ("VOL-"= FFE01F), ("VOL+"= FFA857), ("EQ"= FF906F), ("0"= FF6897)
// ("100+"= FF9867), ("200+"= FFB04F), ("1"= FF30CF), ("2"= FF18E7), ("3"= FF7A85), ("4"= FF10EF), ("5"= FF38C7), ("6"= FF5AA5), ("7"= FF42BD), ("8"= FF4AB5), ("9"= FF52AD)
void translateIR()
{
switch (myDecoder.value) {
case 0xFF22DD: // "PRECEDENT" El valor "FF22DD" es la tecla "Anterior" en el mando a distancia por infrarojos (si compráis el que está en el enlace anterior).
if (VLed == 0) { // SE ACTIVA O DESACTIVA EL "LED VERDE" "Señaliza el encendido o apagado del SENSOR ULTRASÓNIDOS" Si la variable Vled esta a 0 (led verde de "trabajo con ultrasonido" apagado) se activa en la siguiente instrucción
digitalWrite(Led1, HIGH); // Activamos el Pin "D3" usado para activar el led "verde" que señaliza el "encendido la forma de trabajo con Sensor de Ultrasonidos"
VLed = 1; // Valor estado de la variable activo ya que el led se encuentra activo.
Parpadeo1();
buzzer();
}
else {
digitalWrite(Led1, LOW); // En caso contrario (que VLed1 esté a 1), lo apagamos (deshabilitamos el trabajar con sensor de ultrasonidos)
VLed = 0;
// VMotB=0; // PENDIENTE DE PROBAR SI NO ARRANCA DESPUES DE ESTAR PARADO AL DESHABILITAR EL SENSOR DE ULTRASONIDOS.
Parpadeo1();
buzzer2();
}
break;
case 0xFF02FD: // El valor "FF02FD" es la tecla "Siguiente (NEXT)" en el mando a distancia por infrarojos. SE ACTIVA O DESACTIVA LAS "LUCES DELANTERAS"
if (VLuz == 0) { // La rutina básicamente trabaja que si las "Luces delanteras" estaban apagadas se enciende y si estaban encendidas se apagan
digitalWrite(luz, HIGH);
VLuz = 1;
}
else {
digitalWrite(luz, LOW);
VLuz = 0;
}
break;
case 0xFFE01F: // El valor "FFE01F" es la tecla "-" en el mando a distancia por infrarojos. SE ACTIVA EL "MOTOR PORTAIMANES" en dirección ADELANTE (MOTOR A)
if (VMotA != 1) {
Speed_MA = PWM_SLOW_A;
go_forward_A ();
}
else {
Speed_MA = Speed_MA + SpeedStep_MA ;
Speed_MA = min(255, max(0, Speed_MA));
if (Speed_MA == 255) {
buzzer3();
Parpadeo();
}
go_forward_A ();
}
break;
case 0xFF906F: // El valor "FF906F" es la tecla "EQ" en el mando a distancia por infrarojos. SE ACTIVA EL "MOTOR PORTAIMANES" en dirección ATRAS (MOTOR A)
if (VMotA != 2) {
Speed_MA = PWM_SLOW_A;
go_backward_A ();
}
else {
Speed_MA = Speed_MA + SpeedStep_MA ;
Speed_MA = min(255, max(0, Speed_MA));
if (Speed_MA == 255) {
buzzer3();
Parpadeo();
}
go_backward_A ();
}
break;
case 0xFF629D: // El valor "FF629D" es la tecla "CH" en el mando a distancia por infrarojos. SE BAJA LA VELOCIDAD EN LOS DOS SENTIDOS DE AVANCE Y RETROCESO DE LAS RUEDAS (MOTOR B)
if (VMotB == 1) { // Si la variable "VMotB" Motor Status es 1 (Locomotora hacia ADELANTE) bajamos la velocidad en ese sentido de giro.
Speed = Speed - SpeedStep ;
Speed = min(255, max(0, Speed));
if (Speed <= 40) {
Speed = 0 ; //Cuando bajamos de velocidad y el valor es menor o igual a 40 (insuficiente para mover el motor) Por tanto lo paramos por completo.
}
go_forward ();
if (Speed == 0) {
buzzer3(); // Señalizamos con un pitido y parpadeo luces delanteras que llegamos a velocidad cero (parados) en el sentido de Avance del tren.
Parpadeo();
VMotB = 0;
}
}
else if (VMotB == 2) { // Si la variable "VMotB" Motor Status es 2 (Locomotora hacia ATRAS) bajamos la velocidad en ese sentido de giro.
Speed = Speed - SpeedStep ; // Bajamos de velocidad el valor de la variable "SpeedStep" que va en pasos de "50".
Speed = min(255, max(0, Speed));
if (Speed <= 40) {
Speed = 0 ; //Cuando bajamos de velocidad y el valor es menor o igual a 40 (insuficiente para mover el motor) Por tanto lo paramos por completo.
}
go_backward();
if (Speed == 0) {
buzzer3(); // Señalizamos con un pitido y parpadeo luces delanteras que llegamos a velocidad cero (parados) en el sentido de Retroceso del tren.
Parpadeo();
VMotB = 0;
}
}
//Stop_MB();
break;
case 0xFFA857: // El valor "FFA857" es la tecla "+" en el mando a distancia por infrarojos. SE BAJA LA VELOCIDAD EN LOS DOS SENTIDOS DE GIRO DEL MOTOR PORTA IMANES (MOTOR A)
if (VMotA == 1) { // Si la variable "VMotA" (Motor Status) es 1 (MOTOR PORTA IMANES A DERECHAS) bajamos la velocidad en ese sentido de giro.
Speed_MA = Speed_MA - SpeedStep_MA ; // Bajamos de velocidad el valor de la variable "SpeedStep_MA" que va en pasos de "50".
Speed_MA = min(255, max(0, Speed_MA));
if (Speed_MA <= 40) {
Speed_MA = 0; //Cuando bajamos de velocidad y el valor es menor o igual a 40 (insuficiente para mover el motor) Por tanto lo paramos por completo.
}
go_forward_A ();
if (Speed_MA == 0) {
buzzer3(); // Señalizamos con un pitido y parpadeo luces delanteras que llegamos a velocidad cero. (GIRO A DERECHAS VELOCIDAD CERO)
Parpadeo();
VMotA = 0;
}
}
else if (VMotA == 2) { // Si la variable "VMotA" (Motor Status) es 2 (MOTOR PORTA IMANES A IZQUIERDAS) bajamos la velocidad en ese sentido de giro.
Speed_MA = Speed_MA - SpeedStep_MA ;
Speed_MA = min(255, max(0, Speed_MA));
if (Speed_MA <= 40) {
Speed_MA = 0; //Cuando bajamos de velocidad y el valor es menor o igual a 40 (insuficiente para mover el motor) Por tanto lo paramos por completo.
}
go_backward_A();
if (Speed_MA == 0) {
buzzer3(); // Señalizamos con un pitido y parpadeo luces delanteras que llegamos a velocidad cero. (GIRO A IZQUIERDAS VELOCIDAD CERO)
Parpadeo();
VMotA = 0;
}
}
//Stop_MA();
break;
case 0xFFC23D: // El valor "FFC23D" es la tecla "Play/Pause" en el mando a distancia por infrarojos. STOP PARA LOS 2 MOTORES.
//if(VMotB !=0 || VMotA !=0) {
Stop_ALL ();
break;
case 0xFF38C7: // El valor "FF38C7" es la tecla "5" en el mando a distancia por infrarojos. DAR LUCES LARGAS (3 PARPADEOS PARA AVISAR AL CONDUCTOR DELANTERO)
Parpadeo2();
break;
case 0xFF9867: // El valor "FF9867" es la tecla "100+" en el mando a distancia por infrarojos. SONIDO DEL CLAXON PARA INCORDIAR AL PERSONAL.
Claxon();
break;
case 0xFF6897: // El valor "FF6897" es la tecla "0" en el mando a distancia por infrarojos. HABILITA O DESHABILITA EL ARRANQUE AUTOMÁTICO DESPUES DE UNA PARADA POR POSIBLE COLISIÓN.
if (VStopGo == 0) { // Estando el valor de la variable "VStopGo" a "1" cada vez que para debido a que el detector de ultrasonidos nos dice que hay un objeto muy cercano se para y no vuelve a arrancar
VStopGo = 1; // hasta que volvemos a pulsar el boton de avance "CH+" en mando a distancia. Con valor a "0" de ésta variable arranca automáticamente cuando el objeto cercano se ha retirado.
Parpadeo();
buzzer2();
}
else {
VStopGo = 0;
Parpadeo();
buzzer();
}
break;
case 0xFFB04F: // El valor "FFB04F" es la tecla "200+" del mando a distancia por infrarojos, HABILITA O DESHABILITA TODOS LOS SONIDOS (NOSound=0 => Sonidos activos)
if (NOSound == 0) {
Parpadeo();
buzzer2();
NOSound = 1;
}
else {
NOSound = 0;
Parpadeo();
buzzer();
}
break;
case 0xFFE21D: // El valor "FFE21D" es la tecla "CH+" del mando a distancia por infrarojos. HACIA ADELANTE MOTOR B (RUEDAS)
if (VMotB != 1) { // Si la variable "VMotB" Motor Status (Ruedas) es diferente de 1 lanza la rutina de avance
Speed = PWM_SLOW_B;
go_forward ();
}
else {
Speed = Speed + SpeedStep ; //Realiza uno de los cambios de velocidad para la variable "speed"
Speed = min(255, max(0, Speed)); // Asigna al valor de Velocidad "Speed" el menor de los números. Sería de 255 en caso que la velocidad sobrepase éste valor.
if (Speed == 255) {
buzzer3();
Parpadeo();
}
go_forward();
}
break;
case 0xFFA25D: // El valor "FFA25D" es la tecla "CH-" del mando a distancia por infrarojos. HACIA ATRÁS EL MOTOR B (RUEDAS)
if (VMotB != 2) {
Speed = PWM_SLOW_B;
go_backward ();
}
else {
Speed = Speed + SpeedStep ; //Realiza uno de los cambios de velocidad para la variable "speed"
Speed = min(255, max(0, Speed)); // Asigna al valor de Velocidad "Speed" el menor de los números. Sería de 255 en caso que la velocidad sobrepase éste valor.
if (Speed == 255) {
buzzer3();
Parpadeo();
}
go_backward();
}
break;
default: //Se ejecuta si nada coíncide....
//buzzer();
//buzzer1();
//buzzer2();
break;
}
}
// RUTINA HACIA ADELANTE MOTOR B (RUEDAS)
void go_forward ()
{
Serial.println ("Hacia ADELANTE en motor de las ruedas ...");
Serial.print ("La velocidad de motor ruedas es: ");
Serial.println (Speed);
//Serial.print ("La distancia medida por ultrasonidos es (puede no ser la actual): ");
//Serial.println (Vdistancia);
//if (VMotB == 0){buzzer1 ();}
// Siempre se para los motores antes de realizar un cambio de sentido (evita cambios de dirección bruscos)
if (VMotB == 2) {
Stop_MB(); //buzzer1 ();
delay( DIR_DELAY );
}
// Activa el motor la velocidad y dirección
digitalWrite( MOTOR_B_DIR, HIGH ); // Dirección Avance hacia Adelante
analogWrite( MOTOR_B_PWM, 255 - Speed ); // Velocidad PWM, valor en variable "Speed"
VMotB = 1;
}
// RUTINA HACIA ATRAS MOTOR B (RUEDAS)
void go_backward ()
{
Serial.println ("Hacia ATRAS en motor de las ruedas ....");
Serial.print ("La velocidad de motor ruedas es: ");
Serial.println (Speed);
//Serial.print ("La distancia medida por ultrasonidos es (puede no ser la actual): ");
//Serial.println (Vdistancia);
// if (VMotB == 0){buzzer1 ();}
// Siempre se para los motores antes de realizar un cambio de sentido (evita cambios de dirección bruscos)
if (VMotB == 1) {
Stop_MB(); //buzzer1 ();
delay( DIR_DELAY );
}
// Activa el motor la velocidad y dirección
digitalWrite( MOTOR_B_DIR, LOW ); // Dirección inversa (marcha atrás)
analogWrite( MOTOR_B_PWM, Speed ); // Velocidad PWM, valor en variable "Speed"
VMotB = 2;
}
// RUTINA HACIA ADELANTE MOTOR A (PORTAIMANES)
void go_forward_A ()
{
Serial.println ("Vamos hacia adelante en motor portaimanes...");
Serial.print ("La velocidad actual portaimanes es: ");
Serial.println (Speed_MA);
// if (VMotA == 0){buzzer1 ();} // Un pequeño pitido de arranca de motor portaimanes en dirección Avance
// Siempre se para los motores antes de realizar un cambio de sentido (evita cambios de dirección bruscos)
if (VMotA == 2) {
Stop_MA(); //buzzer1 ();
delay( DIR_DELAY_A );
}
// Activa el motor la velocidad y dirección
digitalWrite( MOTOR_A_DIR, HIGH ); // Dirección Giro hacia la derecha
analogWrite( MOTOR_A_PWM, 255 - Speed_MA ); // Velocidad PWM, valor en variable "Speed_MA"
VMotA = 1;
}
// RUTINA HACIA ATRAS MOTOR A (PORTAIMANES)
void go_backward_A ()
{
Serial.println ("Vamos hacia atrás en motor portaimanes...");
Serial.print ("La Velocidad actual portaimanes es: ");
Serial.println (Speed_MA);
// if (VMotA == 0){buzzer1 ();} // Un pequeño pitido de arranca de motor portaimanes en dirección Retroceso
// Siempre se para los motores antes de realizar un cambio de sentido (evita cambios de dirección bruscos)
if (VMotA == 1) {
Stop_MA(); // buzzer1 ();
delay( DIR_DELAY_A );
}
// set the motor speed and direction
digitalWrite( MOTOR_A_DIR, LOW ); // Dirección Giro hacia la izquierda
analogWrite( MOTOR_A_PWM, Speed_MA ); // Velocidad PWM, valor en variable "Speed_MA"
VMotA = 2;
}
// RUTINA DE "STOP" PARA LOS 2 DOS MOTORES (MOTOR A Y MOTOR B)
void Stop_ALL ()
{
//Serial.println ("STOP Para los 2 motores...");
digitalWrite( MOTOR_B_DIR, LOW ); //Motor Ruedas OFF
digitalWrite( MOTOR_B_PWM, LOW ); //Motor Ruedas OFF
digitalWrite( MOTOR_A_DIR, LOW ); //Motor portaimanes OFF
digitalWrite( MOTOR_A_PWM, LOW ); //Motor portaimanes OFF
VMotB = 0; //Motor Ruedas Valor inicial (parado)
VMotA = 0; //Motor portaimanes valor inicial (parado)
}
// RUTINA DE "STOP" PARA EL MOTOR DE LAS RUEDAS (MOTOR B)
void Stop_MB ()
{
//Serial.println ("STOP Para el motor de las ruedas (Motor B....");
digitalWrite( MOTOR_B_DIR, LOW ); //Motor Ruedas OFF
digitalWrite( MOTOR_B_PWM, LOW ); //Motor Ruedas OFF
VMotB = 0; //Motor Ruedas Valor inicial (parado)
}
// RUTINA DE "STOP" PARA EL MOTOR PORTAIMANES (MOTOR A)
void Stop_MA ()
{
//Serial.println ("STOP Para el motor portaimanes (Motor A....");
digitalWrite( MOTOR_A_DIR, LOW ); //Motor portaimanes OFF
digitalWrite( MOTOR_A_PWM, LOW ); //Motor portaimanes OFF
VMotA = 0; //Motor PortaImanes Valor inicial (parado)
}
// FUNCIÓN DE CÁLCULO DE DISTANCIA MEDIANTE SENSOR DE ULTRASONIDO
int Distancia_test()
{
digitalWrite(trigger, LOW);
delayMicroseconds(12); // Valor original 10 (modificado a 12)
digitalWrite(trigger, HIGH);
delayMicroseconds(120); // Valor Original 100 (modificado a 120)
digitalWrite(trigger, LOW);
float Fdistance = pulseIn(echo, HIGH);
Fdistance = Fdistance / 58;
return (int)Fdistance;
}
//RUTINAS PARA EL AVISO SONORO DE DIVERSAS FUNCIONES - Hay que tener en cuenta que si tenemos deshabilitados los sonidos el control de la locomotora irá más fluída, lo mismo sucede deshabilitando el control de velocidad mediante ultrasonidos.
// DOBLE PITIDO DE ALTAVOZ - Doble pitido que indica que se ha habilitado alguna de las opciones programadas. (Activado control de velocidad por Ultrasonidos, Activado arranque automático después de un paro, o habilitación de todos los sonidos)
void buzzer ()
{
if (NOSound == 0) {
for (int thisBuz = 0; thisBuz < 2; thisBuz++) {
digitalWrite(Altavoz_Pin, HIGH);
delay(100);
digitalWrite(Altavoz_Pin, LOW);
delay(50);
}
}
}
// PITIDO DE ALTAVOZ 1 - Pitido de arranque o paro, cuando se inicia un movimiento de cualquiera de los 2 motores (DESHABILITADO "Comentado" en rutina de avance y retroceso motores ruedas y portaimanes)
void buzzer1 ()
{
if (NOSound == 0) {
for (int thisBuz = 0; thisBuz < 1; thisBuz++) {
digitalWrite(Altavoz_Pin, HIGH);
delay(120);
digitalWrite(Altavoz_Pin, LOW);
delay(50);
}
}
}
// PITIDO DE ALTAVOZ 2 Sonido apagado que indica que se ha deshabilitado alguna de las opciones programadas (Desactivado Ultrasonidos, desactivado arranque automático después de un paro, o desactivado todos los sonidos)
void buzzer2 ()
{
if (NOSound == 0) {
for (int thisBuz = 25; thisBuz > 0; thisBuz--) {
analogWrite(Altavoz_Pin, thisBuz);
delay(10);
analogWrite(Altavoz_Pin, 0);
delay(10);
}
}
}
// PITIDO DE ALTAVOZ 3 - Velocidad máxima alcanzada (Trabaja con cualquiera de los 2 motores, cuando pulsamos varias veces el mismo botón de avance (o retroceso) y llegamos al máximo de velocidad.
void buzzer3 ()
{
if (NOSound == 0) {
for (int thisBuz = 0; thisBuz < 1; thisBuz++) {
digitalWrite(Altavoz_Pin, HIGH);
delay(100);
digitalWrite(Altavoz_Pin, LOW);
delay(50);
}
}
}
// PITIDO DE ALTAVOZ 4 - Claxon para advertir a nuestros rivales. Un dolor de cabeza para los padres.... (3 pitidos largos)
void Claxon ()
{
if (NOSound == 0) {
for (int thisBuz = 0; thisBuz < 3; thisBuz++) {
digitalWrite(Altavoz_Pin, HIGH);
delay(300);
digitalWrite(Altavoz_Pin, LOW);
delay(100);
}
}
}
// RUTINA PARPADEO DE LUCES DELANTERA (BLANCAS) - Señaliza la activación o desactivación de alguna opción (si las luces estaban encendidas después del parpadeo, se vuelven a dejar encendidas).
void Parpadeo ()
{
for (int BlinkL = 0; BlinkL < 2; BlinkL++) {
digitalWrite(luz, HIGH);
delay(100);
digitalWrite(luz, LOW);
delay(50);
}
if (VLuz == 1) {
digitalWrite(luz, HIGH);
}
}
// RUTINA PARPADEO1 DE LUZ VERDE DE CONTROL DE VELOCIDAD POR ULTRASONIDOS ACTIVADO) - Señaliza la activación o desactivación del Control de Velocidad por ultrasonidos.
void Parpadeo1 ()
{
for (int BlinkL = 0; BlinkL < 2; BlinkL++) {
digitalWrite(Led1, HIGH);
delay(100);
digitalWrite(Led1, LOW);
delay(50);
}
if (VLed == 1) {
digitalWrite(Led1, HIGH);
}
}
// RUTINA PARPADEO2 DE LUCES DELANTERA (BLANCAS) - Realiza 3 parpadeos de las luces delanteras (dar luces) para que se entere el que va por delante..
void Parpadeo2 ()
{
for (int BlinkL = 0; BlinkL < 3; BlinkL++) {
digitalWrite(luz, HIGH);
delay(200);
digitalWrite(luz, LOW);
delay(200);
}
if (VLuz == 1) {
digitalWrite(luz, HIGH);
}
}
[/code]