[Aporte] Panel de instrumentos para automóviles (En fase de desarrollo)

Ratmayor

ModeraTroll
El siguiente proyecto se trata de un panel de instrumentos para automóviles que cuenta con:
  • Velocímetro.
  • Contador de recorrido.
  • Medidor de presión de aceite.
  • Medidor de temperatura.
  • Medidor de tensión.
  • Avisos sobre el funcionamiento en general.

Lo publico con 3 condiciones:
  1. NO deberá emplearse para fines comerciales. :(
  2. Si hacen una mejora en el software o hardware, por favor, publicarla. :D
  3. Ya que NO TODOS los vehículos son iguales, ni los displays y LCD tampoco, solo postearé el PCB de la tarjeta principal, para que cada quien personalice los visores a su gusto, recordando la condición número 2. :cool:
Ahora comencemos con el código del contador de recorrido :D

PHP:
//***************************************************//
//   Panel de instrumentos digital para vehículos    //
//                   Versión 4.0                     //
// Este sistema consta de:                           //
// *Odómetro, contador de recorrido.                 //
//***************************************************//
// Este programa ha sido creado por: Carlos Alvarez  //
// (Ratmayor) Bajo la licencia GNU GPL.              //
//***************************************************//
#include <16F628A.h>
 
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
 
#use delay(clock=4000000)
 
#zero_ram
#include <LCD420.C>
 
int km0, km1, km2, km3, km4, km5, od0, od1, od2, od3, a=0, b=0;
 
void main(){
   lcd_init();
   //Leemos los datos guardados en memoria para comenzar.
   km0 = read_eeprom (0x01);
   km1 = read_eeprom (0x02);
   km2 = read_eeprom (0x03);
   km3 = read_eeprom (0x04);
   km4 = read_eeprom (0x05);
   km5 = read_eeprom (0x06);
   od0 = read_eeprom (0x07);
   od1 = read_eeprom (0x08);
   od2 = read_eeprom (0x09);
   od3 = read_eeprom (0x10);
 
   for(;;){
      //Mostramos los datos cargados.
      lcd_gotoxy(1,1);
      printf(lcd_putc "%d%d%d%d%d%dKm",km5,km4,km3,km2,km1,km0);
      lcd_gotoxy(1,2);
      printf(lcd_putc "Tp %d%d%d.%d",od3,od2,od1,od0);
 
      //Reinicia contador (Reset).
      if(input(PIN_A2)){
         od0 = 0; od1 = 0; od2 = 0; od3 = 0;
      }
      //Reinicio general de los contadores (Hard reset).
      if(input(PIN_A2) && input(PIN_A4)){
         delay_ms(100);
         if(b==5){
            km0 = 0; km1 = 0; km2 = 0; km3 = 0; km4 = 0; km5 = 0; od0 = 0; od1 = 0; od2 = 0; od3 = 0;
         }
         b=b+1;
      }
      //Contador, requiere de la habilitación del micro principal para evitar conteos erróneos.
      if(input(PIN_A3)){
         //La variable a funciona como anti-rebotes.
         if(input(PIN_A1) && a==0){
            od0=od0+1;
            a=1;
         }
         else{
            a=0;
         }      
      }
 
      //Manejamos cada cifra por separado para no sobrecargar el PIC.
      //Además ayuda a la presentación.
      if(od0>9){od0=0; od1=od1+1;}
      if(od1>9){od1=0; od2=od2+1; km0=km0+1;} 
      if(od2>9){od2=0; od3=od3+1;}
      if(od3>9){od3=0;}
 
      if(km0>9){km0=0; km1=km1+1;}
      if(km1>9){km1=0; km2=km2+1;}
      if(km2>9){km2=0; km3=km3+1;}
      if(km3>9){km3=0; km4=km4+1;}
      if(km4>9){km4=0; km5=km5+1;}
      if(km5>9){km5=0;}
 
      //Terminado el conteo, se guardan los datos en la memoria interna del micro.
      if(!input(PIN_A3)){
         write_eeprom (0x01, km0);
         write_eeprom (0x02, km1);
         write_eeprom (0x03, km2);
         write_eeprom (0x04, km3);
         write_eeprom (0x05, km4);
         write_eeprom (0x06, km5);
         write_eeprom (0x07, od0);
         write_eeprom (0x08, od1);
         write_eeprom (0x09, od2);
         write_eeprom (0x10, od3);
      }
   }
}

Como notaron, manejé número por número, esto por 2 razones: 1) Para que se viera como el de los autos :cool: y 2) para no castigar al PIC manejando variables de 32bits con semejantes cantidades :LOL:

