Altitude

#include <barometric-usb.h>
#include <math.h>
//#include <ex_usb_common.h>
//#include <usb_cdc.h>
//#include <string.h>
 
//#include <stdio.h>
//#include "F:\Shemi\barometric-usb\barometric-usb_bootloader.h"
 
#define LCD_ENABLE_PIN PIN_C5
#define LCD_RS_PIN PIN_C0
#define LCD_RW_PIN PIN_B7
#define LCD_Data4 PIN_C4
#define LCD_Data5 PIN_C3
#define LCD_Data6 PIN_C6
#define LCD_Data7 PIN_C7
 
   
 
#include <lcd.c>
int16 timer0_div=0;
int16 touch_b=500,touch_b_triger=200;
float bat_volt;
float pressure_ref=102325.0;////calculate altitude 102325.0 must be 101325.0 but where i live give me negative altitude
 
short set_flag=0;
 int oss=0; //oversampling 0-low current 1-standart, 2,3- precision  
 signed int32 UT ;
 unsigned int32 UP;
 signed int16 AC1,AC2,AC3;
 unsigned int16 AC4,AC5,AC6;
 signed int16 B1,B2,MB,MC,MD;
 signed int32 X1,X2,B5,temperature,B6,X3,B3;
 signed int32 pressure;
 signed int32 pressure_log[128];
 int pressure_index=0;
 unsigned int32 B4,B7;
 float altitude;
 
 signed int16 bmp085_read(int reg_address);
 void bmp085_write_control(int data);
 
#int_TIMER0  //execute evry 12,5ms
void  TIMER0_isr(void) 
{timer0_div++;
if (timer0_div==48000){//execute evry 12,5ms * timer0_div(48000) = 10min
   timer0_div=0;
   pressure_log[pressure_index]=pressure;
   pressure_index++;
   if(pressure_index==128)pressure_index=0;
}
 
 
}
 
#int_TIMER1
void  TIMER1_isr(void) 
{
 
}
 
#int_TIMER2
void  TIMER2_isr(void) 
{
 
}
 
#int_TIMER3
void  TIMER3_isr(void) 
{
 
}
 
#int_USB
void  USB_isr(void) 
{
 
}
 
//BOOTLOADER AT START - Include Bootloader.h in your application - See sample application Ex_Bootload.c
//BOOTLOADER AT END - Always include the projectname_bootloader.h file in future versions of the project
 
// NOTE - User must include PROJECTNAME_bootloader.C in his final Application program
 
//void application(void) {
 // while(TRUE);
//}
void main()
{// Enter Bootloader if Pin B5 is low after a RESET
  // if(!input(PIN_B5))
  // {
    //  real_load_program();
   //}
 
  //    application();
  lcd_init();
  
 
 
  
  setup_vref(VREF_2v048);
   setup_adc_ports(sAN6|sAN11|VSS_FVR );//|VSS_FVR defined in 18f14k50.h by Martin Nikiforov
   setup_adc(ADC_CLOCK_DIV_4|ADC_TAD_MUL_12);
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);      //12.5 s overflow
  /// setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //349 ms overflow
 //  setup_timer_2(T2_DIV_BY_16,255,16);      //2.7 ms overflow, 43.6 ms interrupt
  // setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);      //43.6 ms overflow
   setup_timer_2(T2_DIV_BY_16,255,1);      //2.7 ms overflow, 2.7 ms interrupt
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
   
    enable_interrupts(INT_TIMER0);
//   enable_interrupts(INT_TIMER1);
 //  enable_interrupts(INT_TIMER2);
 //  enable_interrupts(INT_TIMER3);
