Introduction:
The BMP180 is a tiny, high resolution, Atmospheric Pressure (and Temperature) sensor which uses the I2C two-wire data bus, so it can be easily interfaced with most PICaxe chips, including the 08M2. Many ebay listings suggest the BMP280 "replaces" the 180, but this is rather misleading because it is not a "drop in" replacement. It uses different data formats and most of the "breakout" modules don't include the (required) 3.3 volt supply regulator which is included on most BMP180 modules. However, it can give even higher resolution results, around +/- 0.002 hPa (aka millibars) and 0.01 degree C, and adds other hardware options such as a SPI bus interface. Then, the BME280 (E for Environmental) adds Humidity sensing, again at modest cost such that these devices are worthy of consideration even if only one or two of the sensor functions are required.
However, an issue for PICaxe is that these sensors supply "Raw" (uncalibrated) measurements, together with up to 18 "Calibration Constants" (3 for Temperature, 9 for Pressure and 6 for Humidity), which need quite complex mathematical processing to deliver a useful result. There are several related threads on the forum, and one "Finished Project" for the BMP180, but it requires an X2 chip and my trial run using the PE5 simulator took half an hour to compute the test result (and returned an incorrect pressure value). Therefore, I have been looking to see if it is practical to use these sensors with an M2 PICaxe (Hint: Yes it is, or I wouldn't be bothering with this thread ).
For my "Library" subroutines and programs I try to use less than half of the "available resources" (Program and Variables Memory, etc.) of an 08M2. That won't be possible for the full gamut of Pressure, Temperature and Humidity sensing (however they should all fit within a single slot of any larger M2), but could give, for example, useful high resolution temperature sensing with an 08M2.
This is still a "work in progress"; I don't yet have test data or a validated program for the Humidity sensor, and perhaps my mathematical subroutines can be improved? This thread will (necessarily) be quite long; it will definitely spread into multiple posts, if only because of the 10,000 character forum limit, so I am including some subheadings to help readers find relevant (or skip irrelevant) details.
The Mathematics:
The Bosch data sheets for these devices are quite "readable", but the mathematical computations become progressively more obscure (IMHO). It is worthwhile looking at all three data sheets because they contain rather different details, for example only the BMP180 data describes how to convert a pressure change into altitude above sea level, whilst only the BME280 data includes the Humidity computation. Unfortunately the .PDF listings are in the form of "Images", or are "Protected", so it may be necessary to jump through a few hoops to transfer the computational details into a text editor (such as the PICaxe PE). Also, the data sheets give no indication of the range or function of the Calibration Constants, so the conversion of the equations or programs into PICaxe Basic must be mainly via a rather "dumb" replication process.
The BMP180 data includes a list of equations and a "worked example" with typical 32-bit data values. However, the BMP280 data sheet shows only sample "C" program code, primarily in 64-bit "Long-Long-Signed-Integer" form, but with options of 32-bit integer ("for 8-bit microcontrollers") and "Double-Precision Floating-Point" (for systems where integers are "not well supported"). Again there is a sample calculation, but using Floating-Point values, whilst the full listings use around ten different numerical formats (from nibbles up to 64-bit words, Signed and Unsigned integers, FP and a few "fractional binary" formats such Q22.10). The BME280 data sheet continues with the C program format, where a single line in the Humidity calculation contains no less than 33 pairs of partially-nested brackets () and there is no example data or calculation.
Although the "recommended" calculations use 64-bit integer maths, this is probably "overkill", at least for most PICaxe applications. The calibration data uses 16-bit integer words (mostly Signed, a few Unsigned) and the "Raw" measurements use 16 - 20 bits depending on the degree of "oversampling" (adding together repeated measurements). To maintain resolution in integer multiplication and division processes, twice this number of bits is required, but in practice 32 bits should be sufficient. The advantage of this is that for most processes we can simply "double-up" the PICaxe's normal Word variables, rather than working with groups of 4+ bytes or even strings of individual bits.
Basic Implementation:
32-bit (4 byte) variables can be stored in the same way as if we run out of (named) variables in PICaxe Basic, i.e. by using a "pointer" variable. This is similar to the use of read/write or peek/poke, or @bptr into the "extended" RAM area (beyond the named byte/word variables). In the same way that we need to step the pointer by 2 (bytes) for each complete Word variable, we must step it by 4 for each Double-Word. However, the Calibration Constants are only 16-bit words and never change for any individual sensor, so they can be read just once and stored in EEPROM. Alternatively, for simplicity or convenience (e.g. whilst debugging) they may be stored entirely in RAM and/or as 32-bit double-words, but generally the EEPROM (or Table) memory is most appropriate.
For high precision numerical calculations, of the type A = B * C , we need to create a software "Arithmetic Logic Unit" (ALU) using "normal" Word variables. But usually, the operator (e.g. the * multiplier, or + , / , etc.) will be part of a continuous sequence of operations, so it is more efficient and compact to use the form A = A * B . As with many ALUs, the primary variable has been named the "Accumulator" (ACC), with the second variable named BCC (to assist text editing). However, some operations act directly on the Accumulator alone, so a separate Auxiliary Word register (WA) may be used to "control" the operation, rather than disturb (overwrite) a running value in BCC. Thus, the basic ALU requires 5 words (or 10 bytes) of variable space, plus two "Pointer bytes" to load/save the registers. For most "internal" ALU operations the ACC and BCC are split into High and Low Words, namely AH, AL, BH, and BL.
Since the word variables "overlay" the normal RAM space, only one subroutine is required to move data between any of the ALU Registers or Memory (Double-) Words. For this subroutine I've used the keyword "COPY" to indicate that the source value remains unchanged. However, the current routines do NOT reinstate the Pointers on exit (Return) because this appears to be (mainly) unneeded. Conversely, the "WORD" qualifier in PICaxe data transfers does maintain the pointer value, but these appear to be "Pseudo" commands (generated within the PE), so separate byte commands can be more efficient. Nearly all the "ALU" functions must be within Subroutines (not Macros) because most will be used many times throughout the program.
If the calibration data are stored as 16-bit words and/or in EEPROM, then a second subroutine is needed to load them into the 32-bit Long-Word format. The keyword "GET" is used here (no reverse path is relevant), which might be used only when loading the data values from the sensor chip via I2C, or more probably "on the fly" during the normal calculations. Most of these constants are Signed (a few are Unsigned), so when expanding a Word to fill a Double-Word variable, it's necessary to "Sign Extend" the most significant bit (the sign bit) all through the upper two bytes.
Of course PICaxe Basic doesn't support Signed arithmetic, but ADD (ition) works "automatically" if the operands are in "two's complement" format (i.e. where the MS bit = 1 indicates a negative number). But for other operations such as multiplication and division it's necessary to convert negative numbers to positive, perform the operation on the positive numbers and then convert back to negative if one (but not both) of the operands was negative.
A detailed description of the subroutines will take me past the 10,000 character forum post limit, so I will continue in another post (in due course). The impatient can take a look at (and try in the simulator) the Finished Project linked above.
Cheers, Alan.
The BMP180 is a tiny, high resolution, Atmospheric Pressure (and Temperature) sensor which uses the I2C two-wire data bus, so it can be easily interfaced with most PICaxe chips, including the 08M2. Many ebay listings suggest the BMP280 "replaces" the 180, but this is rather misleading because it is not a "drop in" replacement. It uses different data formats and most of the "breakout" modules don't include the (required) 3.3 volt supply regulator which is included on most BMP180 modules. However, it can give even higher resolution results, around +/- 0.002 hPa (aka millibars) and 0.01 degree C, and adds other hardware options such as a SPI bus interface. Then, the BME280 (E for Environmental) adds Humidity sensing, again at modest cost such that these devices are worthy of consideration even if only one or two of the sensor functions are required.
However, an issue for PICaxe is that these sensors supply "Raw" (uncalibrated) measurements, together with up to 18 "Calibration Constants" (3 for Temperature, 9 for Pressure and 6 for Humidity), which need quite complex mathematical processing to deliver a useful result. There are several related threads on the forum, and one "Finished Project" for the BMP180, but it requires an X2 chip and my trial run using the PE5 simulator took half an hour to compute the test result (and returned an incorrect pressure value). Therefore, I have been looking to see if it is practical to use these sensors with an M2 PICaxe (Hint: Yes it is, or I wouldn't be bothering with this thread ).
For my "Library" subroutines and programs I try to use less than half of the "available resources" (Program and Variables Memory, etc.) of an 08M2. That won't be possible for the full gamut of Pressure, Temperature and Humidity sensing (however they should all fit within a single slot of any larger M2), but could give, for example, useful high resolution temperature sensing with an 08M2.
This is still a "work in progress"; I don't yet have test data or a validated program for the Humidity sensor, and perhaps my mathematical subroutines can be improved? This thread will (necessarily) be quite long; it will definitely spread into multiple posts, if only because of the 10,000 character forum limit, so I am including some subheadings to help readers find relevant (or skip irrelevant) details.
The Mathematics:
The Bosch data sheets for these devices are quite "readable", but the mathematical computations become progressively more obscure (IMHO). It is worthwhile looking at all three data sheets because they contain rather different details, for example only the BMP180 data describes how to convert a pressure change into altitude above sea level, whilst only the BME280 data includes the Humidity computation. Unfortunately the .PDF listings are in the form of "Images", or are "Protected", so it may be necessary to jump through a few hoops to transfer the computational details into a text editor (such as the PICaxe PE). Also, the data sheets give no indication of the range or function of the Calibration Constants, so the conversion of the equations or programs into PICaxe Basic must be mainly via a rather "dumb" replication process.
The BMP180 data includes a list of equations and a "worked example" with typical 32-bit data values. However, the BMP280 data sheet shows only sample "C" program code, primarily in 64-bit "Long-Long-Signed-Integer" form, but with options of 32-bit integer ("for 8-bit microcontrollers") and "Double-Precision Floating-Point" (for systems where integers are "not well supported"). Again there is a sample calculation, but using Floating-Point values, whilst the full listings use around ten different numerical formats (from nibbles up to 64-bit words, Signed and Unsigned integers, FP and a few "fractional binary" formats such Q22.10). The BME280 data sheet continues with the C program format, where a single line in the Humidity calculation contains no less than 33 pairs of partially-nested brackets () and there is no example data or calculation.
Although the "recommended" calculations use 64-bit integer maths, this is probably "overkill", at least for most PICaxe applications. The calibration data uses 16-bit integer words (mostly Signed, a few Unsigned) and the "Raw" measurements use 16 - 20 bits depending on the degree of "oversampling" (adding together repeated measurements). To maintain resolution in integer multiplication and division processes, twice this number of bits is required, but in practice 32 bits should be sufficient. The advantage of this is that for most processes we can simply "double-up" the PICaxe's normal Word variables, rather than working with groups of 4+ bytes or even strings of individual bits.
Basic Implementation:
32-bit (4 byte) variables can be stored in the same way as if we run out of (named) variables in PICaxe Basic, i.e. by using a "pointer" variable. This is similar to the use of read/write or peek/poke, or @bptr into the "extended" RAM area (beyond the named byte/word variables). In the same way that we need to step the pointer by 2 (bytes) for each complete Word variable, we must step it by 4 for each Double-Word. However, the Calibration Constants are only 16-bit words and never change for any individual sensor, so they can be read just once and stored in EEPROM. Alternatively, for simplicity or convenience (e.g. whilst debugging) they may be stored entirely in RAM and/or as 32-bit double-words, but generally the EEPROM (or Table) memory is most appropriate.
For high precision numerical calculations, of the type A = B * C , we need to create a software "Arithmetic Logic Unit" (ALU) using "normal" Word variables. But usually, the operator (e.g. the * multiplier, or + , / , etc.) will be part of a continuous sequence of operations, so it is more efficient and compact to use the form A = A * B . As with many ALUs, the primary variable has been named the "Accumulator" (ACC), with the second variable named BCC (to assist text editing). However, some operations act directly on the Accumulator alone, so a separate Auxiliary Word register (WA) may be used to "control" the operation, rather than disturb (overwrite) a running value in BCC. Thus, the basic ALU requires 5 words (or 10 bytes) of variable space, plus two "Pointer bytes" to load/save the registers. For most "internal" ALU operations the ACC and BCC are split into High and Low Words, namely AH, AL, BH, and BL.
Since the word variables "overlay" the normal RAM space, only one subroutine is required to move data between any of the ALU Registers or Memory (Double-) Words. For this subroutine I've used the keyword "COPY" to indicate that the source value remains unchanged. However, the current routines do NOT reinstate the Pointers on exit (Return) because this appears to be (mainly) unneeded. Conversely, the "WORD" qualifier in PICaxe data transfers does maintain the pointer value, but these appear to be "Pseudo" commands (generated within the PE), so separate byte commands can be more efficient. Nearly all the "ALU" functions must be within Subroutines (not Macros) because most will be used many times throughout the program.
If the calibration data are stored as 16-bit words and/or in EEPROM, then a second subroutine is needed to load them into the 32-bit Long-Word format. The keyword "GET" is used here (no reverse path is relevant), which might be used only when loading the data values from the sensor chip via I2C, or more probably "on the fly" during the normal calculations. Most of these constants are Signed (a few are Unsigned), so when expanding a Word to fill a Double-Word variable, it's necessary to "Sign Extend" the most significant bit (the sign bit) all through the upper two bytes.
Of course PICaxe Basic doesn't support Signed arithmetic, but ADD (ition) works "automatically" if the operands are in "two's complement" format (i.e. where the MS bit = 1 indicates a negative number). But for other operations such as multiplication and division it's necessary to convert negative numbers to positive, perform the operation on the positive numbers and then convert back to negative if one (but not both) of the operands was negative.
A detailed description of the subroutines will take me past the 10,000 character forum post limit, so I will continue in another post (in due course). The impatient can take a look at (and try in the simulator) the Finished Project linked above.
Cheers, Alan.