| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| Gabriel 
 
 
 Joined: 03 Aug 2009
 Posts: 1074
 Location: Panama
 
 
			    
 
 | 
			
				| int64 with PIC18F87J50 |  
				|  Posted: Wed Jun 28, 2017 12:52 pm |   |  
				| 
 |  
				| Hi all, 
 I tried declaring an int64 and seems the compiler does not recognize it.
 how can i get around this?
 
 can i not do 64bit math with 18F?
 
 thanks.
 
 G.
 _________________
 CCS PCM 5.078 & CCS PCH 5.093
 |  |  
		|  |  
		| ezflyr 
 
 
 Joined: 25 Oct 2010
 Posts: 1019
 Location: Tewksbury, MA
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Jun 28, 2017 1:14 pm |   |  
				| 
 |  
				| Hi Gabriel, 
 The CCS manual for the PCB, PCM, and PCH compilers shows 'int32' as the largest value under the Data Definitions - Type Specifiers topic.
 
 Just out of curiosity, why do you *need* an int64 variable?
 _________________
 John
 
 If it's worth doing, it's worth doing in real hardware!
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Jun 29, 2017 12:35 am |   |  
				| 
 |  
				| CCS in the PIC12/16/18 chips is close to implementing ANSI C90. However int64 was only added to ANSI C around C99. Now generally it is only needed for things like large number shifts, which CCS can already do with it's multi-byte shift function. Outside this there is very little that ever needs an int64, and the sheer size of the library makes it impractical on most of the smaller PIC's. On the larger PIC24/30/33 chips, support for int64 has been added. There are a number of published libraries to add int64 to compilers that are only C89/90 compliant, and one of these could be compiled in CCS. However except for very basic functions (+/- etc.), be prepared for just how bulky the functions will be.
 |  |  
		|  |  
		| Gabriel 
 
 
 Joined: 03 Aug 2009
 Posts: 1074
 Location: Panama
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Thu Jun 29, 2017 6:27 am |   |  
				| 
 |  
				| I was developing a driver for the BME280 chip and the conversion formulas as per the datasheet called for int64 math..... 
 I later found the datasheet included a 32 bit equivalent formula as well, so this post is Null now.
 
 This is by far the most complicated sensor I've ever used... not hard just "un-natural".
 _________________
 CCS PCM 5.078 & CCS PCH 5.093
 |  |  
		|  |  
		| ntrungtruc2003 
 
 
 Joined: 16 Feb 2011
 Posts: 42
 
 
 
			    
 
 | 
			
				| Need help BME280 driver |  
				|  Posted: Sun Jul 23, 2017 10:28 pm |   |  
				| 
 |  
				| Dear Sir, 
 Could you please share BME280 driver for PIC18F
 Thanks you very so much if you can help
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Mon Jul 24, 2017 5:01 am |   |  
				| 
 |  
				| You should have a look at what 'others' have done. I was curuous to see what the sensor does and found a link to Sparkfun. While they use the Arduino, it isn't that hard to cross-convert into CCS C. It might be a good starting point to build from.
 
 Jay
 |  |  
		|  |  
		| ntrungtruc2003 
 
 
 Joined: 16 Feb 2011
 Posts: 42
 
 
 
			    
 
 | 
			
				| BME280 sensor |  
				|  Posted: Tue Jul 25, 2017 2:01 am |   |  
				| 
 |  
				|  	  | Code: |  	  | //************************************************ //  BME280 Barometric Pressure Sensor
 //
 //  - Datasheet:  https://cdn-shop.adafruit.com/datasheets/BST-BME280_DS001-10.pdf
 //
 //  - Written in CCS PCH C using floating point math
 //  - Several integer math versions of this driver exist but the speed improvement is
 //    not warranted in typical weather station type applications
 //
 //  - Based on a paper posted to thebackshed.com by
 //    https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/wiring-and-test
 //
 //
 //    Revision - integer algotihm
 //
 //    07/24/2017
 //
 //  Nguyen Trung Truc
 //
 //************************************************
 // place a #use i2c statement in the main program and comment this out if not applicable
 #define BME280_SDA  PIN_C4
 #define BME280_SCL  PIN_C3
 #use i2c(master, sda=BME280_SDA, scl=BME280_SCL)
 
 #include <math.h>
 #define BME280_ADDRESS 0x77          // I2C address of BME280 VDD
 //calibration values of BME280
 
 static unsigned int16 dig_T1;
 static int16  dig_T2;
 static int16  dig_T3;
 static unsigned int16  dig_P1;
 static int16  dig_P2;
 static int16  dig_P3;
 static int16  dig_P4;
 static int16  dig_P5;
 static int16  dig_P6;
 static int16  dig_P7;
 static int16  dig_P8;
 static int16  dig_P9;
 
 static unsigned int8  dig_H1;
 static int16  dig_H2;
 static unsigned int8  dig_H3;
 static int16  dig_H4;
 static int16  dig_H5;
 static int8   dig_H6;
 static int32 t_fine;
 
 int8 BME280ReadByte(int8 address);
 int16 BME280ReadInt(int8 address) ;
 int32 BME280Read24(int8 data);
 void BME280WriteByte(int8 address, int8 data) ;
 int1 BME280ReadingCalibration(void);
 void BME280Calibration();
 void BME280SetSampling();
 
 int1 BME280Begin(unsigned int8  addr)
 {
 
 // check if sensor, i.e. the chip ID is correct
 if(BME280ReadByte(0xD0) != 0x60)
 return false;
 // reset the device using soft-reset
 // this makes sure the IIR is off, etc.
 BME280WriteByte(0xE0, 0xB6);
 
 // wait for chip to wake up.
 delay_us(300);
 
 // if chip is still reading calibration, delay
 while ( BME280ReadingCalibration())
 delay_us(100);
 
 BME280Calibration(); // read trimming parameters, see DS 4.2.2
 
 BME280SetSampling(); // use defaults
 
 return true;
 }
 
 void BME280SetSampling()
 {
 
 BME280WriteByte(0xF2,0x03);
 BME280WriteByte(0xF5,0x6C);
 BME280WriteByte(0xF4,0x6E);
 // you must make sure to also set REGISTER_CONTROL after setting the
 // CONTROLHUMID register, otherwise the values won't be applied (see DS 5.4.3)
 // write8(BME280_REGISTER_CONTROLHUMID, _humReg.get());
 // write8(BME280_REGISTER_CONFIG, _configReg.get());
 // write8(BME280_REGISTER_CONTROL, _measReg.get());
 }
 
 //----------------------------------------------
 int8 BME280ReadByte(int8 address)
 //----------------------------------------------
 {
 int8 data;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01 );
 data=i2c_read(0);
 i2c_stop();
 return(data);
 }
 
 
 
 //----------------------------------------------
 int16 BME280ReadInt(int8 address)
 //----------------------------------------------
 {
 int8 msb, lsb;
 int16 temp;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01 );
 msb = i2c_read();
 lsb = i2c_read(0);
 i2c_stop();
 temp = make16(msb, lsb);
 return ( temp );
 }
 
 
 //----------------------------------------------
 void BME280WriteByte(int8 address, int8 data)
 //----------------------------------------------
 {
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_write(data);
 i2c_stop();
 }
 
 void BME280Calibration()
 //----------------------------------------------
 {
 dig_T1 = BME280ReadInt(0x88);
 dig_T2 = BME280ReadInt(0x8A);
 dig_T3 = BME280ReadInt(0x8C);
 dig_P1 = BME280ReadInt(0x8E);
 dig_P2 = BME280ReadInt(0x90);
 dig_P3 = BME280ReadInt(0x92);
 dig_P4 = BME280ReadInt(0x94);
 dig_P5 = BME280ReadInt(0x96);
 dig_P6 = BME280ReadInt(0x98);
 dig_P7 = BME280ReadInt(0x9A);
 dig_P8 = BME280ReadInt(0x9C);
 dig_P9 = BME280ReadInt(0x9E);
 dig_H1 = BME280ReadInt(0xA1);
 dig_H2 = BME280ReadInt(0xE1);
 dig_H3 = BME280ReadInt(0xE3);
 dig_H4 = BME280ReadInt(0xE4)<<4;
 dig_H5 = BME280ReadInt(0xE5)>>4;
 dig_H6 = BME280ReadInt(0xE7);
 }
 
 //----------------------------------------------
 // Read the uncompensated temperature value
 //----------------------------------------------
 
 int32 BME280Read24(int8 data)
 {
 unsigned int32 value;
 int8 msb, lsb, xlsb;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(data);
 
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01);
 
 // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 
 msb = i2c_read();
 lsb = i2c_read();
 xlsb = i2c_read(0); // NACK on last read
 i2c_stop(); //*/
 
 value = make32(0,msb,lsb,xlsb);
 
 return value;
 }
 
 int1 BME280ReadingCalibration(void)
 {
 // unsigned int8 const rStatus = BME280ReadByte(0xF3);
 int8 rStatus = BME280ReadByte(0xF3);
 return (rStatus & (1 << 0)) != 0;
 }
 
 float BME280ReadTemperature(void)
 {
 int32 var1, var2;
 
 int32 adc_T = BME280Read24(0xFA); //FA THE TEMPERATURE REGISTER
 if (adc_T == 0x800000) // value in case temp measurement was disabled
 return 0;
 adc_T >>= 4;
 
 var1 = ((((adc_T>>3) - ((int32)dig_T1 <<1))) *
 ((int32)dig_T2)) >> 11;
 
 var2 = (((((adc_T>>4) - ((int32)dig_T1)) *
 ((adc_T>>4) - ((int32)dig_T1))) >> 12) *
 ((int32)dig_T3)) >> 14;
 
 t_fine = var1 + var2;
 
 float T = (t_fine * 5 + 128) >> 8;
 return T/100;
 }
 
 
 float BME280ReadPressure(void) {
 int32 var1, var2, p;
 
 // readTemperature(); // must be done first to get t_fine
 
 int32 adc_P = BME280Read24(0XF7);
 if (adc_P == 0x800000) // value in case pressure measurement was disabled
 return 0;
 adc_P >>= 4;
 
 var1 = ((int32)t_fine) - 128000;
 var2 = var1 * var1 * (int32)dig_P6;
 var2 = var2 + ((var1*(int32)dig_P5)<<17);
 var2 = var2 + (((int32)dig_P4)<<35);
 var1 = ((var1 * var1 * (int32)dig_P3)>>8) +
 ((var1 * (int32)dig_P2)<<12);
 var1 = (((((int32)1)<<47)+var1))*((int32)dig_P1)>>33;
 
 if (var1 == 0) {
 return 0; // avoid exception caused by division by zero
 }
 p = 1048576 - adc_P;
 p = (((p<<31) - var2)*3125) / var1;
 var1 = (((int32)dig_P9) * (p>>13) * (p>>13)) >> 25;
 var2 = (((int32)dig_P8) * p) >> 19;
 
 p = ((p + var1 + var2) >> 8) + (((int32)dig_P7)<<4);
 return (float)p/256;
 }
 
 float BME280ReadHumidity(void) {
 //readTemperature(); // must be done first to get t_fine
 
 int32 adc_H = BME280ReadInt(0xFD);// BME280_REGISTER_HUMIDDATA
 if (adc_H == 0x8000) // value in case humidity measurement was disabled
 return 0;
 
 int32  v_x1_u32r;
 
 v_x1_u32r = (t_fine - ((int32)76800));
 
 v_x1_u32r = (((((adc_H << 14) - (((int32)dig_H4) << 20) -
 (((int32)dig_H5) * v_x1_u32r)) + ((int32)16384)) >> 15) *
 (((((((v_x1_u32r * ((int32)dig_H6)) >> 10) *
 (((v_x1_u32r * ((int32)dig_H3)) >> 11) + ((int32)32768))) >> 10) +
 ((int32)2097152)) * ((int32)dig_H2) + 8192) >> 14));
 
 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
 ((int32)dig_H1)) >> 4));
 
 v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
 v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
 float h = (v_x1_u32r>>12);
 return  h / 1024.0;
 }
 
 // Read the uncompensated pressure value
 //----------------------------------------------
 
 | 
 
 This code converted from aduino, in float BME280ReadPressure(void), all of  variable using int64, but ccs can not support int64 therefore i used int32 for this function.
 
 I'm not sure that int32 is correct for this function, anybody have experiments with BME280 I2C ?
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Jul 25, 2017 1:16 pm |   |  
				| 
 |  
				| Look at section 8.2 in the datasheet. This gives a listing for the code required, using int32 arithmetic. It is this that the poster above used.
 |  |  
		|  |  
		| ntrungtruc2003 
 
 
 Joined: 16 Feb 2011
 Posts: 42
 
 
 
			    
 
 | 
			
				| BME280 problem with calculate temperature |  
				|  Posted: Tue Aug 01, 2017 6:02 am |   |  
				| 
 |  
				| Dear Sir 
 1.) I use PIC16F887 I2c FORCE_SW connect to BME280
 sda = PIN_D0
 scl  = PIN_D1
 
 2.) I had successfully read and write the BME280's register,
 The problem is the temperature after calculated is not true ( it equal about 357.8 degree), I have aslo used "burst read" but the result is the same.
 
 The  trimming parameter readout for calculate temperature is in the following
 dig_T1 = 64366
 dig_T2 = 14952
 dig_T3 = 12800
 adc_T  is bout ( 557243 - 56xxxx)
 3.) setup indoor navigation mode
 
 
 Could you please help me an advice. Thanks you so much
 
 BME280.C
 
 
  	  | Code: |  	  | //************************************************
 //  BME280 Barometric Pressure Sensor
 //
 //  - Datasheet:  https://cdn-shop.adafruit.com/datasheets/BST-BME280_DS001-10.pdf
 //
 //  - Written in CCS PCH C using floating point math
 //  - Several integer math versions of this driver exist but the speed improvement is
 //    not warranted in typical weather station type applications
 //
 //  - Based on a paper posted to thebackshed.com by
 //    https://learn.adafruit.com/adafruit-bme280-humidity-barometric-pressure-temperature-sensor-breakout/wiring-and-test
 //
 //
 //    Revision - integer algotihm
 //
 //    07/24/2017
 //
 //  Nguyen Trung Truc
 //  08/17/12
 //************************************************
 // place a #use i2c statement in the main program and comment this out if not applicable
 //#define BME280_SDA  PIN_C4
 //#define BME280_SCL  PIN_C3
 #use i2c(master, sda=PIN_D0, scl=PIN_D1, FORCE_SW)
 #define BME280_ADDRESS 0xEE          // I2C address of BME280 VDD
 #include <math.h>
 //calibration values of BME280
 
 static unsigned int16 dig_T1;
 static signed int16  dig_T2;
 static signed int16  dig_T3;
 static unsigned int16  dig_P1;
 static signed int16  dig_P2;
 static signed int16  dig_P3;
 static signed int16  dig_P4;
 static signed int16  dig_P5;
 static signed int16  dig_P6;
 static signed int16  dig_P7;
 static signed int16  dig_P8;
 static signed int16  dig_P9;
 static unsigned int8  dig_H1;
 static signed int16  dig_H2;
 static unsigned int8  dig_H3;
 static signed int16  dig_H4;
 static signed int16  dig_H5;
 static signed int8   dig_H6;
 static int32 t_fine, var1, var2, adc_P, adc_T;
 static int16 adc_H;
 int8 BME280ReadByte(int8 address);
 int16 BME280ReadInt(int8 address) ;
 int32 BME280Read24(int8 data);
 void BME280WriteByte(int8 address, int8 data) ;
 int1 BME280ReadingCalibration(void);
 void BME280Calibration();
 void BME280SetSampling();
 
 void init_BME280()
 {
 output_float(PIN_D0);
 output_float(PIN_D1);
 }
 int1 BME280Begin()
 {
 
 // check if sensor, i.e. the chip ID is correct
 if(BME280ReadByte(0xD0) != 0x60)
 return 0;
 // reset the device using soft-reset
 // this makes sure the IIR is off, etc.
 BME280WriteByte(0xE0, 0xB6);
 
 // wait for chip to wake up.
 delay_ms(300);
 
 // if chip is still reading calibration, delay
 while ( BME280ReadingCalibration())
 delay_ms(100);
 
 BME280Calibration(); // read trimming parameters, see DS 4.2.2
 
 BME280SetSampling(); // use defaults
 
 return 1;
 }
 void BME280SetSampling()
 {
 
 BME280WriteByte(0xF2,0x03); // oversampling x 4, ctr_hum
 BME280WriteByte(0xF5,0x68); //011 (250ms tstandby) 0100 (filter coefficient =4) 0 (i2c)
 BME280WriteByte(0xF4,0x6E);// 011 011 10 temperature oversampling x 4, pressure oversampling x 4, force mode
 // you must make sure to also set REGISTER_CONTROL after setting the
 // CONTROLHUMID register, otherwise the values won't be applied (see DS 5.4.3)
 // write8(BME280_REGISTER_CONTROLHUMID, _humReg.get());
 // write8(BME280_REGISTER_CONFIG, _configReg.get());
 // write8(BME280_REGISTER_CONTROL, _measReg.get());
 }
 
 int8 BME280ReadID()
 //----------------------------------------------
 {
 int8 data;
 
 i2c_start();
 i2c_write(0xEE); // 0X77 11101110X IS IC ADDRESS, 0X76 IS 1110 110
 i2c_write(0xD0);
 i2c_start();
 i2c_write(0xEF );
 data=i2c_read(0);
 i2c_stop();
 delay_us(20);
 return(data);
 }
 //----------------------------------------------
 int8 BME280ReadByte(int8 address)
 //----------------------------------------------
 {
 int8 data;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01 );
 data=i2c_read(0);
 i2c_stop();
 return(data);
 }
 
 
 
 //----------------------------------------------
 int16 BME280ReadInt(int8 address)
 //----------------------------------------------
 {
 int8 msb, lsb;
 int16 temp;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01 );
 msb = i2c_read();
 lsb = i2c_read(0);
 i2c_stop();
 temp = make16(msb, lsb);
 return ( temp );
 }
 
 
 //----------------------------------------------
 void BME280WriteByte(int8 address, int8 data)
 //----------------------------------------------
 {
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_write(data);
 i2c_stop();
 }
 
 void BME280Calibration()
 //----------------------------------------------
 {
 dig_T1 = BME280ReadInt(0x88);
 dig_T2 = BME280ReadInt(0x8A);
 dig_T3 = BME280ReadInt(0x8C);
 dig_P1 = BME280ReadInt(0x8E);
 dig_P2 = BME280ReadInt(0x90);
 dig_P3 = BME280ReadInt(0x92);
 dig_P4 = BME280ReadInt(0x94);
 dig_P5 = BME280ReadInt(0x96);
 dig_P6 = BME280ReadInt(0x98);
 dig_P7 = BME280ReadInt(0x9A);
 dig_P8 = BME280ReadInt(0x9C);
 dig_P9 = BME280ReadInt(0x9E);
 dig_H1 = BME280ReadByte(0xA1);
 dig_H2 = BME280ReadInt(0xE1);
 dig_H3 = BME280ReadByte(0xE3);
 dig_H4 = (BME280ReadByte(0xE4)<<4|(BME280ReadByte(0xE5) & 0xF));
 dig_H5 = (BME280ReadByte(0xE6)<<4|(BME280ReadByte(0xE5) >>4));
 dig_H6 = BME280ReadByte(0xE7);
 }
 
 //----------------------------------------------
 
 
 // Read the uncompensated temperature value
 //----------------------------------------------
 void BurstRead()
 {
 int8 data[8];
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(0xF7);
 
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01);
 data[0] = i2c_read();
 data[1] = i2c_read();
 data[2] = i2c_read();
 data[3] = i2c_read();
 data[4] = i2c_read();
 data[5] = i2c_read();
 data[6] = i2c_read();
 data[7] = i2c_read(0);
 
 i2c_stop();
 adc_P = make32(0,data[0],data[1],data[2]);
 // adc_T = make32(0,data[3],data[4]);
 adc_T  = make32(0,data[3],data[4],data[5]);
 adc_H = make16(data[6],data[7]);
 
 // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 }
 
 int32 BME280Read24(int8 data)
 {
 unsigned int32 value;
 int8 msb, lsb, xlsb;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(data);
 
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01);
 
 // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
 
 msb = i2c_read();
 lsb = i2c_read();
 xlsb = i2c_read(0); // NACK on last read
 i2c_stop(); //*/
 
 value = make32(0,msb,lsb,xlsb);
 
 return value;
 }
 
 int1 BME280ReadingCalibration(void)
 {
 // unsigned int8 const rStatus = BME280ReadByte(0xF3);
 int8 rStatus = BME280ReadByte(0xF3);
 return (rStatus & (1 << 0)) != 0; // return 1 if bus is busy reading 1<<0  is 1 shifted left 0 times
 }
 
 void BME280TakeForcedMeasurement()
 {
 
 BME280WriteByte(0xF4,0x6E); //011 011 01 pressure oversampling x 4, temperature oversampling x 4, forced mode
 while (BME280ReadByte(0xF4) & 0x08)  // wait until measurement has been completed, otherwise we would read the values from the last measurement
 delay_us(10);
 }
 
 
 
 float BME280ReadTemperature(void)
 {
 
 
 int32 var1, var2;
 
 adc_T = BME280Read24(0xFA); //FA THE TEMPERATURE REGISTER
 if (adc_T == 0x800000) // value in case temp measurement was disabled
 return 0;
 adc_T >>= 4;
 
 var1 = ((((adc_T>>3) - ((int32)dig_T1 <<1)))*((int32)dig_T2)) >> 11;
 
 var2 = (((((adc_T>>4) - ((int32)dig_T1)) * ((adc_T>>4) - ((int32)dig_T1))) >> 12) *((int32)dig_T3)) >> 14;
 
 t_fine = var1 + var2;
 
 float T = (t_fine * 5 + 128) >> 8;
 return T/100;
 
 }
 float BME280ReadPressure(void) {
 int32 var1, var2, p;
 
 // readTemperature(); // must be done first to get t_fine
 
 int32 adc_P = BME280Read24(0XF7);
 if (adc_P == 0x800000) // value in case pressure measurement was disabled
 return 0;
 adc_P >>= 4;
 
 var1 = ((int32)t_fine) - 128000;
 var2 = var1 * var1 * (int32)dig_P6;
 var2 = var2 + ((var1*(int32)dig_P5)<<17);
 var2 = var2 + (((int32)dig_P4)<<35);
 var1 = ((var1 * var1 * (int32)dig_P3)>>8) +
 ((var1 * (int32)dig_P2)<<12);
 var1 = (((((int32)1)<<47)+var1))*((int32)dig_P1)>>33;
 
 if (var1 == 0) {
 return 0; // avoid exception caused by division by zero
 }
 p = 1048576 - adc_P;
 p = (((p<<31) - var2)*3125) / var1;
 var1 = (((int32)dig_P9) * (p>>13) * (p>>13)) >> 25;
 var2 = (((int32)dig_P8) * p) >> 19;
 
 p = ((p + var1 + var2) >> 8) + (((int32)dig_P7)<<4);
 return (float)p/256;
 }
 
 float BME280ReadHumidity(void) {
 //readTemperature(); // must be done first to get t_fine
 
 //int32 adc_H = BME280ReadInt(0xFD);// BME280_REGISTER_HUMIDDATA
 if (adc_H == 0x8000) // value in case humidity measurement was disabled
 return 0;
 int32  v_x1_u32r;
 
 v_x1_u32r = (t_fine - ((int32)76800));
 
 v_x1_u32r = (((((adc_H << 14) - (((int32)dig_H4) << 20) -
 (((int32)dig_H5) * v_x1_u32r)) + ((int32)16384)) >> 15) *
 (((((((v_x1_u32r * ((int32)dig_H6)) >> 10) *
 (((v_x1_u32r * ((int32)dig_H3)) >> 11) + ((int32)32768))) >> 10) +
 ((int32)2097152)) * ((int32)dig_H2) + 8192) >> 14));
 
 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7)*((int32)dig_H1)) >> 4));
 v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
 v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
 float h = (v_x1_u32r>>12);
 return  h / 1024.0;
 }
 
 // Read the uncompensated pressure value
 //----------------------------------------------
 
 
 
 
 | 
 
 and the main.c
 
 
  	  | Code: |  	  | //#include <16f877A.h>
 #include <16F887.h>
 #fuses HS, NOLVP, NOWDT, NOPROTECT
 #use   delay (clock=8000000) //Use built-in function: delay_ms() & delay_us()
 #use rs232(baud=38400, xmit=PIN_C6, rcv=PIN_C7)
 #include "LCD_TM.c" //use module function
 #include "BME280.c"
 void main(void)
 {
 int8 a;
 float temp;
 init_BME280();
 BME280Begin();
 delay_ms(20);
 
 printf("\r\ndig_T1: =%LU dig_T2=%Ld dig_T3=%Ld", dig_T1, dig_T2, dig_T3);
 printf("\r\nP1=%Ld P2=%Ld  P3=%Ld P4=%Ld P5=%Ld P6=%Ld P7=%Ld P8=%Ld P9=%Ld",dig_P1, dig_P2, dig_P3, dig_P4, dig_P5, dig_P6, dig_P7, dig_P8, dig_P9 );
 
 while(true)
 {
 
 
 
 temp = BME280ReadTemperature();
 delay_ms(50);
 
 lcd_init();
 lcd_gotoxy(1,1);
 printf(lcd_putc, "%Lu",adc_T);
 
 lcd_gotoxy(10,1);
 printf(lcd_putc, "%3.1f",temp);
 
 lcd_gotoxy(1,2);
 
 
 
 a = BME280ReadByte(0xF3);
 BME280WriteByte(0xF5,0x68); //011 (250ms tstandby) 0100 (filter coefficient =4) 0 (i2c)
 BME280WriteByte(0xF4,0x6E);
 lcd_gotoxy(14,2);
 printf(lcd_putc, "%u",a);
 
 delay_ms(500);
 
 }
 }
 
 | 
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 01, 2017 7:01 am |   |  
				| 
 |  
				| Look again at the data sheet code. 
 Note that BME280_S32_t, is a signed int32, and BME280_U32_t, is an unsigned int32. Note that 99% of the maths uses the _signed_ type.
 
 You are omitting this critical distinction.
 
 The simplest way to use the code, is to cut and paste it directly. If you typedef the two types, the actual conversion maths can be used 'as is'.
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9589
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 01, 2017 7:28 am |   |  
				| 
 |  
				| a comment. 
 Whenever doing 'complicated math', it's best to display intermediate calculations and do the math yourself to confirm EACH step of the calculations is correct.
 Use KNOWN test values, for temperature say, 0, 50, 100*C. Do ALL the math and get a set of known values. Perhaps use a spreadsheet to CONFIRM the numbers are correct.
 Reminds me of GIGO. Garbage In ,Garbage Out. A faulty sensor ,giving bad data then a "+x" insead of "-x" in the math is a sure way to ruin a few hours(or days) of your life.
 If you have bipolar ( negative AND positive) values, check BOTH ! Just because it works for one does not mean it'll work for the other. Also do the LIMITS ! Full scale vaules at both ends....
 
 Jay
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 01, 2017 8:04 am |   |  
				| 
 |  
				| There is also a big caveat. 
 CCS does a logical shift right, even on signed values. If you are right shifting a signed number, you need to sign extend this yourself.
 
 Have a look at:
 <http://www.ccsinfo.com/forum/viewtopic.php?t=54417&highlight=signed+shift>
 
 I've posted better versions in other similar threads at times, but this is reliable and simple.
 
 K&R specifically say the result of a right shift on a signed value is 'undefined'. Unfortunately the posted code relies on this....
 |  |  
		|  |  
		| ntrungtruc2003 
 
 
 Joined: 16 Feb 2011
 Posts: 42
 
 
 
			    
 
 | 
			
				| BME280 calculate temperature |  
				|  Posted: Tue Aug 01, 2017 10:11 am |   |  
				| 
 |  
				| Thanks for your response 
 Following BME280 from Bosch BME280 API
 https://github.com/BoschSensortec/BME280_driver, have another int32 function for calculte temperarute.
 
 But the problem hasn't been solved yet.
 I have also tested by excel file.
 dig_T1: 64366
 dig_T2: 14952
 dig_T3: 12800
 adc_T is an interger 20 bits: 556463
 
 and the excel's result is negative number about (-5xxx), therefore i think the
 new function is ok, but the adc_T is not good.
 
 The adc_T input will be  12xxxxx  to have the result of temperature is true.
 This is the first  time i test with this sensor, therefore i don't know what is true value for adc_T.
 
 Hope you can helps.
 
 
  	  | Code: |  	  | int32 Compensate_Temperature(void)
 {
 adc_T = BME280Read24(0xFA); //FA THE TEMPERATURE REGISTER
 if (adc_T == 0x800000) // value in case temp measurement was disabled
 return 0;
 //adc_T >>= 4;
 int32 var1;
 int32 var2;
 int32 temperature;
 int32 temperature_min = -4000;
 int32 temperature_max = 8500;
 
 var1 = (int32)((adc_T / 8) - ((int32)dig_T1 * 2));
 var1 = (var1 * ((int32)dig_T2)) / 2048;
 var2 = (int32)((adc_T / 16) - ((int32)dig_T1));
 var2 = (((var2 * var2) / 4096) * ((int32)dig_T3)) / 16384;
 t_fine = var1 + var2;
 temperature = (t_fine * 5 + 128) / 256;
 
 if (temperature < temperature_min)
 temperature = temperature_min;
 else if (temperature > temperature_max)
 temperature = temperature_max;
 
 return temperature;
 }
 
 | 
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19967
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Aug 01, 2017 10:19 am |   |  
				| 
 |  
				| Change _all_ the int32 declarations to signed. 
 The default 'int32' on most processors is signed _unless you specify otherwise_. On CCS it isn't.
 
 So (for instance):
 
 int32 temperature_min = -4000;
 
 will actually load temperature_min with 0xFFFFF060.
 
 If you printed it as a signed would give -4000.
 
 However if you then perform maths on it, the results will be the results of the unsigned arithmetic, not signed.
 
 In particular the > and < tests will be wrong....
 
 Just to confirm (went and checked - you have included the comma in the link get rid of this...), in the code, int32_t, is a signed int32, and uint32_t is an unsigned int32. If you include the standard types library (stdint.h), that already contains these definitions, and the original code will compile without changes....
 |  |  
		|  |  
		| ntrungtruc2003 
 
 
 Joined: 16 Feb 2011
 Posts: 42
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Aug 02, 2017 12:23 am |   |  
				| 
 |  
				| Thanks sir 
 The problem has been solved after checked datasheet again.
 
 The true trimming parameter readout is
 dig_T1: 28411
 dig_T2:26682
 dig_T3:50
 adc_T: 89xxxxx
 
 The true parameters are refererred from adruino board.
 
 
  	  | Code: |  	  | dig_T1 = BME280Read16_LE(0x88);
 dig_T2 = BME280ReadS16_LE(0x8A);
 dig_T3 = BME280ReadS16_LE(0x8C);
 | 
 
 I have also added 2 new fuction for receive  signed int16, unsigned int16 from i2c.
 
 
  	  | Code: |  	  | //----------------------------------------------
 int16 BME280Read16(int8 address)
 //----------------------------------------------
 {
 int8 msb, lsb;
 unsigned int16 temp;
 
 i2c_start();
 i2c_write(BME280_ADDRESS);
 i2c_write(address);
 i2c_start();
 i2c_write(BME280_ADDRESS | 0x01 );
 msb = i2c_read();
 lsb = i2c_read(0);
 i2c_stop();
 temp = (msb<<8)|lsb;  //make16(msb, lsb);
 return ( temp );
 }
 
 /**************************************************************************/
 /*!
 @brief  Reads a signed 16 bit value over I2C or SPI
 */
 /**************************************************************************/
 int16 BME280ReadS16(int8 address)
 {
 return ((signed int16)BME280Read16(address));
 }
 
 unsigned int16 BME280Read16_LE(int8 address)
 {
 unsigned int16 temp = BME280Read16(address);
 return (temp >> 8) | (temp << 8);
 }
 int16 BME280ReadS16_LE(int8 address)
 {
 return (int16)BME280Read16_LE(address);
 }
 
 
 | 
 
 Next step will be test with pressure and humidity, thanks for your response
 |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |