Proyecto: Control Variables Motor 4 Tiempos para mejora funcionamiento a Gas

Hola a todos, me encuentro desarrollando el software para el Arduino Uno, para el control de algunas variables de un motor de 4 tiempos para el Control del motor de un Auto y la cantidad de gas entredada por un equipo de Gas Natural Comprimido de 2da Generación.

Tomo información del sensor inductivo posición del cigüeñal (ckp) para desfasar la señal y así desfasar la chispa de las bujías. Tomo la señal del sensor de posicion del acelerador (TPS) e información de la sonda Lambda (Medición de Oxigeno en el escape) para controlar la entrada de gas al motor.

Los sensores de referencia son los siguientes:

Sensor CKP:
https://mecanicabasicacr.com/osciloscopio/forma-de-onda-de-un-sensor-de-posicion-de-ciguenal-ckp.html
https://forum.arduino.cc/index.php?topic=567187.0

Sensor TPS:
https://www.autodaewoospark.com/sensor-TPS.php

Sensor de O2:

http://www.aficionadosalamecanica.net/sonda-lambda.htm

El código es el siguiente:

const int salida = 10;  //a la ecu
const int interrupcion = 2; //sensor ckp
const int sensorTps = A1; //sensor acelerador
const int sensorLambda = A0; // medicion de la sonda lambda
const int actuadorMPP = 9

//variables
int medicionTps = 0;
int medicionLambda = 0;
int tiempoInicial=0;
int tiempoBajo=0;
int tiempoAnterior=0
int contadorBajos=0;
int contadorAltos=0;
int rpmRelenti=900;
int encendido=0;
int lambda=0;
long ciclos=0;
int retardoVariable=0;
dientes
contador




//referencias
int lambdaMin=500;
int lambdaMax=1500;
int tpsMin=500;
int tpsMax=5000;
int valorActuadorMPP=125;
int valorActuadorMPPMin=10;


int rpmVector[50];
int mapaRevoluciones[] = { 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 , 15 }
// 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000
int mapaLambda[] = { 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 , 125 }
// 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 6500 7000


/************************************************************************************************************************************************/

void setup()
 {
 pinMode(salida, OUTPUT);
 pinMode(interrupcion, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(interrupcion),interrupcionFlancoDecendente, FALLING);//siempre inicio contando el bajo
 retardoVariable=retardo(0);
 }

/************************************************************************************************************************************************/

void loop() 
 {
//calculo las Rpms del motor
 
 if(dientes) //se realiza si ya se determinadron la cantidad de dientes
 if(contador==dientes) //se realiza en cada vuelta
 if(tiempoBajo<tiempoAnterior*1,15) //solo calculo rpm para los pulsos normales
 {
 calculoRpm();
 retardoVariable=retardo(1);
 }
 if(encendido) //si el gnc esta activado actuo sobre la sonda lambda
 controlLambda();
 }
/************************************************************************************************************************************************/

interrupcionFlancoDecendente //copio señal de entrada hasta que puedo calcular ancho de dientes y rpms
 {
 delayMicroseconds(retardoVariable);
 digitalWrite(salida,LOW);
 tiempoInicial=micros();
 tiempoAlto=tiempoInicial-tiempoBajo;
 attachInterrupt(digitalPinToInterrupt(interrupcion),interrupcionFlancoAscendente, RISING);
 }

interrupcionFlancoAscendente
 {
 delayMicroseconds(retardoVariable);
 digitalWrite(salida,HIGH);
 tiempoBajo=micros()-tiempoInicial;
 tiempoAnterior=tiempoBajo;
 cuentaDientes();
 attachInterrupt(digitalPinToInterrupt(interrupcion),interrupcionFlancoDecendente, FALLING);
 }

/************************************************************************************************************************************************/

int retardo(int activado) //calcula retardo en funcion de las rpm y el ancho del pulso, devuelve uS 
 {
 if(activado)
 {
 if(sensorTps=0)
 return 15;
 else
 {
 avanceIntermedio=interpolacion(rpm,rpm/500,mapaRevoluciones[rpmInf],rpm/500+1,mapaRevoluciones[rpmSup]);
 return round(avanceIntermedio);
 }
 }
 else
 return 0;
 }