Ahora conozcamos el código de micro principal...

PHP:
//***************************************************// 
//   Panel de instrumentos digital para vehículos    // 
//                   Versión 4.3                     // 
// Este sistema consta de:                           // 
// *Velocímetro                                      // 
// *Medidor de presión de aceite                     // 
// *Medidor de temperatura                           // 
// *Medidor de tensión                               // 
// *Detección de palanca de cambios (T. Automática)  // 
//***************************************************// 
// Este programa ha sido creado por: Carlos Alvarez  // 
// (Ratmayor)                                        // 
//***************************************************// 
 
#include <16F877A.h> 
#device adc=8 
 
#FUSES NOWDT                    //No Watch Dog Timer 
#FUSES HS                       //Crystal osc <= 4mhz 
#FUSES NOPUT                    //No Power Up Timer 
#FUSES PROTECT                  //Code protected from reads 
#FUSES NOBROWNOUT               //No brownout reset 
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 
#FUSES NOCPD                    //No EE protection 
#FUSES NOWRT                    //Program memory not write protected 
#FUSES NODEBUG                  //No Debug mode for ICD 
 
#use delay(clock=8000000) 
 
#include <LCD420.C> 
 
//Inicio de variables 
float sensor, temper, volt, oil, fuel; 
int a=0, b=0, dis=0, shift, unit, decs, cent, speed, alt, ododiv=0, fail[6]; 
unsigned char segunit[10] = {0x04,0x0C,0x44,0x4C,0x24,0x2C,0x64,0x6C,0x14,0x1C}; 
unsigned char segdecs[10] = {0x02,0x0A,0x42,0x4A,0x22,0x2A,0x62,0x6A,0x12,0x1A}; 
unsigned char segcent[10] = {0x01,0x09,0x41,0x49,0x21,0x29,0x61,0x69,0x11,0x19}; 
 
