Simulador de ECU S V.1.3
Simulador de ECU S V.1.3
Simulador de ECU S V.1.3
---------------------------
[SIMULADOR DE ECU´S]
Con este banco se pretende hacer funcionar una centralita de motor como si estuviera en un
vehículo, permite simular las señales de diferentes sensores y actuadores más importantes del
vehículo.
INDICE
1 Introdución ...................................................................................................... 2
2.2 Tutorial LCD con I2C, controla un LCD con solo dos pines .....................13
3 Esquemas ......................................................................................................26
4.2 Placaprincipal..........................................................................................28
5 Conexiones ....................................................................................................30
7 Planos ............................................................................................................57
1
1 INTRODUCIÓN
El objetivo de este proyecto es poder simular las señales de los diferentes sensores
y actuadores más importantes que necesita una ECU para que pueda funcionar, para ello
se necesitará que la ECU este sin inmovilizador.
El simulador cuenta con una toma EOBD para poder conectar un equipo de
diagnosis y así poder realizar un diagnóstico de la ECU.
Este simulador también podrá utilizarse para hacer funcionar la ECU para la
reparación de las ECU´s en el caso de que estas tengan alguna avería.
2
3
4
2 CONCEPTOS BÁSICOS
En este tutorial trabajaremos con el Modulo RTC (Real Time Clock) DS1307,
podremos saber la hora exacta, día mes año e incluso el día de la semana, a su vez gracias
a una EEPROM que trae el modulo podemos guardar los datos sin que se borren al apagar
el Arduino.
Agregando el modulo El RTC a nuestro Arduino es como darle un reloj y un
calendario, con el DS1307 nuestro Arduino sabrá la hora exacta como segundos, minutos
y horas. También podremos saber el día del mes, día de la semana, mes, y año. EL ds1307
tiene implementado su calendario hasta el 2100 y tiene en cuenta también los años
bisiestos.
5
Al reverso tiene un socket para insertar
una batería de 3V, que le permite al RTC
mantener en funcionamiento la hora y fecha
cuando se apague el Arduino o se le quiete la
alimentación principal. Esta batería
dependiendo de la marca y del tiempo
apagado, puede durar desde los 3 hasta los 10
años aproximadamente.
Este módulo también trae una memoria no volátil, una EEPROM AT24C32 con capacidad
para 32Kbit o 4Kbytes y también se comunica con el Arduino a través del bus I2C, bus que
comparte con el DS1307, de esta forma solo necesitamos 2 pines del Arduino para
controlar el RTC y EEPROM del Módulo.
Adaptador LCD a I2C Arduino Uno, Nano, Mini. Arduino Mega , DUE Arduino Leonardo
SCL A5 21 3
SDA A4 20 2
VCC 5V 5V 5V
SCL A5 21 3
6
2.1.2 Librería para el RTC DS1307
Para este ejemplo usaremos la librería RTClib de Adafruit, librería que pueden descargarlo
en:
https://github.com/adafruit/RTClib
Necesitamos descargar e importar dicha librería al IDE de Arduino.
Cuando adquirimos un DS1307, al no traer su pila, no tiene la hora actualizada, cada vez
que quitamos la pila el DS1307 pierde la hora, estableciéndose como hora 0:0:0 y fecha
00/00/00,
Este ejemplo solo se utiliza para poner a la hora nuestro DS1307:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
void setup () {
Serial.begin(9600);
rtc.begin(); //Inicializamos el RTC
Serial.println("Estableciendo Hora y fecha...");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
Serial.println("DS1307 actualizado con la hora y fecha que se compilo este prog
rama:");
Serial.print("Fecha = ");
Serial.print(__DATE__);
Serial.print(" Hora = ");
Serial.println(__TIME__);
}
void loop () {
}
7
De esta forma cada vez que el Arduino se enciende o se reinicia, el Arduino
actualizara al DS1307 con la hora que fue compilado el programa.
Después de cargar el código anterior, tan pronto termine la carga Arduino
actualizará la hora, pero cada vez que se habré el monitor serial o se reinicie el Arduino,
nuevamente vuelve a actualizase con la misma hora de compilación.
El monitor serial solo nos sirve para verificar que nuestro programa es correcto. Después
de esto hay que compilarlo y cargarlo de nuevo, para que tenga la hora correcta.
Después de cargar este programa se debe cargar otro distinto, o uno en blanco, para evitar
que se esté actualizando con la misma hora de compilación cada vez que se reinicia o
enciende el Arduino.
Si deseamos actualizar a una hora y fecha en específico deben de modificar a la
siguiente línea de código:
8
2.1.4 Obteniendo Hora y Fecha del DS1307
En este ejemplo realizaremos la lectura de los segundos, minutos y horas del DS1307, y a
su vez también obtendremos la fecha.
Para realizar este ejemplo usamos el siguiente código:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
int segundo,minuto,hora,dia,mes;
long anio; //variable año
DateTime HoraFecha;
void setup () {
Serial.begin(9600);
rtc.begin(); //Inicializamos el RTC
}
void loop () {
HoraFecha = rtc.now(); //obtenemos la hora y fecha actual
segundo=HoraFecha.second();
minuto=HoraFecha.minute();
hora=HoraFecha.hour();
dia=HoraFecha.day();
mes=HoraFecha.month();
anio=HoraFecha.year();
9
Serial.print(mes);
Serial.print("/");
Serial.print(anio);
Serial.println();
delay(1000);
}
10
A este ejemplo, podemos agregar variables tipo cadena para mostrar o tener la
fecha en formato de texto, por ejemplo para el nombre de los días de la semana y los
nombres del mes.
El ejemplo muestra los cambios para mostrar la fecha de forma textual:
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
DateTime HoraFecha;
void setup () {
Serial.begin(9600);
rtc.begin(); //Inicializamos el RTC
}
void loop () {
HoraFecha = rtc.now(); //obtenemos la hora y fecha actual
segundo=HoraFecha.second();
minuto=HoraFecha.minute();
hora=HoraFecha.hour();
dia=HoraFecha.day();
mes=HoraFecha.month();
anio=HoraFecha.year();
diaDeLaSemana=HoraFecha.dayOfTheWeek();
11
Serial.print(" , ");
Serial.print(nombreDia[diaDeLaSemana]);
Serial.print(" ");
Serial.print(dia);
Serial.print(" de ");
Serial.print(nombreMes[mes-1]);
Serial.print(" del ");
Serial.print(anio);
Serial.println();
delay(1000);
}
12
2.2 Tutorial LCD con I2C, controla un LCD con solo dos pines
En este tutorial usaremos un módulo adaptador de LCD a I2C para poder controlar
nuestro LCD con solo dos pines de nuestro Arduino
*También existen módulos con dirección por defecto 0x3F cuyos bits de
configuración son 0|0|1|1|1|A2|A1|A0
13
Para controlar el contraste solo necesitamos variar el potenciómetro que se
encuentra en el módulo.
La luz de fondo se controla por software, desde el Arduino; pero el modulo tiene un
Jumper para desconectar el Led de la luz de fondo.
Adaptador LCD a I2C Arduino Uno, Nano, Mini. Arduino Mega , DUE Arduino Leonardo
VCC 5V 5V 5V
SDA A4 20 2
SCL A5 21 3
14
* Las conexiones para el LCD de 20 x 4 son las mismas.
Las funciones que utiliza esta librería son similares a la librería LiquidCrystal de
Arduino, pero volveremos a explicaremos las funciones principales.
15
✓ print()
Escribe un texto o mensaje en el LCD, su uso es similar a un Serial.print
✓ scrollDisplayLeft()
Se desplaza el contenido de la pantalla (texto y el cursor) un espacio hacia la
izquierda.
✓ scrollDisplayRight()
Se desplaza el contenido de la pantalla (texto y el cursor) un espacio a la derecha.
✓ backlight();
Enciende la Luz del Fondo del LCD
✓ noBacklight();
Apaga la Luz del Fondo del LCD
✓ createChar (num, datos)
Crea un carácter personalizado para su uso en la pantalla LCD. Se admiten hasta
ocho caracteres de 5x8 píxeles (numeradas del 0 al 7). Dónde: num es el número de
carácter y datos es una matriz que contienen los pixeles del carácter. Se verá un ejemplo
de esto más adelante.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
void setup() {
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
// Escribimos el Mensaje en el LCD.
lcd.print("Hola Mundo");
}
void loop() {
16
// Ubicamos el cursor en la primera posición(columna:0) de la segunda línea(fila:1)
lcd.setCursor(0, 1);
// Escribimos el número de segundos trascurridos
lcd.print(millis()/1000);
lcd.print(" Segundos");
delay(100);
}
La programación es similar para un LCD de 20x4, solo hay que modificar en:
LiquidCrystal_I2C lcd(0x27,20,4);
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//Crear el objeto lcd dirección 0x27 y 16 columnas x 2 filas
LiquidCrystal_I2C lcd(0x27,16,2); //
17
void setup() {
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
// Escribimos el Mensaje en el LCD en una posición central.
lcd.setCursor(10, 0);
lcd.print("WWW.NAYLAMPMECHATRONICS.COM");
lcd.setCursor(4, 1);
lcd.print("Tutorial LCD, Test de desplazamiento ");
}
void loop() {
//desplazamos una posición a la izquierda
lcd.scrollDisplayLeft();
delay(500);
}
18
2.2.5 3. Mostrando datos de sensores o variables en el LCD
En este ejemplo mostramos en el LCD variables, que pueden representar valores
de sensores u otros datos. Para simular los sensores usaremos potenciómetros
conectados a los puertos analógicos.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
void setup() {
// Inicializar el LCD
lcd.init();
//Encender la luz de fondo.
lcd.backlight();
}
void loop() {
int sen1=analogRead(A0);
float sen2=analogRead(A1)*(5.0 / 1023.0);
float sen3=analogRead(A2)*(100.0 / 1023.0);
int tiempo=millis()/1000;
// Cursor en la primera posición de la primera fila
lcd.setCursor(0,0);
lcd.print("ADC:");
lcd.print(sen1);
lcd.print(" ");
// Cursor en la 11° posición de la primera fila
lcd.setCursor(10,0);
lcd.print("V:");
lcd.print(sen2,1);//1 decimal
lcd.print("V ");
// Cursor en la primera posición de la 2° fila
lcd.setCursor(0,1);
lcd.print("T:");
lcd.print(sen3,1); //1 decimal
lcd.print("337C "); // "337" -> "°"
// Cursor en la 11° posición de la 2° fila
19
lcd.setCursor(10,1);
lcd.print("t:");
lcd.print(tiempo);
lcd.print(" s ");
delay(200);
}
20
Como máximo podemos crear 8
caracteres nuevos.
21
A continuación se muestra el código para implementar los nuevos caracteres.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
22
B10000,
B10000,
B10000,
B11111,
B00000,
};
byte M[8] = {
B11111,
B10101,
B10101,
B10101,
B10101,
B10101,
B10101,
B00000,
};
byte P[8] = {
B11111,
B10001,
B10001,
B10001,
B11111,
B10000,
B10000,
B00000,
};
byte cara[8] = {
B00000,
B10001,
B00000,
B00000,
B10001,
B01110,
B00000,
};
byte cuerpo[8] = {
B01110,
B01110,
B00100,
B11111,
23
B00100,
B01010,
B10001,
B00000,
};
void setup() {
// Inicializar el LCD
lcd.init();
24
lcd.write (byte (7));
}
void loop () {}
25
3 ESQUEMAS
26
4 LISTA DE COMPONENTES
27
4.2 Placaprincipal
28
4.3 Placa para el cuerpo de Mariposa y Pedal acelerador
Para poder adaptar los voltajes que genera el microcontrolador (arduino) y que
estas señales puedan ser reconocidas por la ECU, se ha de intercalar este circuito con el
fin de elevar la señal (intensidad) ya que la señal del arduino es débil.
Básicamente este circuito es un adaptador o interfase que mediante las señales
que son generadas por el arduino va a microcontrolar la tensión variable que generará el
LM317 (regulador variable de tensión).
Mediante el siguiente esquema se ha incorporado dos relés que conectan y
desconectan automáticamente cuando se conecta la clavija externa del cuerpo de
mariposa y el del acelerador, si está no se conecta la señal pasará por el interface.
29
5 CONEXIONES
Dado que el corazón del proyecto es el microcontrolador basado en un arduino y
sus conexiones de entras y salidas, en la siguiente imagen se puede apreciar de una forma
más reducida montada directamente sobre una placa de arduino uno, aunque en nuestro
proyecto en la placa principal se ha insertado el microcontrolador de arduino con el fin de
optimizar el espacio.
En cuanto a las conexiones exteriores del comprobador son las siguientes, consta
de 4 conexiones, 2 de ellas que van directamente a la ECU, otra para poder conectar un
cuerpo de mariposa y acelerador exterior y otra que nos permitirá modificar el programa de
arduino sin necesidad de extraer el microcontrolador.
30
31
6 PROGRAMA ARDUINO (GENERADOR SEÑAL CKP-CMP)
/********************************************************************************************
* Proyecto: Generador de señal CKP y CMP con ajuste de avance y RPM *
* Autor : Jorge Vázquez *
* Fecha : 27/11/2016 *
* Versión : 1.3 Arduino UNO *
* Notas : Se añade configuración para pedal de acelerador *
* Pines : LCD= I2C (4 y 5) S. Señal CKP= 5 S. Señal CMP= 6 S. Señal Acel 1= 3 *
* S. Señal Acel 2= 9 Potenciómetro Acelerador= A2 Potenciómetro RPM= A1 *
* Pulsadores= A3 *
********************************************************************************************/
// Declaración de librerías
#include <Wire.h> // Declaración de la librería para comunicar con dispositivos I2C / TWI (SDA y SCL)
#include <LiquidCrystal_I2C.h> // Declaración de la librería I2C
32
float Pista2Max = 0.50; // Valor en tensión máximo de la pista 2
float PistaAMin; // Valor en PWM mínimo de la pista 1
float PistaAMax; // Valor en PWM máximo de la pista 1
float PistaBMin; // Valor en PWM mínimo de la pista 2
float PistaBMax; // Valor en PWM máximo de la pista 2
int Pista1; // Salida de tensión de la pista 1 del acelerador (este
oscilara entre los valores indicados en Pista1Min y Pista1Max)
int Pista2; // Salida de tensión de la pista 2 del acelerador (este
oscilara entre los valores indicados en Pista2Min y Pista2Max)
int Beep = 1; // Variable que indica si funciona o no el sonido
int LCD_ON = 1; // Variable que indica si la luz del LCD está encendida
int Cilindro = 1; // Variable para indicar el cilindro inicial
int RPM; // Variable de la señal RPM
int Acelerador; // Variable de la señal del Acelerador
//Pines (I/O)
int CMP = 6; // Pin de salida para la señal CMP
int CKP = 5; // Pin de salida para la señal CKP
int Buzzer = 7; // Pin Digital 7
int LCD = 4; // Pin Digital 4
int Acelerador1 = 3; // Pin de salida para la señal del acelerador (pista 1)
int Acelerador2 = 9; // Pin de salida para la señal del acelerador (pista 2)
int PontRPM = 16; // Pin de entrada para el potenciómetro RPM A2
int PontAcelerador = 15; // Pin de entrada para el potenciómetro del acelerador A1
int Boton = 17; // Pin de entrada para el Botón A3
boolean Parpadeo = true; // Variable que indica el ultimo estado del parpadeo
long HoraPrevia = 0; // Variable para indicar la hora de inicio desde que se
reinicio
long Intervalo = 480; // Variable para indicar el tiempo de retardo
33
//**************************************** Inicio del loop *****************************************
void loop() {
// if (key > -1) Sonido_Accion(); // Cada pulsación suena un pitido
Menus (); // Se ejecuta el bloque de Menú_0
if (a!= 9) { // Solamente aparece el menú 0 al iniciar (hora + Fecha)
get_time (); // Se ejecuta el bloque de Get_Time
get_date (); // Se ejecuta el bloque de Get_Date
display_time (); // Se ejecuta el bloque de Display_Time
display_date (); // Se ejecuta el bloque de Display_Date
unsigned long HoraActual = millis (); // A la variable HoraAtual se le graba el valor de tiempo de
ejecución desde el ultimo reset
if (HoraActual - HoraPrevia > Intervalo){// Si el valor de HoraActual - HoraPrevia > Intervalo entonces
....
HoraPrevia = HoraActual; // Se actualiza la variable HoraPrevia con el valor de
HoraActual
if (Parpadeo == true){ // Si el valor de Parpadeo es verdadero
Parpadeo = false ; // Se cambia el valor de Parpadeo a Falso
lcd.setCursor (13,0); // Posicionamos el texto en la 14ª posición de la 1ª fila
lcd.print (" "); // Se escribe el texto
} // Fin del IF
else { // Y sino ....
lcd.setCursor (13,0); // Posicionamos el texto en la 14ª posición de la 1ª fila
lcd.print (":"); // Se escribe el texto
Parpadeo = true ; // La variable Parpadeo pasa a valor Verdadero
} // Fin del IF
} // Fin del IF
Menus (); // Se ejecuta el bloque de Menú_0
} // Fin del IF
} // Fin del Loop
//**************************************** Fin del loop ********************************************
// Se contabiliza el número de pulsaciones del pulsador OK para evitar que se salten menús
if (key == 2) { // Si se pulsa la tecla OK
P=P++; // Se incrementa el valor de la variable P
delay (200); // Se pausa 200mseg. (Evitar rebotes de pulsador)
} // Fin del IF
34
////////// Menú 4 (Ajuste Acelerador) ///////
if (a == 2 && key == 2 && P == 1){ // Estamos en el menú de Ajuste de Hora
lcd.setCursor (0,0); // Posicionamos el texto en la 1ª posición de la 1ª fila
lcd.print (" Ajuste Acel. "); // Se escribe el texto
a = 9; // Se cambia el valor de la variable A para no entrar en el
menú Principal (Menú 1)
d = 1; // Se cambia la variable I para indicar que estamos en el menú
de Ajuste de Acelerador
} // Fin del IF
Menu_4 (); // Se ejecuta el bloque de Menú_4
/////////////////////////////////////////////
35
lcd.print (" Se"); // Se escribe el texto
lcd.print (char(238)); // Escribimos el carácter "ñ"
lcd.print ("al (EDC15C2)"); // Se escribe el texto
lcd.setCursor (2,1); // Posicionamos el texto en la 1ª posición de la 2ª fila
lcd.print (D); // Se escribe la variable
lcd.print ("-"); // Se escribe el texto
lcd.print (H); // Se escribe la variable
lcd.print (" con fase "); // Se escribe el texto
Sonido_Accion(); // Se ejecuta el bloque de Sonido_Accion
y = 1; // Variable para ejecutar la señal del CKP y CMP
b = 9; // Se cambia el valor de la variable B para indicar que se
sale de este bucle
N = 1; // Se cambia la variable N para indicar que no entramos en el
menú de ajuste del pedal del acelerador
} // Fin del IF
Menu_7 (); // Se ejecuta el bloque de Menú_7
/////////////////////////////////////////////
36
Sonido_Accion(); // Se ejecuta el bloque de Sonido_Accion
y = 1; // Variable para ejecutar la señal del CKP y CMP
b = 9; // Se cambia el valor de la variable B para indicar que se
sale de este bucle
N = 1; // Se cambia la variable N para indicar que no entramos en el
menú de ajuste del pedal del acelerador
} // Fin del IF
Menu_7 (); // Se ejecuta el bloque de Menú_7
/////////////////////////////////////////////
37
/////////////////////////////////////////////
38
lcd.setCursor (2,1); // Posicionamos el texto en la 1ª posición de la 2ª fila
lcd.print (D); // Se escribe la variable
lcd.print ("-"); // Se escribe el texto
lcd.print (H); // Se escribe la variable
lcd.print (" sin fase "); // Se escribe el texto
Sonido_Accion(); // Se ejecuta el bloque de Sonido_Accion
c = 9; // Se cambia el valor de la variable C para indicar que se
sale de este bucle
N = 1; // Se cambia la variable N para indicar que no entramos en el
menú de ajuste del pedal del acelerador
} // Fin del IF
Menu_7 (); // Se ejecuta el bloque de Menú_7
/////////////////////////////////////////////
39
y = 0; // Variable para indicar si la ECU tiene diferentes señales de
CKP y CMP según el número de cilindro (por ejemplo EDC15P)
j = 0; // Variable para ejecutar la señal del CKP y CMP
case 2: // Cilindro Nº 2
if (y == 1){ // Si es la ECU EDC15 (Variable Y = 1)
switch (count){ // Se ejecuta el bloque Switch
case 2: // Si es el diente 2 del CKP
digitalWrite(CMP, LOW); // Se pone la salida digital CMP en estado bajo
break; // Salimos del SWITCH
case 3: // Si es el diente 3 del CKP
digitalWrite(CMP, HIGH); // Se pone la salida digital CMP en estado alto
break; // Salimos del SWITCH
case 5: // Si es el diente 5 del CKP
digitalWrite(CMP, LOW); // Se pone la salida digital CMP en estado bajo
break; // Salimos del SWITCH
case 6: // Si es el diente 6 del CKP
digitalWrite(CMP, HIGH); // Se pone la salida digital CMP en estado alto
break; // Salimos del SWITCH
} // Fin del SWITCH
} // Fin del IF
40
break; // Salimos del SWITCH
} // Fin del SWITCH
} // Fin del IF
break;*/ // Salimos del SWITCH
case 3: // Cilindro Nº 3
if (y == 1){ // Si es la ECU EDC15 (Variable Y = 1)
switch (count){ // Se ejecuta el bloque Switch
case 2: // Si es el diente 2 del CKP
digitalWrite(CMP, LOW); // Se pone la salida digital CMP en estado bajo
break; // Salimos del SWITCH
case 3: // Si es el diente 3 del CKP
digitalWrite(CMP, HIGH); // Se pone la salida digital CMP en estado alto
break; // Salimos del SWITCH
} // Fin del SWITCH
} // Fin del IF
case 4: // Cilindro Nº 4
if (y == 1){ // Si es la ECU EDC15 (Variable Y = 1)
switch (count){ // Se ejecuta el bloque Switch
case 2: // Si es el diente 2 del CKP
digitalWrite(CMP, LOW); // Se pone la salida digital CMP en estado bajo
break; // Salimos del SWITCH
case 3: // Si es el diente 3 del CKP
digitalWrite(CMP, HIGH); // Se pone la salida digital CMP en estado alto
break; // Salimos del SWITCH
case 8: // Si es el diente 8 del CKP
digitalWrite(CMP, LOW); // Se pone la salida digital CMP en estado bajo
break; // Salimos del SWITCH
case 9: // Si es el diente 9 del CKP
digitalWrite(CMP, HIGH); // Se pone la salida digital CMP en estado alto
break; // Salimos del SWITCH
} // Fin del SWITCH
} // Fin del IF
41
//**************************************** Logotipo ************************************************
void Logo (){
lcd.createChar (0, caracter0); // Se crea el caracter especial "caracter0" y se guarda en el
byte 0
lcd.createChar (1, caracter1); // Se crea el caracter especial "caracter1" y se guarda en el
byte 1
lcd.createChar (2, caracter2); // Se crea el caracter especial "caracter2" y se guarda en el
byte 2
lcd.createChar (3, caracter3); // Se crea el caracter especial "caracter3" y se guarda en el
byte 3
lcd.createChar (4, caracter4); // Se crea el caracter especial "caracter4" y se guarda en el
byte 4
lcd.createChar (5, caracter5); // Se crea el caracter especial "caracter5" y se guarda en el
byte 5
lcd.createChar (6, caracter6); // Se crea el caracter especial "caracter6" y se guarda en el
byte 6
lcd.createChar (7, caracter7); // Se crea el caracter especial "caracter7" y se guarda en el
byte 7
42
case 0: // Tipo de señal
lcd.setCursor (0,1); // Posicionamos el texto en la 1ª posición de la 2ª fila
lcd.print (" Tipo de ECU "); // Se escribe el texto
lcd.print (char(126)); // Se escribe la flecha a la derecha
if (key == 0){ // Si se pulsa la tecla de la derecha
a++; // Incrementamos 1 unidad la variable D para pasar al
siguiente Item
delay (250); // Se pausa 200mseg. (Evitar rebotes de pulsador)
} // Fin del IF
if (key == 3){ // Si se pulsa la tecla de la izquierda
a=0; // Se cambia el valor de la variable D para pasar al siguiente
Item
delay (250); // Se pausa 200mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
43
lcd.print (" EDC15P "); // Se escribe el texto
D=60; // Se indica en la variable D los dientes
H=4; // Se indica en la variable H los huecos
Pista1Min = 0.50; // Valor en tensión mínimo de la pista 1
Pista1Max = 4.50; // Valor en tensión máximo de la pista 1
Pista2Min = 0.00; // Valor en tensión mínimo de la pista 2
Pista2Max = 0.00; // Valor en tensión máximo de la pista 2
lcd.print (char(126)); // Se escribe la flecha a la derecha
if (key == 0){ // Si se pulsa la tecla de la derecha
b++; // Incrementamos 1 unidad la variable D para pasar al
siguiente Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
if (key == 3){ // Si se pulsa la tecla de la izquierda
b=1; // Se cambia el valor de la variable D para pasar al siguiente
Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
44
if (key == 0){ // Si se pulsa la tecla de la derecha
b++; // Incrementamos 1 unidad la variable D para pasar al
siguiente Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
if (key == 3){ // Si se pulsa la tecla de la izquierda
b--; // Decrecemos 1 unidad la variable D para pasar al siguiente
Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
45
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
46
lcd.print (" 30-2 "); // Se escribe el texto
D=30; // Se indica en la variable D los dientes
H=2; // Se indica en la variable H los huecos
lcd.print (char(126)); // Se escribe la flecha a la derecha
if (key == 0){ // Si se pulsa la tecla de la derecha
c++; // Incrementamos 1 unidad la variable D para pasar al
siguiente Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
if (key == 3){ // Si se pulsa la tecla de la izquierda
c--; // Decrecemos 1 unidad la variable D para pasar al siguiente
Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
47
if (d == 1){ // Se ajusta los valores de la pista 1
if (x==0) { // Si la variable X=0
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista1Max); // Se escribe el valor de la variable Pista1Max
x=1; // Se cambia el valor de la variable X para no volver a
ejecutar el IF
} // Fin del IF
unsigned long HoraActual = millis (); // A la variable HoraAtual se le graba el valor de tiempo de
ejecución desde el ultimo reset
if (HoraActual - HoraPrevia > Intervalo){// Si el valor de HoraActual - HoraPrevia > Intervalo entonces
....
HoraPrevia = HoraActual; // Se actualiza la variable HoraPrevia con el valor de
HoraActual
if (Parpadeo == true){ // Si el valor de Parpadeo es verdadero
Parpadeo = false ; // Se cambia el valor de Parpadeo a Falso
if (d == 1 && P == 1){ // Esta en la posición del valor Pista1Min
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista1Min); // Se escribe el valor de la variable Pista1Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista1Max); // Se escribe el valor de la variable Pista1Max
} // Fin del IF
if (d == 1 && P == 2){ // Esta en la posición del valor Pista1Max
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista1Min); // Se escribe el valor de la variable Pista1Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista1Max); // Se escribe el valor de la variable
Pista1Max
} // Fin del IF
} // Fin del IF
else { // Y sino ....
if (d == 1 && P == 1){ // Esta en la posición del valor Pista1Min
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (" "); // Se escribe el texto
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista1Max); // Se escribe el valor de la variable Pista1Max
} // Fin del IF
if (d == 1 && P == 2){ // Esta en la posición del valor Pista1Max
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista1Min); // Se escribe el valor de la variable Pista1Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (" "); // Se escribe el texto
} // Fin del IF
Parpadeo = true ; // La variable Parpadeo pasa a valor Verdadero
} // Fin del IF
} // Fin del IF
48
if (Pista1Max > 5.0) Pista1Max=0.0; // Si el valor de la variable Pista1Max mayor de 5.0 pasamos
al valor 0.0
lcd.print (Pista1Max); // Se escribe el valor de la variable Pista1Max
} // Fin del IF
if (key == 3 && P == 2){ // Si pulsamos el botón de la izquierda
Pista1Max = Pista1Max - 0.1; // Decrecemos 0.1 unidad la variable Pista1Max
delay (Intervalo); // Se pausa por el valor del intervalo (Evitar rebotes de
pulsador)
if (Pista1Max < 0.0) Pista1Max=5.0; // Si el valor de la variable Pista1Max menor de 0.0 pasamos
al valor 5.0
lcd.print (Pista1Max); // Se escribe el valor de la variable Pista1Max
} // Fin del IF
unsigned long HoraActual = millis (); // A la variable HoraAtual se le graba el valor de tiempo de
ejecución desde el ultimo reset
if (HoraActual - HoraPrevia > Intervalo){// Si el valor de HoraActual - HoraPrevia > Intervalo entonces
....
HoraPrevia = HoraActual; // Se actualiza la variable HoraPrevia con el valor de
HoraActual
if (Parpadeo == true){ // Si el valor de Parpadeo es verdadero
Parpadeo = false ; // Se cambia el valor de Parpadeo a Falso
if (d == 2 && P == 3){ // Esta en la posición del valor Pista2Min
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista2Min); // Se escribe el valor de la variable Pista2Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista2Max); // Se escribe el valor de la variable Pista2Max
} // Fin del IF
if (d == 2 && P == 4){ // Esta en la posición del valor Pista2Max
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista2Min); // Se escribe el valor de la variable Pista2Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista2Max); // Se escribe el valor de la variable Pista2Max
} // Fin del IF
} // Fin del IF
else { // Y sino ....
if (d == 2 && P == 3){ // Esta en la posición del valor Pista2Min
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (" "); // Se escribe el texto
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (Pista2Max); // Se escribe el valor de la variable Pista2Max
} // Fin del IF
if (d == 2 && P == 4){ // Esta en la posición del valor Pista2Max
lcd.setCursor (6,1); // Posicionamos el texto en la 7ª posición de la 1ª fila
lcd.print (Pista2Min); // Se escribe el valor de la variable Pista2Min
lcd.setCursor (11,1); // Posicionamos el texto en la 12ª posición de la 1ª fila
lcd.print (" "); // Se escribe el texto
} // Fin del IF
Parpadeo = true ; // La variable Parpadeo pasa a valor Verdadero
49
} // Fin del IF
} // Fin del IF
50
e=2; // Se cambia el valor de la variable D para mantenerse en este
Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
if (key == 3){ // Si se pulsa la tecla de la izquierda
e=1; // Se cambia el valor de la variable D para pasar al siguiente
Item
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
} // Fin del IF
break; // Salimos del switch
} // Fin del SWITCH
} // Fin del Menu_5
//**************************************************************************************************
51
lcd.clear (); // Se limpia el lcd
a = 0; // Se cambia el valor de la variable A acceder al Menú 1 (Menú
Principal)
e = 0; // Se mantiene la variable I para estar en el Menú 10 (Ajuste
de Hora)
HF = 0; // Confirmación de ajuste de Hora y Fecha
P = 0; // Variable que indica el número de pulsaciones de la tecla OK
(se pone el contador a cero)
loop (); // Se ejecuta el bloque de Loop
} // Fin del IF
break; // Salimos del switch
52
month++; // Incrementamos 1 unidad del Mes
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
if (month > 12) month=1; // Si el valor del Mes es mayor de 12 pasamos al valor 1
lcd.write (month); // Se guarda el valor del Mes
} // Fin del IF
if (key == 3 && P == 3){ // Si pulsamos el botón de la izquierda
month--; // Decrecemos 1 unidad del Mes
delay (250); // Se pausa 250mseg. (Evitar rebotes de pulsador)
if (month < 1) month=12; // Si el valor del Mes es menor de 1 pasamos al valor 12
lcd.write (month); // Se guarda el valor del Mes
} // Fin del IF
53
Pista1 = map (Acelerador,0,1023,PistaAMin,PistaAMax); // Mapeo de la pista 1 con los valores mínimos
y maximos prefijados
Pista2 = map (Acelerador,0,1023,PistaBMin,PistaBMax); // Mapeo de la pista 2 con los valores mínimos
y maximos prefijados
analogWrite(Acelerador1 ,Pista1); // Salida del voltaje de la pista 1
analogWrite(Acelerador2 ,Pista2); // Salida del voltaje de la pista 2
54
break; // Salimos del switch
} // Fin del SWITCH
} // Fin del Display_Date
void initChrono (){ // Se graban los nuevos valores en la memoria del Reloj
set_time (); // Se registra en el RTC los nuevos valores (Hora y Minutos)
set_date (); // Se registra en el RTC los nuevos valores (Día, Mes y Año)
} // Fin del initChrono
void set_time () {
Wire. beginTransmission (104); // Empieza transmisión.
Wire. write ((byte)0); // Set register to 0
Wire. write (decToBcd(seconds));
Wire. write (decToBcd(minutes));
Wire. write (decToBcd(hours));
Wire. endTransmission (); // Termina transmisión
} // Fin del set_time
void get_time () {
Wire. beginTransmission (104); // Empieza transmisión.
Wire. write ((byte)0); // Set register to 0
Wire. endTransmission (); // Termina transmisión
Wire. requestFrom (104,3); // Get 3 bytes (seconds,minutes,hours);
seconds = bcdToDec ( Wire. read() & 0x7f );
minutes = bcdToDec ( Wire. read ());
hours = bcdToDec ( Wire. read () & 0x3f );
}
55
} // Fin del IF
} // Fin del bucle Sonido Acción
// Sonido de confirmación
void Sonido_Confirmacion() { // Bloque de Sonido Confirmación
if (Beep == 1){ // Si la variable Beep está en 1 se ejecuta el
bucle
digitalWrite(Buzzer, HIGH); // Se ponen en estado ALTO el pin del buzzer
delay(50); // Se pausa 50mseg.
digitalWrite(Buzzer, LOW); // Se ponen en estado BAJO el pin del buzzer
delay(150); // Se pausa 150mseg.
digitalWrite(Buzzer, HIGH); // Se ponen en estado ALTO el pin del buzzer
delay(50); // Se pausa 50mseg.
digitalWrite(Buzzer, LOW); // Se ponen en estado BAJO el pin del buzzer
} // Fin del IF
} // Fin del bucle Sonido Confirmación
56
7 PLANOS
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73