/************************************************************************************************************************************************/
//Control lambda
void controlLambda(void)
 {
 medicionLambda = analogRead(sensorLambda);
 medicionLambdaMap = map(medicionLambda, lambdaMin, lambdaMax, 0, 255); 
 medicionTps = analogRead(sensorTps);
 medicionTps = map(medicionTps, TpsMin, TpsMax, 0, 255);
 //500 600 700 800 900 1000 1100 1200 1300 1400 1500
 // 0 26 52 78 104 130 156 182 208 234 255
 // 0 1 2 3 4 5 6 7 8 9 10

 controlLambdaRef();
 
 if(medicionLambdaMap < lambdaRef) // establezco rangos de velocidad de actuacion
 {
 if(medicionLambdaMap < lambdaRef*2/10 && medicionLambdaMap => lambdaRef*0/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,20);
 if(medicionLambdaMap < lambdaRef*4/10 && medicionLambdaMap => lambdaRef*2/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,10);
 if(medicionLambdaMap < lambdaRef*5/10 && medicionLambdaMap => lambdaRef*4/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,1);
 }
 else
 {
 if(medicionLambdaMap < lambdaRef*10/10 && medicionLambdaMap => lambdaRef*7/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,20);
 if(medicionLambdaMap < lambdaRef*7/10 && medicionLambdaMap => lambdaRef*6/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,10);
 if(medicionLambdaMap < lambdaRef*6/10 && medicionLambdaMap => lambdaRef*5/10 )
 valorActuadorMPP=funcionActuador(valorActuadorMPP,1);
 }
 if(medicionTps>=TpsMax*0.95) //apertura total con el pedal a fondo
 valorActuadorMPP=valorActuadorMPPMax;
 if(medicionTps<=TpsMmin) //cierre cuando se saca el pie del acelerador
 valorActuadorMPP=valorActuadorMPPMin;
 analogWrite(actuadorMPP, valorActuadorMPP);
 }
 
void controlLambdaRef(void)
 {
 lambdaRef = =interpolacion(rpm,rpm/500,mapaLambda[rpm/500],rpm/500+1,mapaLambda[rpm/500+1])
 }
 
int funcionActuador(int valorinicial,int incremento)
 {
 return valorinicial+incremento;
 }

/************************************************************************************************************************************************/

void calculoRpm(void)
 {
 periodo=(2*(dientes+2)*tiempoAlto); //periodo en uS de 1 vuelta es igual a 58 dientes/58 huecos + 4 huecos
 rpm=60/(periodo/1000000); //calculo sobre tiempo alto para evitar los huecos dobles
 }

/************************************************************************************************************************************************/

//funcion interpolacion
int interpolacion(int x,int x1,int y1,int x2,int y2)
 {
 float y;
 y=(x-x1)(y2-y1)/(x2-x1)+y1;
 return round(y);
 }

/************************************************************************************************************************************************/

int retardo(int grados)
 {
 long retardoX;
 retardoX=tiempoAlto*2*grados/360;
 if(retardoX<=3) //minima resolucion de delaymicros() sin error
 retardoX=3;
 return round(retardoX);
 }

/************************************************************************************************************************************************/
 
void cuentaDientes(void)
 {
 if(tiempoAnterior!=0)
 {
 if(tiempoBajo>tiempoanterior*1,75)
 {
 iniciarCuenta=!iniciarCuenta;
 dientes=contadorAltos; 
 }
 }
 if(iniciarcuenta)
 if(dientes!=contadorAltos
 contadorAltos++;
 else
 contadorAltos=0;
}

Espero de su colaboración para mejorar el código dado que esto es solo el primer borrador.

Saludos,

Leonardo

PD: Tengo mi proyecto en Github: https://github.com/leogbar/ControlGnc
Variables

como mi intensión antes de probar esto en un auto real con equipo de gas, es ensayarlo, la idea es hacerlo con otro arduino y simular las variables que senso del motor para ver como reacciona el código de control

#include <TimerOne.h>


const int salida = 10;
const int sensorTps = 11;
const int sensorLambda = 12;
bool estado = false;
int varDientes=0;
int dientes=58;
int huecos=2;
int alto=1;
int bajo=1;
int valorTps=0;
int valorLambda=0;

void setup(void)
{
 pinMode(salida, OUTPUT);
 pinMode(sensorTps, OUTPUT);
 pinMode(sensorLambda, OUTPUT);
 digitalWrite(salida, LOW);
 Timer1.initialize(medioperiodo(900));
 Timer1.attachInterrupt(cuadrada);
  salidaTps(0.0);
  salidaLambda(1);
}

void loop (void)
{
 Timer1.initialize(medioperiodo(900));
 Timer1.attachInterrupt(cuadrada);
  salidaTps(0);
  salidaLambda(1);
}


int medioperiodo(int revs)
{
 return round((60/revs/((dientes+huecos)*2))*1000000);
}


void cuadrada(void)
{
 if(alto<=dientes*2)
 {
 if (estado) 
 {
 digitalWrite(salida, LOW);
 estado = false;
 bajo++;
 }
 else 
 {
 digitalWrite(salida, HIGH);
 estado = true;
 alto++;
 }
 }
 else
 { 
 if(bajo<(dientes+huecos)*2)
 {
 digitalWrite(salida, LOW);
 estado = false;
 bajo++; 
 }
 else
 {
 digitalWrite(salida, LOW);
 estado = false;
 bajo=1;
 alto=1;
 }
 }
 }


void salidaTps(int voltaje)
{
 valorTps=map(voltaje, 0, 5, 0, 255);
  analogWrite(sensorTps, valorTps);
}

void salidaLambda(float voltaje)
{
 valorLambda=map(voltaje, 0.5, 1.5, 0, 255);
 analogWrite(sensorLambda, valorLambda);
}

He podido compilarlo y depurarlo en Arduino IDE pero no simularlo en AVR Studio dado que no encuentra la libreria TimerOne.h

1 Like