//Inicio de programa principal 
void main(){ 
   //Configuración de ADC 
   setup_adc_ports(ALL_ANALOG); 
   setup_adc(adc_clock_internal); 
 
   //Inicio de display 
   lcd_init(); 
   output_c(0x00); 
   //Iniciamos el sistema 
   output_high(PIN_B3); //LCD Backlight. 
   output_high(PIN_D5); //Cinturones de seguridad. 
   //Presentación 
   lcd_gotoxy(1,1); 
   printf(lcd_putc "     RatNET     "); 
   lcd_gotoxy(1,2); 
   printf(lcd_putc "  ElectroGears  "); 
   delay_ms(3000); 
   lcd_putc("f"); 
   output_low(PIN_D5); 
 
   //Inicio de bucle de programa. 
   for(;;){ 
     //Lectura de ADCs 
     set_adc_channel(0); 
         delay_us(2); 
         sensor = read_adc(); 
         temper = (1.97 * sensor); 
     set_adc_channel(1); 
         delay_us(2); 
         volt = read_adc(); 
     set_adc_channel(2); 
         delay_us(2); 
         oil = read_adc(); 
     set_adc_channel(3); 
         delay_us(2); 
         shift = read_adc(); 
     set_adc_channel(4); 
         delay_us(2); 
         speed = read_adc(); 
     set_adc_channel(5); 
         delay_us(2); 
         fuel = read_adc(); 
     set_adc_channel(6); 
         delay_us(2); 
         alt = read_adc(); 
 
      //Divisor Odómetro 
      if(input(PIN_D2)){ 
         ododiv=ododiv+1; 
      } 
      if(ododiv > 150){ 
         output_high(PIN_D1); 
         delay_ms(2); 
         output_low(PIN_D1); 
         ododiv=0; 
      } 
 
      //Velocímetro 
      /*Los delay_ms() dispuestos a lo largo del código, son para mantener una velocidad 
        constante en la multiplexión, aún cuando los displays no están encendidos */ 
      dis=dis+1; 
      delay_ms(1); 
      if(dis==1 && speed > 99){ 
         cent = (speed / 100) > 99 ? ((speed / 100) % 100) : (speed / 100); 
         output_c(segcent[cent]); 
      } 
      else if(dis==2 && speed > 9){ 
         decs = (speed / 10) > 9 ? ((speed / 10) % 10) : (speed / 10); 
         output_c(segdecs[decs]); 
      } 
      else if(dis==3){ 
         unit = speed % 10; 
         output_c(segunit[unit]); 
      } 
      if(dis>3){dis=0;} 
 
      //Detección de fallas, si se detecta algún problema, se guarda en una posición del Array. 
      if(temper > 100){fail[0]=1;}else{fail[0]=0;} 
      if(oil < 20){fail[1]=1;}else{fail[1]=0;} 
      if(fuel < 16){fail[2]=1;}else{fail[2]=0;} 
      if(volt > 14){fail[3]=1;}else{fail[3]=0;} 
      if(volt < 11){fail[4]=1;}else{fail[4]=0;} 
      if(alt > 60){fail[5]=1;}else{fail[5]=0;} 
 
      /*Contador que genera un retrazo en el directorio para que no afecte la multiplexión del velocímetro. 
        a su vez un rastrea constantemente el directorio de fallas. Este contador solo afecta al directorio.*/ 
      if(a < 100){ 
         a=a+1; 
      } 
      else{ 
         a=0; 
         b=b+1; 
         if(b > 6){b=0;} 
      } 
      //Detecta si el motor está encendido. 
      if(input(PIN_D3)){ 
         //Falla detectada y se busca en el directorio. 
         if((fail[0] == 1 || fail[1] == 1 || fail[2] == 1 || fail[3] == 1 || fail[4] == 1 || fail[5] == 1)){ 
            if(a%30 == 0){ 
               output_toggle(PIN_B3); 
            } 
            //Encontrada alguna falla en el directorio, se vuelve a comprobar para así crear un listado, en caso de que ocurra más de un problema. 
            switch(b){ 
               case 0: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "    %.1f%CC      ",temper,0xDF); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc "HIGH TEMPERATURE"); 
                  } 
               break; 
               case 1: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "    %.1f PSI    ",oil); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc "LOW OIL PRESSURE"); 
                     output_high(PIN_D7); 
                  } 
               break; 
               case 2: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "       %.0f%C       ",fuel,0x25); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc " LOW LEVEL FUEL "); 
                     output_high(PIN_D4); 
                  } 
               break; 
               case 3: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "      %.1fV     ",volt); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc "  OVER TENSION  "); 
                  } 
               break; 
               case 4: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "      %.1fV     ",volt); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc "   OVER  LOAD   "); 
                  } 
               break; 
               case 5: 
                  if(fail[b]==1){ 
                     lcd_gotoxy(1,1); 
                     printf(lcd_putc "      %.1fV     ",volt); 
                     lcd_gotoxy(1,2); 
                     printf(lcd_putc "  Alt  Failure  "); 
                     output_high(PIN_D6); 
                  } 
               break; 
            } 
         } 
         else{ 
            //Posición de palanca de cambios 
            //Dependiendo de la posición de la palanca, habilita o deshabilita el contador de recorrido. 
            if(input(PIN_A4)){ 
               lcd_gotoxy(1,1); 
               if(shift >= 10 && shift <= 25){ 
                  printf(lcd_putc "     Reverse    "); 
                  output_high(PIN_D0); 
               } 
               else if(shift >= 26 && shift <= 36){ 
                  printf(lcd_putc "     Neutral    "); 
                  output_low(PIN_D0); 
               } 
               else if(shift >= 37 && shift <= 47){ 
                  printf(lcd_putc "      Drive     "); 
                  output_high(PIN_D0); 
               } 
               else if(shift >= 48 && shift <= 58){ 
                  printf(lcd_putc "     Lower 2    "); 
                  output_high(PIN_D0); 
               } 
               else if(shift > 60){ 
                  printf(lcd_putc "     Lower 1    "); 
                  output_high(PIN_D0); 
               } 
               else{ 
                  printf(lcd_putc "     Parking    "); 
                  output_low(PIN_D0); 
               } 
               lcd_gotoxy(1,2); 
               printf(lcd_putc "                "); 
            } 
            else{ 
               lcd_gotoxy(1,1); 
               printf(lcd_putc "%.1f  %.2f  %.0f ",temper,volt,oil); 
               lcd_gotoxy(1,2); 
               printf(lcd_putc "Temp  Volts  Oil"); 
               output_high(PIN_B3); 
               output_low(PIN_D4); 
               output_low(PIN_D7); 
               output_low(PIN_D6); 
            } 
         } 
      } 
      else{ 
         if(speed > 5 || shift > 10){ 
            lcd_gotoxy(1,1); 
            printf(lcd_putc "    Atention    "); 
            output_toggle(PIN_B3); 
         } 
         else{ 
            lcd_gotoxy(1,1); 
            printf(lcd_putc "                "); 
         } 
         lcd_gotoxy(1,2); 
         printf(lcd_putc "  Stop  Engine  "); 
         output_high(PIN_B3); 
      } 
   } 
}
La explicación de como funciona, está en los comentarios del código...

