BME280 Pressure Sensor

For questions and comments on programming in general. And for any items that don't fit into the forums below.

Moderators: Benj, Mods

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

BME280 Pressure Sensor

Post by viki2000 »

I use Flowcode 7.2.1 professional version purchased few months ago and BME280 is included at the Sensors as Pressure Sensor, but the Wiki Help page shows nothing.
I decided to give it a try.
In order to avoid any future discussion about wirings, I used Arduino Uno and Arduino Mega 2560 together with an OLED SH1106 display and I have tested the BME280 using Arduino programming environment in C. I have used Adafruit BME280 library, but I have tried also other libraries as Sparkfun BME280 and other found on internet, GitHub.
The Arduino, BME280 and OLED SH1106 work fine without problems.
I focused only the temperature measurement to be easy when I jump into Flowcode.
With the Flowcode the BME280 component does not work as it should. It shows wrong numbers, in my case negative numbers in the range -3.2 to -4.5 for temperatures which normal are 22-25 degree Celsius. The numbers just mentioned are not exactly, just as example.
The OLED SH1106 works fin inside the Flowcode, but the BME280 does not.
I have checked the discussion here:
viewtopic.php?f=65&t=18574
I have also tried RS232 and the HERCULES Setup Utility (the serial port monitor) used by Alan_37 and the numbers shown on PC screen are the same as on OLED display.
I will provide here below the code used for further debugging/reference, if needed also photos and schematic/diagram, but the Flowcode BME280 must be improved/re-written.

Any hope for improvements?

Here are the codes used:
Arduino_UNO_R3_BME280.zip
This code works fine
(695 Bytes) Downloaded 431 times
Arduino_UNO_R3_BME280.fcfx
This code does not work - the BME280 component gives wrong numbers
(12.4 KiB) Downloaded 340 times

kersing
Valued Contributor
Valued Contributor
Posts: 2045
Joined: Wed Aug 27, 2008 10:31 pm
Location: Netherlands
Has thanked: 553 times
Been thanked: 1081 times
Contact:

Re: BME280 Pressure Sensor

Post by kersing »

but if you look at the Adafruit or Sparkfun library in the .h code, there we do not see those compensation code implemented and the code works fine.
The sparkfun library includes the compensation code at lines 256-258 (for temperature) of src/SparkFunBME280.cpp, a quick look at the Adafruit library shows the code as well. I have recently been programming for these modules (in another programming language) and the results without compensation code would be useless.
I do not have any experience using the Flowcode component (yet) so I won't comment on that.
“Integrity is doing the right thing, even when no one is watching.”

― C.S. Lewis

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

I have realized that right after I have posted the question, so I deleted my comment about the compensation before you explained/answered it.
Then it seems the Arduino code library must be studied deeper and the code from there better transposed in Flowcode BME280 component.

jgu1
Posts: 1333
Joined: Tue Oct 06, 2009 9:39 am
Has thanked: 1135 times
Been thanked: 299 times
Contact:

Re: BME280 Pressure Sensor

Post by jgu1 »

Hi!

would be nice if somebody could finish Ben´s component :D

Sorry I am not able to fix it

Br Jorgen

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

There is one more piece of code, besides the known Arduino library and inspired from Arduino library, that can be used as comparison to fix the Flowcode BME280 component.
That is next CCS complier C code, at the bottom of next page, which is said that works, but I have never tested it myself:
http://na.wmrp.com/forum/viewtopic.php?t=56327&start=15

Then few more resources on net:
Directly Bosch:
https://github.com/BoschSensortec/BME280_driver
Mikroelektronika:
https://github.com/MikroElektronika/Fli ... Man/bme280
https://libstock.mikroe.com/projects/vi ... ther-click
and a Japanese pages (can be translated with Googke Translate) with PIC24FJ64GA00:
https://translate.google.com/translate? ... rev=search
http://www7b.biglobe.ne.jp/~nobosan_flu ... age006.gif
http://www7b.biglobe.ne.jp/~nobosan_flu ... 280_TEST.c
another Japanese code for PIC16F1829:
https://github.com/fues/BME280
PIC18F14K50 with temperature and humidity sensor BME 280:
https://translate.google.com/translate? ... rev=search
PIC16F1705 and BME280:
https://translate.google.com/translate? ... rev=search
PIC16F1938 and BME280:
http://takacity.blog.fc2.com/blog-entry-145.html
It seems the japanese guys focused more on PIC with BME280.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

