
#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();
}
Add new comment