Adjunto están los códigos, la simulación en proteus, los archivos hex, una foto mía en traje de baño... :unsure::eek: Ok, no, eso no... :LOL:

Ahora algunas fotos...
Cluster1.jpg

Cluster2.jpg

Cluster3.jpg


A medida que vaya avanzando, iré subiendo más información. Saludos... :apreton:
 

Adjuntos

  • Cluster-V2.0.zip
    457.6 KB · Visitas: 32
Última edición por un moderador:

Fogonazo

"Qualified exorcist approved by the Vatican"
Al medidor de presión de aceite no le veo mucho sentido, seria mas sencillo una alarma por falta de presión.

Pero si lo deseas hacer mas completo:

Nivel de refrigerante o alarma de nivel
Nivel de líquido de frenos o alarma de nivel
Nivel de líquido lava-parabrisas o alarma de nivel.
Temperatura de aceite o alarma por sobre-temperatura.

Mas completo y mas complicado:
Nivel de aceite o alarma por falta de aceite.
Presión y temperatura de las cubiertas o alarma por falta de presión / exceso de temperatura.

:devilish:
Complicado a nivel Fogonazo:
Análisis de gases de escape, temperatura de gases y con esto corrección de la mezcla estequiométrica combustible-aire.
Censado de vibraciones del block del motor y con esto corrección de la puesta a punto del encendido para evitar "Pistoneo" (Detonaciones)
 

Ratmayor

ModeraTroll
Al medidor de presión de aceite no le veo mucho sentido, seria mas sencillo una alarma por falta de presión.

Además, ya tengo el sensor :LOL:

Pero si lo deseas hacer mas completo:

Nivel de refrigerante o alarma de nivel
Nivel de líquido de frenos o alarma de nivel
Nivel de líquido lava-parabrisas o alarma de nivel.
Temperatura de aceite o alarma por sobre-temperatura.
El de nivel de refrigerante no se me ocurre donde colocar el sensor :unsure: El de liquido de frenos, pues... Sí no frenas, creo que te darás cuenta de que no hay liquido :LOL: pero lo tenía pensado, incluso, el sensor está debajo de la bomba :unsure: El del limpia parabrisas, ya lo tiene la ratanave, por eso no lo incluí ahí :D, y el de la temperatura del aceite, no se... supongo que ha de ser más alta que la temperatura del agua... No se que sensor pueda soportar tanto... :unsure:


Mas completo y mas complicado:
Nivel de aceite o alarma por falta de aceite.
Presión y temperatura de las cubiertas o alarma por falta de presión / exceso de temperatura.
:unsure: Bueno, si no tienes aceite no tienes presión :LOL: a sí que calcular el nivel sería paranóico, además de no saber donde rayos poner el sensor o cual :LOL:
:devilish:
Complicado a nivel Fogonazo:
Análisis de gases de escape, temperatura de gases y con esto corrección de la mezcla estequiométrica combustible-aire.
Censado de vibraciones del block del motor y con esto corrección de la puesta a punto del encendido para evitar "Pistoneo" (Detonaciones)
Mirá vos... Que en ese sí estoy trabajando, pero para el TBI :devilish:
 

Fogonazo

"Qualified exorcist approved by the Vatican"
Yo tuve una fea experiencia con la medición electrónica de presión de aceite (Motor estacionario), por eso mi recomendación.

En un sistema de medición a distancia con trasmisión de datos, el medidor reventó y el aceite se salió.
No llegó a dañarse el motor porque el sistema de seguridad lo apagó a tiempo.
Pero el "Chiquero" de aceite tirado estuvo muy muy feo. :rolleyes:
 
leches fogonazo si poco mas le pides que haga un programa para llegar a la luna jeje, bromas aparte, a mi me parece que esta muy bien la idea, lo demas todo se andara, por lo menos yo lo veo asi.
 

Fogonazo