I would like to confirm the code used in CCS compiler in the 1st link above.
I have tested it with PIC16F1829, BME280 address 0x76 (0xEC) and a LCD display 2x8. I was interested only in temperature and humidity. The code provides meaningful data/info on display, similar with Arduino code.
The setup and code used is below.
Image
PIC16F1829_BME280_CCS.zip
(128.77 KiB) Downloaded 438 times

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Hi,

I spent some good hours trying to find the bug in the code from BME280 component.
I think I found something and I would like to share it in order to have a final good component done by Ben.
First of all, I think it would be good if the component would have as parameters the oversampling and normal/forced mode to be exposed in settings. I know we have the read and write register and can be used, but is not exactly the same.
Here is my debugging journey.
I have used PIC161829 and BME280 with address 0x76 as in CCS setup above, only this time a LCD 4x20 to see more data. Of course works with RS232, a PC with serial terminal instead of LCD, but I find it easier with LCD.
I have used a LCD attached to the PIC16F1829 .
I have used the “Pressure_Sensor_BME280.fcfx” code (used to make the component) provided by Ben above and then I printed on LCD different parameters from different subroutines.
I focused only on temperature, because if one parameter is solved, then I thought is easier to correct the rest.
Using the same hardware, I then did the same inside the CCS IDE and I compared the code between Flowcode and CCS. That took some time.
I noticed 1st time that the .adc_T value in the “ReadTemperatureFloat” macro is almost the same in CCS as in FC7, but var1 and var2 were not the same.
Then I looked at T1, T2 and T3 and I noticed T1 is almost the same, but T2 and T3 not. That’s why var1 and var2 have wrong results.
Then I looked into “ReadCalibData” macro and T1, T2, T3 were not the same value as in CCS where BE280Calibartion(); subroutine is called. Especially T2 and T3 have totally different values than expected.
When T1, T2, and T3 are read then “I2C_Read2_Register” macro is called.
CCS has one more piece of code besides “temp = msb*256 + lsb; //(msb<<8)|lsb; ” in “int16 BME280Read16(int8 address)” subroutine or in our case “.Return = .Return | (.temp << 8)” and that is
“temp = (temp >> 8) | (temp << 8); ” in “unsigned int16 BME280Read16_LE(int8 address)” subroutine.
That means in our case we have to do “.Return = (.Return >> 8) | (.Return << 8); ” at the end of “I2C_Read2_Register” macro.
And now the LCD shows a meaningful info for temperature similar as CCS code.
I did not check the humidity and pressure macros and parameters, but at least we have a start point to continue and one bug came out in the light.
PIC16F1829_BME280.fcfx
Test program to find the bug in BME280 component.
(49.81 KiB) Downloaded 348 times

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

For humidity the “.Return = (.Return >> 8) | (.Return << 8)” must be disabled in “I2C_Read2_Register” otherwise the TFINE gives wrong values. So, maybe 2 macros “I2C_Read2_Register” must be written, one for temperature and one for humidity. Or another options is to write in Read Calibration macro, after reading T1 next code “T1 = (T1 >> 8) | (T1 << 8)” and similar for T2 and T3.
With these change we get good value for .adc_H in ReadHumidityFloat, but there is at least one more bug in C code at v_x1_u32r calculations.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

The humidity is solved too. It was a bigger headache to trace down the problem.
In the “ReadHumidityFloat” macro, the error came from C code of “v_x1_u32r” variable calculations.
I had to split that impossible equations in many simple calculations and check the evaluation of each expression. With so many parenthesis left and right, even if we count them, it still seems like those illusion pictures and is easy to lose track of them if you want to split that long expression. In the end I did it by copying it in Word and then with help from formula it shows up nicer with bigger and smaller parenthesis. It turned out that H2 parameter is not read properly or at least its calculation.
It must be unsigned and then signed when some calculations are done.
I do not know how to convert in Flowcode unsigned to signed, except using C, and that’s why I declared 2 variables, one unsigned and one signed and I just added a calculation block where the signed is equal with unsigned.
If you have any ideas how to convert in Flowcode unsigned to signed for the same variable please post some code or comments.
That solved the problem and the humidity is shown now with good values.
Thinking back, I realize the bugs came out of 2 things, and I expect for the pressure to be the same, the next subroutines in CCS show missing code in initial Flowcode and the way how the variables are declared signed or unsigned:

