Autor Tema: Necesito ayuda con soft de medidor de presion digital  (Leído 5641 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado quirogaareal

  • PIC16
  • ***
  • Mensajes: 180
Re: Necesito ayuda con soft de medidor de presion digital
« Respuesta #15 en: 05 de Septiembre de 2006, 08:07:35 »
Hola Maunix:

Mira ya notengo problemas con el sleep, lo resolvi con un contador degresivo y con interrupciones externas tal cual vos me lo habias sugerido en su momento.

El codigo que va hasta ahora  ...hasta que esta empresa se decida cual put.....sensor quiere es este.




//Tarea para el sabado :

//comprar baterias , lm1458, ver lo de low batery y hacer una condicion de salto cuando haya presion. o probar con mi modo de pregramacion.
//cortar las pistas y alimentar el operacional con 9V . la programcion con los pulsadores deep switch.






////////////////////////////////////////////////////////////////////////////////////
//
// 1/09/06 - Medidor de presion!!! - p+ y p- y ademas posee tabla de conversion.
//
// Programa: Manejo del dispositivo PCF8591 en modo A/D
// Version: 0.0
//
// Dispositivo: PIC 16F628 Compilador: CCS vs3.245
// Entorno IDE: MPLAB IDE v7.31 Simulador: Proteus 6.7sp3
//
// Software con Modificaciones
// METER OTRO SENSOR PARA HACER PRESION DIFERENCIAL O CONSEGUIR UN SENSOR QUE HAGA AMBAS
//////////////////////////////////////////////////////////////////////////////////

/******************************************************/
/********** Programa Medidor de Presion  con 16f628 ***/
/******************************************************/

#include <16f876.h> //pic a utilizar
#device *=16
#device adc=8
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT,NOCPD, NOWRT,NODEBUG                  //No Debug mode for ICD
#use delay (clock=4000000) //Fosc=4Mhz
#define use_portc_lcd TRUE
#include <flex_lcd1.c> //libreria para lcd

//////////////////////////////////////////////////
//Posiciones de memorias en eeprom del pic usadas
//0x00 Lectura A0 del adc negativo
//0x01 Lectura A1 del adc positivo
//0x02 Kp
//0x03 Kn
//0x04 Pob
//0x05 copia dir 0x01
//0x06 PobN
//0x07 copiaN dir 0x00
//0x08 unidad de presion
//0x09 formato
//0x10 Bateria positiva
//0x11 Bateria negativa
////////////////////////////////////////

/********DECLARACION DE FUNCIONES************/

void calibracionP(void);
void calibracionN(void);
void cartel(int Pob);
void cartelN(int PobN);
void presiones(void);
void CartelU (int unidad);
void bateria(void);
/********************************************/
//Pob: presion observada positiva
//PobN: presion observada negativa
//copia: copia un valor parano modificar el original positivo
//copia: copia un valor parano modificar el original negativo
//unidad:????
//valor:usado para almacenar valores de una operacion positiva
//valorN:usado para almacenar valores de una operacion negativa
//Kp:constante de multiplicacion para visualizacion de la presion positiva
//Kn:constante de multiplicacion para visualizacion de la presion negativa
//Ku:constante de multiplicacion para visualizacion
//de conversion de la presion (PSI , mmHg, Bar)
/********************************************/
///////////PROGRAMA/////////////////////

///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion( )
{
int dato;
set_adc_channel(0);
delay_ms(10);
dato=read_adc();
write_eeprom(0x00,dato);//0x00 Lectura A0 del adc presion negativa

set_adc_channel(1);
delay_ms(10);
dato=read_adc();
write_eeprom(0x01,dato);//0x01 Lectura A1 del adc presion positiva

set_adc_channel(3);
delay_ms(10);
dato=read_adc();
write_eeprom(0x10,dato);//0x10 Lectura A3 del adc bateria positiva

set_adc_channel(4);
delay_ms(10);
dato=read_adc();
write_eeprom(0x11,dato);//0x11 Lectura A4 del adc bateria negativa

set_timer0(0 ); //carga TMR0
}


void main(void)
{
int Pob,copia,PobN,copiaN,unidad,formato,dato;
long int sleepp=1000;
float valor,valorN,kp=1,kn=1,Ku=1;

lcd_init( ); //inicializamos lcd
lcd_putc("  Medidor de \n  Presion...");
delay_ms(1000);
lcd_putc("\f");

setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);



enable_interrupts(INT_TIMER0); //interrupcion TIMER0 activada
setup_counters(RTCC_INTERNAL,RTCC_DIV_256); //configuracion interrupcion TMR0
set_timer0(0 ); //carga TMR0 -> temporizacion maxima aprox 65.5ms
enable_interrupts(GLOBAL); //activar interrupciones


bateria();

lcd_putc("\f");

while(TRUE)
{

if (!input(PIN_B1))
{
calibracionP();//llama a la funcion calibracion positiva
}
if (!input(PIN_B2))
{
calibracionN();//llama a la funcion calibracion negativa
}
if (!input(PIN_B3))
{
presiones(); //funcion que selecciona unidad de Presion (PSI , mmHg, Bar)
}


unidad=read_eeprom(0x08);//inicializo posicion de eeprom dir0x08 => 0x08=1=bar
formato=read_eeprom(0x09);

/****** Tabla de Comversion **************/
/****** Valores Comversion para otras unidades de presion **************/
/****** por defecto Ku es 1 estaria en Bares **************/

         switch (unidad){
               case 1: Ku=1;        //Presion en Bar
                       break;
               case 2: Ku=750.2467; //Presion en mmHg
                       break;
               case 3: ku=14.5;     //Presion en Psi
                       break;
               default:break;
                        }

/****** Fin de tabla **************/

PobN=read_eeprom(0x06);//calibracion negativa
copiaN=read_eeprom(0x07);//calibracion negativa//copiaN son los escalones del ADC

kn=(float)PobN/copiaN;

dato=read_eeprom(0x00);

valorN=dato*kn*ku*0.01; //Calculo el valor de Presion -

Pob=read_eeprom(0x04);
copia=read_eeprom(0x05);

kp=(float)Pob/copia;

dato=read_eeprom(0x01);

valor=dato*kp*ku*0.01; //Calculo el valor de Presion +

if (formato==2){
/*******************************************/
lcd_gotoxy(1,1);
printf(lcd_putc,"P-:-%1.2f ",valorN); //muestra por lcd
cartelU(unidad);
//delay_ms(500);

lcd_gotoxy(1,2);
printf(lcd_putc,"P+: %1.2f ",valor); //muestra por lcd
cartelU(unidad);
//delay_ms(500);
/*******************************************/
}else
{
lcd_gotoxy(1,1);
printf(lcd_putc,"MANOVACUOMETRO!",valorN); //muestra por lcd
//delay_ms(500);

lcd_gotoxy(1,2);
printf(lcd_putc,"P: %1.2f ",(valor-valorN)); //muestra por lcd
cartelU(unidad);
//delay_ms(500);
}


/******************REVISAR  SI SOLO USAMOS EL RESET PARA VOLVER A ENCENDER EL APARATO************/



sleepp--;
if(sleepp==0)
         {
         lcd_putc("\f");
         sleepp=1000;
         sleep();
         }


}//bucle infinito

}




