BME280 Pressure Sensor
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
BME280 Pressure Sensor
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:
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:
-
- 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
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.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.
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
― C.S. Lewis
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
Then it seems the Arduino code library must be studied deeper and the code from there better transposed in Flowcode BME280 component.
-
- Posts: 1333
- Joined: Tue Oct 06, 2009 9:39 am
- Has thanked: 1135 times
- Been thanked: 299 times
- Contact:
Re: BME280 Pressure Sensor
Hi!
would be nice if somebody could finish Ben´s component
Sorry I am not able to fix it
Br Jorgen
would be nice if somebody could finish Ben´s component
Sorry I am not able to fix it
Br Jorgen
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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:
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.
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);
}
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.
-
- Posts: 315
- Joined: Sun Jun 23, 2013 1:29 pm
- Has thanked: 28 times
- Been thanked: 61 times
- Contact:
Re: BME280 Pressure Sensor
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
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
- 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
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
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
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
Hi Ben,
I think I fixed it by comparing with CCS code.
Here is he test/debug code used: Here is the code for the component: Here is the the component: 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?
I think I fixed it by comparing with CCS code.
Here is he test/debug code used: Here is the code for the component: Here is the the component: 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?
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
Here is a test code with the updated component:
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:
It shows similar data as Arduino sketch with Adafruit BME280 library – tested on the same hardware.-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
- 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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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:
Now, using int32, I implemented the recommendation from Bosch datasheet:
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.
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;
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;
- 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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
Here is one more observation related with long int calculation of the pressure.
The next line is not always proper evaluated:
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:
I do not know what the cause is for that, requires more digging, it could be overflowing some limits of the type specifier variables.
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;
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;
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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:
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:
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:
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:
which gives me a result around +8000.
Now, if we split that long expression in 2:
and we evaluate:
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.
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;
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;
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;
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;
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);
Code: Select all
var1 = (temp1+temp2)>>18;
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
To understand better what I am talking about, look at the next C code:
Now evaluate var1 as
and after evaluation disable it by adding in front
and enable next line
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.
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;
Code: Select all
var1 = (temp1+temp2)>>18;
Code: Select all
//var1 = (temp1+temp2)>>18;
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;
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
- 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.
- 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
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.
With the complex expression there could be an intermediate calculation that is not cast to a long.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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
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
-
- Posts: 190
- Joined: Mon Jul 07, 2014 9:38 am
- Has thanked: 30 times
- Been thanked: 77 times
- Contact:
Re: BME280 Pressure Sensor
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.
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.
- JohnCrow
- 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
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.
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 !