Code: Select all

int16 BME280ReadS16(int8 address)
{
    return ((signed int16)BME280Read16(address));
}

unsigned int16 BME280Read16_LE(int8 address)
{
    unsigned int16 temp;
    temp = BME280Read16(address);
    temp = (temp >> 8) | (temp << 8);
    return (unsigned int16)temp;
}
signed int16 BME280ReadS16_LE(int8 address)
{
    return (signed int16)BME280Read16_LE(address);
}
The test FC7 flowchart code below shows good values for temperature and humidity.
Next would be the correction for pressure and then it should be clean up with the proper signed, unsigned variables and the proper conversions after the “I2C_Read2_Register” macro is called for some of the parameters.
PIC16F1829_BME280_2.fcfx
(51.85 KiB) Downloaded 288 times

Docara
Posts: 315
Joined: Sun Jun 23, 2013 1:29 pm
Has thanked: 28 times
Been thanked: 61 times
Contact:

Re: BME280 Pressure Sensor

Post by Docara »

Hi Viki2000,

Thank you so much for the work you have done and also your willingness to share your findings/results.

I take great pleasure when you post here and always read through your posts and like how you overcome the problems you encounter.

I don't know if Matrix give you any credit for your work you get any credit for your efforts but I would guess a lot of people here gain value from your work.

Thank you again
Matt
Last edited by Docara on Mon Nov 13, 2017 2:06 pm, edited 1 time in total.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

I do not know about you guys, but when I encounter something that does not work I stress myself and the adrenaline goes up as I would be “two steps from hell” and I feel like in an epic movie:
https://www.youtube.com/watch?v=PKC_RQtvAR0
and then I can focus lots better; in the end I am tired, but the problem is solved.

User avatar
Benj
Matrix Staff
Posts: 15312
Joined: Mon Oct 16, 2006 10:48 am
Location: Matrix TS Ltd
Has thanked: 4803 times
Been thanked: 4314 times
Contact:

Re: BME280 Pressure Sensor

Post by Benj »

Hi Viki2000,

Thanks so much for letting us know how you've gotten on. I've added your suggested fixes to the component source code and I also have John Crow's sensor sat here on my bench. I've been carrying it around with me for the past couple of weeks trying to find a few hours to get it tested. This seems like a good opportunity so while this is fresh in my mind I'll have a play with it today and make sure things look correct.

Also thanks for sharing the music. Having a listen now. I've been hammering IDKFA on YouTube far too much recently.
https://www.youtube.com/watch?v=AGK1dr-Ql0w

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Hi Ben,

I think I fixed it by comparing with CCS code.
Here is he test/debug code used:
PIC16F1829_BME280_3.fcfx
(48.74 KiB) Downloaded 232 times
Here is the code for the component:
BME280_2.fcfx
(42.5 KiB) Downloaded 241 times
Here is the the component:
BME280_2.fcpx
(4.77 KiB) Downloaded 227 times
Please check it by yourself and make the improvements that you consider necessary.
For example in the macro “ReadPressureFloat” I have used float instead of long long and the calculation is a bit different compared with Arduino library, it is similar as in CCS code.
Maybe it works also with long long for var1, var2 and the code from Arduino library, but I do not have any more time.
The same hardware with PIC16F1829, LCD 4x20 and BME280 it works fine with CCS code and Flowcode above. Perhaps I will try also Arduino later.

How do you manage to add a nice image/picture to the component in such way that it is seen clear in projects? I know how and where, but what size/resolution do you use?

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Here is a test code with the updated component:
PIC16F1829_LCD_4x20_BME280.fcfx
(13.51 KiB) Downloaded 228 times
Here is a test code with the updated component using Arduino Uno R3, OLED SH1106 128x64 and BME280. It sends data also serial to PC:
Arduino_UNO_R3_BME280.fcfx
(15.37 KiB) Downloaded 237 times
It shows similar data as Arduino sketch with Adafruit BME280 library – tested on the same hardware.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