/****** Funcion  calibracion positiva**************/


void calibracionP(void)
{
int Pob=0,copia=0,Pobinicial=0;

if(!input(PIN_B1)) //pin A2=0 --> calibracion si lo tenes apretado al pin A2
   {

      lcd_putc("\f");//borra pantalla
      lcd_putc("Cal+ A5=up A4=Down");
      Pob=read_eeprom(0x04); //almaceno en memoria el numerador del calculo de Kp
      Pobinicial=Pob;
      cartel(Pob);// llama a la funcion de impresion en lcd realizando una
      //division por 100 ya que POb es un valor entero
      delay_ms(1000);

      while(!input(PIN_B1))
      {
      if(!input(PIN_B3)) //para ello leemos el estado del pin A3 del porta para conteo ascendente
         {
         do
         {
         Pob++; //decremento contador para visualizar siguiente digito
         delay_ms(100);
         cartel(Pob);//imprime para ver que avanza la calibracion
         delay_ms(100);
         }while(!input(PIN_B3));//antirrebote
         }

      if(!input(PIN_B2)) //para ello leemos el estado del pin A3 del porta para conteo descendente
         {
         do
         {
         Pob--; //decremento contador para visualizar siguiente digito
         delay_ms(100);
         cartel(Pob);
         delay_ms(100);
         }while(!input(PIN_B2));
  }
}
}
/***********esto sirve para que efectivamenete se cargue*************/
/**********el valor calibrado y no el valor original***************/
if (Pobinicial!=Pob)
{//condicion para que cuando salga de calibracion no
//modifique el valor de presion calibrada , si no se varia el valor Pob inicial
write_eeprom(0x04,Pob);
copia=read_eeprom(0x01);//0x01 Lectura A1 del adc presion positivo valor de 0 a 255 del ADC
//copia son los escalones del ADC
write_eeprom(0x05,copia);//0x05copia para no modificar el valor original de lectura del ADC
}
lcd_putc("\f");
}