//   enable_interrupts(INT_USB);
   enable_interrupts(GLOBAL);
   
  printf(lcd_putc"\fDesigned by\nMartin Nikiforov");
  delay_ms(2000);
  //Example blinking LED program
  
 
   AC1=bmp085_read(0xAA);   // read parameters from bmp085's eeprom
   AC2=bmp085_read(0xAC);
   AC3=bmp085_read(0xAE);
   
   AC4=bmp085_read(0xB0);
   AC5=bmp085_read(0xB2);
   AC6=bmp085_read(0xB4);
   
   B1=bmp085_read(0xB6);
   B2=bmp085_read(0xB8);
   MB=bmp085_read(0xBA);
   MC=bmp085_read(0xBC);
   MD=bmp085_read(0xBE);
 oss=3;//0-low current for more accuracy 1,2,3
 
 
  while(true)
   {
       
       set_adc_channel(11);
       delay_ms(1);
         touch_b=read_adc()/4;
     
       set_adc_channel(6);
       delay_ms(1);
       bat_volt=4.096*read_adc()/1023.0;
         
         if(touch_b<touch_b_triger){
           
           printf(lcd_putc,"\f%1.2gV %u %Ldmin\n%Ld       %4.1g",
           bat_volt,(pressure_index-(200-(unsigned int)touch_b*2))/2,(200-touch_b)*10,touch_b,(float)pressure_log[pressure_index-((200-(unsigned int)touch_b*2)/2)]/100.0);
           
           if(touch_b<80 && set_flag==0) {
              pressure_ref=pressure;
              printf(lcd_putc," Reset");
           }
           if(touch_b<70) {
                pressure_ref=102325.0;
                printf(lcd_putc," SET");
                set_flag=1;//not allowing when touch_b go obove 70 to reset pressure_ref
           }
         }
         else set_flag=0;
         
     
     bmp085_write_control(0x2E);  //0x2E set to measure temperature   4,5ms
   delay_ms(5);
   UT=(unsigned int16)bmp085_read(0xF6); //read 0xF6 register temperature                             
      
   bmp085_write_control(0x34+(0x40*oss));  //0x34 - oss=0 set to measure pressure   4,5ms conv
                                           //oss=1 the value must be 0x74 oss =2 0xb4 , oss=3 0xF4
   delay_ms(7*(oss+1));
   
   UP=(unsigned int16)bmp085_read(0xF6);//pressure
   UP<<=8;
   UP=(UP+(((unsigned int16)bmp085_read(0xF8))>>8))>>(8-oss);//XLSB extra precision byte
   
   X1=((UT-AC6)*AC5)>>15;
   X2=(((signed int32)MC)<<11)/(X1+MD);
   B5=X1+X2;
   temperature=(B5+8)>>4;            
   
   B6=B5-4000;
   X1=(((signed int32)B2)*((B6*B6)/4096))/2048;
   X2=(((signed int32)AC2)*B6)/2048;
   X3=X1+X2;
   B3=((((((signed int32)AC1)*4)+X3)*((int)pow(2,oss)))+2)/4;
   X1=(((signed int32)AC3)*B6)/8192;
   X2=(((signed int32)B1)*((B6*B6)/4096))/65536;
   X3=((X1+X2)+2)/4;
   B4=(((unsigned int32)AC4)*(unsigned int32)(X3+32768))>>15;
   B7=(unsigned int32)(((unsigned int32)UP)-B3)*(50000>>oss);
   if(B7<0x80000000){pressure=(B7<<1)/B4;}
   else {pressure=(B7/B4)*2;}
   X1=(pressure>>8)*(pressure>>8);
   X1=(((unsigned int32)X1)*3038)/65536;                                         
   X2=(-7357*pressure)/65536;
   pressure=pressure+(X1+X2+3791)/16;
      
   altitude=  44330.0*(1.0-pow((pressure/pressure_ref),(1/5.255)));
   //calculate altitude pressure_ref=102325.0 must be 101325.0 but where i live give me negative altitude
   
   if (touch_b> touch_b_triger)                      
    printf(lcd_putc,"\aT=%4.1gC P=%5.1g\nAltitude%6.1g m\n",temperature/10.0,pressure/100.0,altitude);
     // screen refresh slowly when using \f
   
  delay_ms(200);
   }
  
 
 
}
 
signed int16 bmp085_read(int reg_address)
{
   int msb,lsb;
   int16 data=0;
   i2c_start();
   i2c_write(0b11101110);    // Device address
   i2c_write(reg_address);  // Data to device 
   i2c_start();            // Restart 
   i2c_write(0b11101111);     // to change data direction
   msb=i2c_read(1);        // Now read from slave 
   lsb=i2c_read(0);
   i2c_stop();
   data=msb;
   data<<=8;
   data=data|lsb;
   return (data);
}
void bmp085_write_control(int data)
{
 
   i2c_start();
   i2c_write(0b11101110);//     // Device address
   i2c_write(0xF4);  //control reg address 
   i2c_write(data);   //write the data                 
   i2c_stop();
   
}
English

categories:

Add new comment

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.