I do not know if I will have more time to stay on BME280 component code, but few things to consider if you plan to remake it by changing the code:
- In the macro “ReadPressureFloat” I have used float instead of long long, to follow the CCS code, it works, but I do not like that too much. I would prefer to use long long because is int, even if it is big number, and the PICs are not very tolerant/friendly with float, they are slow and process them harder. In this case might not be a problem, the sensor is anyway slow, but if other processes are going on, then it might matter. As conclusion, maybe is good to correct the initial code with long long and the calculations similar as in Adafruit library.
- The CCS code contains a code for pressure compensation. It is int32 and takes a lot of flash and calculation time/power. It would be good to have it and then only to enable/disable it in the settings of the component.
- A helpful component macro function would be good to be: take a force measurement.
- I think it would be also good if the component would have as parameters the oversampling and normal/forced mode to be exposed in settings.
If there are portable applications, where the power consumptions matters, then forced mode is helpful as initial setting, without necessity to write a new initialization macro using the write register.
Then if it is needed a better precision, downslide loner time of measurements or contrary faster measurements with lower precision, then it would be good to have access to the oversampling in the initial settings.
- If the code for component is provided besides the component itself, then it would also helpful for future users for next reason. As we notice, this component takes a lot of resources, flash memory for a small PIC, as for example my PIC161829. In such situations, in case is needed only 1 or 2 parameters, for example only temperature, then the code could be altered to delete the macros and calls for the other parameters and the whole code becomes smaller.
The nice thing it would be to have at components settings enable/disable for the temperature, humidity, pressure. Then automatically during compiling time, the code would become smaller. That would be nice.
- What is not done here and the Arduino code has it, is the altitude calculation based on “#define SEALEVELPRESSURE_HPA (1013.25)”.
I think that would be all from my point of view.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

The datasheet page 49 shows the implementations with double precision floating point and „is only recommended for PC applications.“
The page 50 shows the “Pressure compensation in 32 bit fixed point”:
https://ae-bst.resource.bosch.com/media ... 001-11.pdf

In the “ReadPressureFloat” macro next working code with float numbers was used during the last days:

Code: Select all

float var1, var2, p;

var1 = ((float)FCL_TFINE/2.0) - 64000.0;
var2 = var1 * var1 * ((float)FCL_P6) / 32768.0;


var2 = var2 + var1 * ((float)FCL_P5) * 2.0;
var2 = (var2/4.0)+(((float)FCL_P4) * 65536.0);
var1 = (((float)FCL_P3) * var1 * var1 / 524288.0 + ((float)FCL_P2) * var1) / 524288.0;
var1 = (1.0 + var1 / 32768.0)*((float)FCL_P1);

if (var1 == 0.0)
   {
   //return 0; // avoid exception caused by division by zero
}
p = 1048576.0 - (float)FCL_ADC_P;
p = (p - (var2 / 4096.0)) * 6250.0 / var1;

var1 = ((float)FCL_P9) * p * p / 2147483648.0;
var2 = p * ((float)FCL_P8) / 32768.0;
p = p + (var1 + var2 + ((float)FCL_P7)) / 16.0;

return p/100;
Now, using int32, I implemented the recommendation from Bosch datasheet:

Code: Select all

signed long int var1, var2;
unsigned long int p;

var1 = (((signed long int)FCL_TFINE)>>1) - (signed long int)64000;
var2 = (((var1>>2) * (var1>>2)) >> 11) * ((signed long int)FCL_P6);
var2 = var2 + ((var1*((signed long int)FCL_P5))<<1);
var2 = (var2>>2)+(((signed long int)FCL_P4)<<16);
var1 = (((FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)FCL_P2) * var1)>>1))>>18;
var1 = ((((32768+var1))*((signed long int)FCL_P1))>>15);
if (var1 == 0)
{
    return 0;
}    
p = (((unsigned long int)(((signed long int)1048576)-FCL_ADC_P)-(var2>>12)))*3125;
if(p<0x80000000)
{
   p = (p << 1) / ((unsigned long int) var1);   
}
else
{
   p = (p / (unsigned long int)var1) * 2;    
}
var1 = (((signed long int)FCL_P9) * ((signed long int)(((p>>3) * (p>>3))>>13)))>>12;
var2 = (((signed long int)(p>>2)) * ((signed long int)FCL_P8))>>13;
p = (unsigned long int)((signed long int)p + ((var1 + var2 + FCL_P7) >> 4));
return p/100;
It works and the difference seen in the pressure is next:
- With float I see 1016.6 hPa on display
- With int32 I see 1016.0 hPa on display
- The difference is around 0.5, I would say acceptable, because the flash memory used is less and the computation power is less.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Here is one more observation related with long int calculation of the pressure.
The next line is not always proper evaluated:

Code: Select all