/****** Funcion  calibracion negativa**************/
void calibracionN(void)
{
int PobN=0,copiaN=0,Pobinicial=0;

if(!input(PIN_B2)) //pin A2=0 --> calibracion
   {
      lcd_putc("\f");
      lcd_putc("Cal- A5=up A2=Down");
      PobN=read_eeprom(0x06);//almaceno en memoria el numerador del calculo de Kn
      Pobinicial=PobN;
      cartelN(PobN);
      delay_ms(1000);

      while(!input(PIN_B2))
      {
      if(!input(PIN_B3)) //para ello leemos el estado del pin A3 del porta para conteo ascendente
         {
         do
         {
         PobN++;
         delay_ms(100);
         cartelN(PobN);
         delay_ms(100);
         }while(!input(PIN_B3));
         }

      if(!input(PIN_B1))
         {
         do
         {
         PobN--; //decremento contador para visualizar siguiente digito
         delay_ms(100);
         cartelN(PobN);
         delay_ms(100);
         }while(!input(PIN_B1));
  }
}
}

/***********esto sirve para que efectivamenete se cargue*************/
/**********el valor calibrado y no el valor original***************/

if (Pobinicial!=PobN){//condicion para que cuando salga de calibracion no
//modifique el valor de presion calibrada , si no se varia el valor PobN inicial
write_eeprom(0x06,PobN);//0x06 Lectura A1 del adc presion negativo valor de 0 a 255 del ADC
copiaN=read_eeprom(0x00);
write_eeprom(0x07,copiaN);//0x07copia para no modificar el valor original de lectura del ADC
}
lcd_putc("\f");
}



/****** Funcion  carteles de impresion LCD**************/

void cartel(int Pob)
{
lcd_gotoxy(2,2);
printf(lcd_putc,"P+=%1.2f bar",((float)Pob/100)); //La div por 100 es para que muestre en Bar
}

void cartelN(int PobN)
{
lcd_gotoxy(2,2);
printf(lcd_putc,"P-=%1.2f bar",((float)PobN/100)); //La div por 100 es para que muestre en Bar

}




/**************** Funcion  presion (PSI mmHg o Bar) + presentacion  INDIVIDUAL*******************/

void presiones(void)
{
int unidad=1,formato=1;
if(!input(PIN_B3))
   {
      lcd_putc("\f");
      lcd_putc("Unidad de P:");
      unidad=read_eeprom(0x08);
      lcd_gotoxy(2,2);
      cartelU(unidad);

      while(!input(PIN_B3))
      {
      if(!input(PIN_B1))//pin A3 apretado + pin A2 como pulsdor cambio a Bar a mmHg o PSI
         {
         do
         {
          unidad++;
          if (unidad>3) unidad=1;//reset para no exeder la condicion
          lcd_gotoxy(2,2);
          cartelU(unidad);
          delay_ms(1000);
         }while(!input(PIN_B1));
        }

       if(!input(PIN_B2))//pin A3 apretado + pin A4 como pulsdor cambio a formatos de presentacion presion +,- o diferencial

         {
         do
         {
          lcd_gotoxy(2,2);
          if (formato==1)
          {
          lcd_putc("Formato P+ P-");
          formato=2;
          }else
          {
          lcd_putc("Formato PSUMA");
          formato=1;
          }
          delay_ms(1000);
         }while(!input(PIN_B2));
        }
}
write_eeprom(0x08,unidad);
write_eeprom(0x09,formato);
lcd_putc("\f");
}
}