"Qualified exorcist approved by the Vatican"
leches fogonazo si poco mas le pides que haga un programa para llegar a la luna jeje, bromas aparte, a mi me parece que esta muy bien la idea, lo demas todo se andara, por lo menos yo lo veo asi.

Y eso que todavía no le sugerí hacer el sistema de mezcla Materia - AntiMateria :rolleyes:
 
en lo referente al aceite como tu dices creo que los vehiculos controlan la presion y la temperatura, yo creo que el nivel es discutible salvo cuando el vehiculo este parado, el nivel del anticongelante eso si es necesario ya que yo tube un problema que poco mas que cargo la junta de culata del motor
 

Ratmayor

ModeraTroll
Yo tuve una fea experiencia con la medición electrónica de presión de aceite (Motor estacionario), por eso mi recomendación.

En un sistema de medición a distancia con trasmisión de datos, el medidor reventó y el aceite se salió.
No llegó a dañarse el motor porque el sistema de seguridad lo apagó a tiempo.
Pero el "Chiquero" de aceite tirado estuvo muy muy feo. :rolleyes:
:eek: El sensor era de juguete? :LOL:

Yo estoy usando este sensor:
10887745_991103454237959_1081914476_n.jpg
El de la izquierda es un XMLP010BC77 (Adjunto datasheet) y el de la derecha es el sensor original del carro que solo enciende una lamparita :LOL: como ves son casi identicos y ambos roscan perfecto en el block ;)

10934758_991107037570934_1061257333_n.jpg
 

Adjuntos

  • OsiSense_XM_XMLP010BC77.pdf
    66.4 KB · Visitas: 22
Última edición:

Fogonazo

"Qualified exorcist approved by the Vatican"
El que reventó era en vida muy parecido al de la izquierda

Edit:
Aceite + Presión + Temperatura: Dan una mala combinación para los plásticos
 
Última edición:

Ratmayor

ModeraTroll
Continuando con el proyecto, esta vez traigo una versión compacta que podría servir para vehículos pequeños o motos...

circluster.png

Usa la misma controladora, pero estoy usando una técnica diferente para controlar los LEDs, apenas tenga avances y las pruebas suficientes, subo el PCB.

Saludos :apreton:
 
Tiene muy buena pinta la cosa, por cierto ¿como haces los puentes? ya que quiero hacer una placa y no me aclaro, me sale todo, mas o menos bien, pero os puentes se me atragantan, por mas que leido de como hacer los puentes no me aclaro.
 
Última edición:
como mides la temperatura del motor?, por el radiador?, me interesa tu proyecto ya que mi automóvil trae los ventiladores directos, sirve que lo uso para manipular el tiempo de encendido y apagado del ventilador.
 

Ratmayor

ModeraTroll
como mides la temperatura del motor?, por el radiador?, me interesa tu proyecto ya que mi automóvil trae los ventiladores directos, sirve que lo uso para manipular el tiempo de encendido y apagado del ventilador.
Hola luis30, estoy usando una versión de el LM35 que viene en encapsulado TO-220


Y estoy sensando la temperatura del agua, en mi carro se me hizo fácil, en la bomba de agua tiene un tapón roscado, lo que hice fue conseguir una reducción de bronce que roscara allí y empotré dentro el sensor y lo rellené con pegamento epoxico marino :devilish: y hasta el momento no ha presentado fallas... :D
 

Fogonazo

"Qualified exorcist approved by the Vatican"
como mides la temperatura del motor?, por el radiador?, me interesa tu proyecto ya que mi automóvil trae los ventiladores directos, sirve que lo uso para manipular el tiempo de encendido y apagado del ventilador.

Los ventiladores no trabajan por tiempo, sino por rango de temperatura, prenden a mas de xx° y apagan a menos de nn°


Se podría emplear una salida del micro para realizar esta función ;)
 
Última edición:

Fogonazo

"Qualified exorcist approved by the Vatican"
Si supieras que tuve la intención, pero haciendo un control para personalizar la temperatura... :unsure:

:no: la puedes personalizar porque la temperatura del motor la determina un termostato mecánico que abre el paso de agua al radiador cuando corresponde.

[Mode :devilish: On]

Si puedes personalizar la temperatura del radiador, lo cual te vendrá bien en invierno para la calefacción del habitáculo del vehículo.



:LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL: :LOL:

[/Mode :devilish: Off]
 
Última edición:
Arriba