Accede A Apuntes, Guías, Libros y Más de Tu Carrera: Programa-Simulador-De-Ecu-V13 74 Pag
Accede A Apuntes, Guías, Libros y Más de Tu Carrera: Programa-Simulador-De-Ecu-V13 74 Pag
programa-simulador-de-ecu-v13
74 pag.
---------------------------
[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.
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
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.
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
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 () {
}
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:
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();
10
#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
12
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
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 funciones que utiliza esta librería son similares a la librería LiquidCrystal de
Arduino, pero volveremos a explicaremos las funciones principales.
15
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
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 loop() {
//desplazamos una posición a la izquierda
lcd.scrollDisplayLeft();
delay(500);
}
18
#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
20
21
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
22
23
void setup() {
// Inicializar el LCD
lcd.init();
24
void loop () {}
25
26
27
28
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
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
// 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
//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
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
35
36
37
38
39
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
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
42
43
44
45
46
47
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
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
50
51
52
53
54
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
// 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
57