/****** Funcion  carteles de impresion LCD**************/

void CartelU (int unidad)

{
         switch (unidad){
         case 1:
         lcd_putc("Bar     ");// aca se imprimen espacios vacion por una cuetion de refresco del diplay para que no
         //queden impresas letras de mas cuando se corra una presentacion en el display.
         break;
         case 2:
         lcd_putc("mmHg    ");
         break;
         case 3:
         lcd_putc("psi     ");
         break;
         default:
         break;
         }
}



void bateria(void)
{
int bat;
lcd_gotoxy(1,1);
lcd_putc("BATERIA...");
lcd_gotoxy(6,2);
bat=read_eeprom(0x10);
lcd_gotoxy(1,2);
if(bat<180)
{
printf(lcd_putc,"Low Bat %d",bat);
}
else
{
printf(lcd_putc,"%3.1f %% %u",(float)(bat*0.4),bat);
}

delay_ms(1500);
}





LA LIBRERIA MODIFICADA PARA EL LCD  EN EL PUERTO C.




// flex_lcd.c

// These pins are for the Microchip PicDem2-Plus board,
// which is what I used to test the driver.  Change these
// pins to fit your own board.

#define LCD_DB4   PIN_C4
#define LCD_DB5   PIN_C5
#define LCD_DB6   PIN_C6
#define LCD_DB7   PIN_C7

#define LCD_E     PIN_C0
#define LCD_RS    PIN_C1
#define LCD_RW    PIN_C2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1

//========================================

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line


int8 const LCD_INIT_STRING[4] =
{
 0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xc,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 };


//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).
 output_bit(LCD_DB4, !!(nibble & 1));
 output_bit(LCD_DB5, !!(nibble & 2));
 output_bit(LCD_DB6, !!(nibble & 4));
 output_bit(LCD_DB7, !!(nibble & 8));

 delay_cycles(1);
 output_high(LCD_E);
 delay_us(2);
 output_low(LCD_E);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine.  For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.

#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3

retval = 0;

output_high(LCD_E);
delay_cycles(1);

retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);

output_low(LCD_E);

return(retval);
}
#endif

//---------------------------------------
// Read a byte from the LCD and return it.

#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;

output_high(LCD_RW);
delay_cycles(1);

high = lcd_read_nibble();

low = lcd_read_nibble();

return( (high<<4) | low);
}
#endif

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);

#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif

if(address)
   output_high(LCD_RS);
else
   output_low(LCD_RS);

 delay_cycles(1);

#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif

output_low(LCD_E);

lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

//----------------------------
void lcd_init(void)
{
int8 i;

output_low(LCD_RS);

#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif

output_low(LCD_E);

delay_ms(15);

for(i=0 ;i < 3; i++)
   {
    lcd_send_nibble(0x03);
    delay_ms(5);
   }

lcd_send_nibble(0x02);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING);

    // If the R/W signal is not used, then
    // the busy bit can't be polled.  One of
    // the init commands takes longer than
    // the hard-coded delay of 60 us, so in
    // that case, lets just do a 5 ms delay
    // after all four of them.
    #ifndef USE_LCD_RW
    delay_ms(5);
    #endif
   }

}

//----------------------------

void lcd_gotoxy(int8 x, int8 y)
{
int8 address;

if(y != 1)
   address = lcd_line_two;
else
   address=0;

address += x-1;
lcd_send_byte(0, 0x80 | address);
}

//-----------------------------
void lcd_putc(char c)
{
 switch(c)
   {
    case '\f':
      lcd_send_byte(0,1);
      delay_ms(2);
      break;

    case '\n':
       lcd_gotoxy(1,2);
       break;

    case '\b':
       lcd_send_byte(0,0x10);
       break;

    default:
       lcd_send_byte(1,c);
       break;
   }
}

//------------------------------
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;

lcd_gotoxy(x,y);

// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));

output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);

return(value);
}
#endif


Saludos desde Cordoba
Recuerda : Si una mujer te ama de verdad no te pedira ni Matrimonio, Ni concubinato , Ni hijos, No te mentira , ni buscara que cambies de opinion con respecto a las tres primeras opciones.

Saludos

desde Cordoba Argentina


 

anything