var1 = ((((signed long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long int)FCL_P2) * var1)>>1))>>18;
When I say not always I mean that I put my finger on sensor and I am looking on display to see any changes.
The pressure changes dramatically from values of 1022 hPa to 817 hPa in 2-3s and then returns back after very long time.
When the code is tested with CCS compiler, then is different, the pressure does not change dramatically.
The above change happens due to var1 evaluation in the above mentioned line.
I noticed that if I split that long expression in 2 using 2 more variables, then everything is fine, similar as CCS code behavior:

Code: Select all

signed long int temp1, temp2;
temp1 = (((signed long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3);
temp2 = ((((signed long int)FCL_P2) * var1)>>1);
var1 = (temp1+temp2)>>18;
I do not know what the cause is for that, requires more digging, it could be overflowing some limits of the type specifier variables.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

These are the last tests and analysis that I have done regarding the pressure calculations.
I have changed from signed long int to signed long long int. I have tried the calculatiosn with signed long long and is the same result.
I have tested in 2 stages: one time free air settle time 5min and then I put my finger on sensor. Then I looked at the numbers var1 and var2 how are evaluated and how do they change during the process when I put my finger on sensor, Then I did the same with CCS code.
Some intermediate numbers are very big and they change the sign during that process.
For example if we take next expressions:

Code: Select all

var1 = (((signed long long int)FCL_TFINE)>>1) - (signed long long int)64000;
//….
temp1 = (((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3);
temp2 = ((((signed long long int)FCL_P2) * var1)>>1);
var1 = (temp1+temp2)>>18;
Then FCL_P3 is almost fixed = 3024 and FCL_P2 the same almost fixed = -10835.
In the free air, no finger on sensor, I get similar results with FC7 and CCS: The numbers below are only indicative to see their dimension order, because they change continuously:
FC7:
var1=-7.788
temp1=176.148
temp2=42.261.504
var1=161

CCS:
var1=-7.100
temp1=145.908
temp2=38.745.000
var1=151
So we are fine here.

When I put my finger on sensor for 10s approx., then:
FC7:
var1=200.000
temp1=1.200.000
temp2=-110.000.000
var1=-390

CCS:
var1=200.000
temp1=1.200.000
temp2=-110.000.000
var1=-420
We are still fine up to this point.

Then if instead of temp1 + temp2 we use a single long expression as:

Code: Select all

var1 = ((((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3)+((((signed long long int)FCL_P2) * var1)>>1))>>18;
Then we are in trouble.
In CCS is evaluated proper giving the same last result as above var1=-420, but in FC7 seems a kind of overflow or a problem with negative big numbers when are shifted or multiplied.
The result in FC7 is var1=+8.000, which is wrong.
The calculation result is wrong due to the type of variable used or the limitation of compiler, I do not know. What I know is that if we split that long expression in 2 and we evaluate 2 variables then the result is correct.
From memory point of view we can use only one temp variable instead of temp1 and temp2.
Next expression gives a good result, similar with 2 variables temp1 and temp2:

Code: Select all

temp = ((((signed long long int)FCL_P2) * var1)>>1);
var1 = ((((signed long long int)FCL_P3*(((var1>>2)*(var1>>2))>>13))>>3)+temp)>>18;
It seems it does not matter not matter of the variables are declared long long int instead of long int.

If you want to continue to find the cause for such improper evaluation in a single long expression then you may try using the above given numbers. I write them here below one more time.
FCL_P3=3024
FCL_P2=-10835
Initial var1=20.000 (here the point is the thousand separator, so you read 20 thousands)
Then the expression to evaluate:

Code: Select all

var1 = ((((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3)+((((signed long long int)FCL_P2) * var1)>>1))>>18;
which gives me a result around +8000.
Now, if we split that long expression in 2:

Code: Select all

temp1 = (((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3);
temp2 = ((((signed long long int)FCL_P2) * var1)>>1);
and we evaluate:

Code: Select all

var1 = (temp1+temp2)>>18;
then I get as result around -400.
Why this difference between +8000 and -400 using the same numbers and only the expression is spitted in2, I think has to do with some limitation of arithmetical computations of the compiler, variable type identifiers. I have no other idea, because cannot be mistyping; I have done copy/paste when the expression was split.
If you have time to look into it, please let me have your comments. I cannot go further for the moment.
If not then we can use it with that additional temp variable and then the variables can be declared long int, seems enough, instead of long long int.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

To understand better what I am talking about, look at the next C code:

Code: Select all

signed long long int var1, temp1, temp2;
FCL_TFINE=170000;
FCL_P2=-10835;
FCL_P3=3024;

var1 = (((signed long long int)FCL_TFINE)>>1) - (signed long long int)64000;
temp1 = (((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3);
temp2 = ((((signed long long int)FCL_P2) * var1)>>1);
var1 = (temp1+temp2)>>18;
//var1 = ((((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long long int)FCL_P2) * var1)>>1))>>18;

FCL_VARB1=var1;
Now evaluate var1 as

Code: Select all

var1 = (temp1+temp2)>>18;
and after evaluation disable it by adding in front

Code: Select all

//var1 = (temp1+temp2)>>18;
and enable next line

Code: Select all

var1 = ((((signed long long int)FCL_P3 * (((var1>>2)*(var1>>2)) >> 13)) >>3) + ((((signed long long int)FCL_P2) * var1)>>1))>>18;
The results are totally different.
First time var1=7762 and the second time var1=-430.
You may try another PIC if you want and use RS232 instead LCD. I send FCL_VARB1 to LCD.
Below is the flowchart used to test the C code above.
Maybe someone can come up with an explanation and a solution for it.
PIC16F1829_large_numbers.fcfx
error
(11.83 KiB) Downloaded 192 times

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

If we come out of C and we implement the calculation with calculation icon in Fowcode then is funny:
- with the real device PIC16F1829 I have the same bad result when the expression is kept long.
- the simulator shows good result no matter if is long expression or split in 2.
Could be then a limitation from my PIC16F1829?
I must try with another PIC, but is good to know when the BME280 component is implemented with int32 for pressure, then is good to think also at smaller PICs as PIC16F and maybe to let the expression split in 2 in order to avoid errors with different other PICs.
PIC16F1829_large_numbers_2.fcfx
out of C
(14.15 KiB) Downloaded 192 times

User avatar
LeighM
Matrix Staff
Posts: 2178
Joined: Tue Jan 17, 2012 10:07 am
Has thanked: 481 times
Been thanked: 699 times
Contact:

Re: BME280 Pressure Sensor

Post by LeighM »

I think the issue is the default size of integer for the compiler.
With the complex expression there could be an intermediate calculation that is not cast to a long.

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Here is final word about the above error.
I have tried the evaluation of the expression with PIC18F4550 and works fine, no matter if it is a long expression or split in 2. No errors, not so ever, C code and normal calculation icon.
It seems the problem was related only with PIC16F1829.
As I mentioned above, maybe is good to let the expression split in 2 in order to avoid errors with different other smaller PICs.
PIC18F4550_large_numbers.fcfx
(11.07 KiB) Downloaded 223 times

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

What if the BME280 is SPI and not I2C?
Then I think we need a component BME280 also for SPI 3 or/and 4 wires.
Here is a XC8 example for PIC18F:
https://github.com/jrmcguire/BME280

viki2000
Posts: 190
Joined: Mon Jul 07, 2014 9:38 am
Has thanked: 30 times
Been thanked: 77 times
Contact:

Re: BME280 Pressure Sensor

Post by viki2000 »

Because at the above problem no one here looked interested to double check it in order to confirm or refute my findings, I opened a discussion on Microchip forum:
http://www.microchip.com/forums/m1025533.aspx
Here is the conclusion: The XC8 version 1.41 with optimization level PRO has a bug when we work with PIC16F and the long expression above. The free and standard optimization work fine.
I did not test other versions of XC8 as 1.40 or 1.42 or 1.43 to see if the bug is still there, but I checked the latest version of XC8 v .144 and the bug is not there. The long expression is evaluated correctly no matter what optimization levels are used.

User avatar
JohnCrow
Valued Contributor
Valued Contributor
Posts: 1367
Joined: Wed Sep 19, 2007 1:21 pm
Location: Lincolnshire
Has thanked: 364 times
Been thanked: 716 times
Contact:

Re: BME280 Pressure Sensor

Post by JohnCrow »

Hi Viki

Thanks for the recent posts
I have had a quick look at your component, (Not had time recently to sit down and have a in-depth look at this or to make replays.)
But not been able to get it to work correctly so far.

Will try the 4550 flowchart as soon as I get chance.

I am keen to get the BME 280 working as I have a project pending for it.
1 in 10 people understand binary, the other one doesn't !

Post Reply