PIC plus-5110 LCD-GPS-BMP280-HMC5983

Status
Not open for further replies.
hi C,
With Oshonsoft you cannot have Signed Integers, you may have to use Single Dim's
A Signed Integer Uses the Most Significant Bit as a SIGN indicator, If MSBit= 1 its considered a Negative Value, if MSBit = 0 its a Positive value.
So with a Signed Integer WORD value the range is roughly +/-32k

An Unsigned Integer WORD has the a range of 0 thru 65535
E
 
Hi E,
This is a bit too difficult for me, but would it be ok for me to make a CALC program, with questions, and work through it?

Here's the start:

Using P.45-46 of the D/S 32BIT.

Are the DIMs so far ok?
Is 'VAR1' a WORD and 'DOUBLE' a LONG?

EDIT: The CALC has been tidied a little
C
 

Attachments

  • 18LF4520 260118 1100 CALC.bas
    5 KB · Views: 270
Last edited:
Hi C,
In the 'C' examples the data TYPE is the highlighted part;
E.

void BME280_SPI::readPressure(void) {

int64_t var1, var2, p; so var1 and var2 are 64 Bit Int

int32_t adc_P = read24(BME280_REGISTER_PRESSUREDATA); adc_p is a 32 Bit Int
adc_P >>= 4;

A LONG is
Data Types.
BIT (1-bit, 0 or 1)
BYTE (1-byte integers in the range 0 to 255)
WORD (2-byte integers in the range 0 to 65,535)
LONG (4-byte integers in the range 0 to 4,294,967,295) [Option} or DOUBLE

NOTE: Any equation with a decimal point will have to be a SINGLE Type
 
Hi E,
As I'm using 32BIT on pages 45-46 is the line with 64BIT irrelevant?
Looking at the attached image, is it correct that the ones marked RED are LONGs and the ones in Blue BYTES?
C
 

Attachments

  • 32BIT DATA type.jpg
    120.2 KB · Views: 274
DOUBLE is a double precision floating point number ~ 16 digits precision.
 
DOUBLE is a double precision floating point number ~ 16 digits precision.
Hi J,
Can the equation CALC be done in the form that I'm trying?
I don't see renference to DOUBLEs in the Oshonsoft reference manual.
C.
 
Last edited:
Hi J,
Can the equasion CALC be done in the form that I'm trying?
I don't see renference to DOUBLEs in the Oshonsoft reference manual.
C.
Oshonsoft has single precision floating point numbers, ~ 6 digit precision.
You will lose some precision by using singles.
Another problem is that the word and long variables are unsigned integers.
 
Oshonsoft has single precision floating point numbers, ~ 6 digit precision.
You will lose some precision by using singles.
Another problem is that the word and long variables are unsigned integers.
Hi J,
Is it possible to make the CALC program in #403, or am I wasting my time?
C.
 
Here is Python code for BMP280 from Github
It might be easier to follow and convert to Basic.

----------------------------------------------------------------------------
# Distributed with a free-will license.

# Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
# BMP280
# This code is designed to work with the BMP280_I2CS I2C Mini Module available from ControlEverything.com.
# **broken link removed**
import smbus
import time
# Get I2C bus
bus = smbus.SMBus(1)
# BMP280 address, 0x76(118)
# Read data back from 0x88(136), 24 bytes
b1 = bus.read_i2c_block_data(0x76, 0x88, 24)

# Convert the data
# Temp coefficents

dig_T1 = b1[1] * 256 + b1[0]
dig_T2 = b1[3] * 256 + b1[2]
if dig_T2 > 32767 :
dig_T2 -= 65536​
dig_T3 = b1[5] * 256 + b1[4]
if dig_T3 > 32767 :
dig_T3 -= 65536
# Pressure coefficents
dig_P1 = b1[7] * 256 + b1[6]
dig_P2 = b1[9] * 256 + b1[8]
if dig_P2 > 32767 :
dig_P2 -= 65536​
dig_P3 = b1[11] * 256 + b1[10]
if dig_P3 > 32767 :
dig_P3 -= 65536​
dig_P4 = b1[13] * 256 + b1[12]
if dig_P4 > 32767 :
dig_P4 -= 65536​
dig_P5 = b1[15] * 256 + b1[14]
if dig_P5 > 32767 :
dig_P5 -= 65536​
dig_P6 = b1[17] * 256 + b1[16]
if dig_P6 > 32767 :
dig_P6 -= 65536​
dig_P7 = b1[19] * 256 + b1[18]
if dig_P7 > 32767 :
dig_P7 -= 65536​
dig_P8 = b1[21] * 256 + b1[20]
if dig_P8 > 32767 :
dig_P8 -= 65536​
dig_P9 = b1[23] * 256 + b1[22]
if dig_P9 > 32767 :
dig_P9 -= 65536
# BMP280 address, 0x76(118)
# Select Control measurement register, 0xF4(244)
# 0x27(39) Pressure and Temperature Oversampling rate = 1
# Normal mode
bus.write_byte_data(0x76, 0xF4, 0x27)
# BMP280 address, 0x76(118)
# Select Configuration register, 0xF5(245)
# 0xA0(00) Stand_by time = 1000 ms
bus.write_byte_data(0x76, 0xF5, 0xA0)
time.sleep(0.5)

# BMP280 address, 0x76(118)
# Read data back from 0xF7(247), 8 bytes
# Pressure MSB, Pressure LSB, Pressure xLSB, Temperature MSB, Temperature LSB
# Temperature xLSB, Humidity MSB, Humidity LSB
data = bus.read_i2c_block_data(0x76, 0xF7, 8)


# Convert pressure and temperature data to 19-bits
adc_p = ((data[0] * 65536) + (data[1] * 256) + (data[2] & 0xF0)) / 16
adc_t = ((data[3] * 65536) + (data[4] * 256) + (data[5] & 0xF0)) / 16

# Temperature offset calculations
var1 = ((adc_t) / 16384.0 - (dig_T1) / 1024.0) * (dig_T2)
var2 = (((adc_t) / 131072.0 - (dig_T1) / 8192.0) * ((adc_t)/131072.0 - (dig_T1)/8192.0)) * (dig_T3)
t_fine = (var1 + var2)
cTemp = (var1 + var2) / 5120.0
fTemp = cTemp * 1.8 + 32

# Pressure offset calculations
var1 = (t_fine / 2.0) - 64000.0
var2 = var1 * var1 * (dig_P6) / 32768.0
var2 = var2 + var1 * (dig_P5) * 2.0
var2 = (var2 / 4.0) + ((dig_P4) * 65536.0)
var1 = ((dig_P3) * var1 * var1 / 524288.0 + ( dig_P2) * var1) / 524288.0
var1 = (1.0 + var1 / 32768.0) * (dig_P1)
p = 1048576.0 - adc_p
p = (p - (var2 / 4096.0)) * 6250.0 / var1
var1 = (dig_P9) * p * p / 2147483648.0)
var2 = p * (dig_P8) / 32768.0

pressure = (p + (var1 + var2 + (dig_P7)) / 16.0) / 100
# Output data to screen
print "Temperature in Celsius : %.2f C" %cTemp
print "Temperature in Fahrenheit : %.2f F" %fTemp
print "Pressure : %.2f hPa " %pressure
--------------------------------------------------------------------

Make all variables as single, except byte arrays b(24), data(8) and SPI registers
Dig_Px - =65536 means Dig_Px = Dig_Px-65536
There are test values in the datasheet, which can be used to test the calculations.
Good luck!
 
Hi J,
I had previously searched online for likely programs, especially written in BASIC, and probably saw this one, and noticed it uses i2c, which put me off, although I'll bare it in mind, thanks.

I'm not sure which program is easier, they both look understandable, till I start writing.

I'll try all variables as SINGLEs with exceptions.

I'm always puzzled when a variable, such as VAR1 runs through a program, as they appear to change as they run through the program. I'm sure proper programmers will not be phased.
C.
 
Hi,
I've READ 2x BYTEs that make a WORD 'HB105 and LB 220'
How do I ADD them to make the WORD? Please.
EDIT: I've just remembered Eric did it in one of the earlier programs.

C
 
Last edited:
Hi,
Does this look ok?
So I can put dig_t1 into the program as a STRING.

Dim dig_t1_lb As Byte
dig_t1_lb = 220
Dim dig_t1_hb As Byte
dig_t1_hb = 105
Dim dig_t1 As Word '0x88 = 220 0x89 = 105
dig_t1.LB = dig_t1_lb
dig_t1.HB = dig_t1_hb
Dim strdig_t1 As String

strdig_t1 = #dig_t1
C.
 
hi C,
Renamed to make it clear to me.

Dim num1 As Byte
Dim num2 As Byte
Dim num3 As Word
Dim strdig As String

num1 = 220
num2 = 105

num3.LB = num1 ''''' 220
num3.HB =num2 ''' 105 * 256 = 26880

strdig_t1 = #num3 ''' 26880 + 220 = 27100



Clip from OS manual.
E

.HB,.LB,
High and low byte of a Word variable can be addressed by .HB and .LB extensions.
Individual bits can be addressed by .0, .1, ..., .14 and .15 extensions.
t is possible to make conversions between Byte and Word data types using .LB and .HB extensions or directly:
Dim x As Byte
Dim y As Word
x = y.HB
x = y.LB 'This statement is equivalent to x = y
y.HB = x
y.LB = x
y = x 'This statement will also clear the high byte of y variable

.HW,.LW,.3B,.4B,
High word (composed by bytes 3 and 2) and low word (composed by bytes 1 and 0) of a Long
(Single) variable can be addressed by .HW and .LW extensions. Byte 0 can be addressed by .LB and byte 1 by .HB extensions.
The third and the fourth byte of Long and Single variables can be addressed by .3B and .4B extensions.
Individual bits can be addressed by .0, .1, ..., .31 extensions. For example:
Dim i As Byte
Dim j As Word
Dim x As Long
i = x.LB
j = x.HW
 
No need for strings.

I have not read the whole documentation of the BMP280,
but I assume that the byte array as in the Python program can be filled from SPI data.

Define array(24) of bytes for temperature and pressure coefficients.
Define single variables for dig_T1 to dig_T3 and dig_P1 to dig_P9
read the coefficients from SPI to array b()
Calculate everything as in Python code.
Because Oshonsoft does not use signed integers we have to make some extra steps

dig_T1= b(1)×256+b(0)
dig_T2=b(3)×256+b(2)
if dig_T2 > 32767 ' if its negative
dig_T2 = dig_T2 - 65536 ' now dig_T2 is negative floating point number​

..... etc.

Edit: removed the last line in calculation.
 
Last edited:
hi jjw,
The String is required for displaying the P and T data on his 5110 Alphanumeric display.
I am not familiar with Python so I cannot help him with a Bin to ASCII conversion using Python.

The easiest method I have found using Oshonsoft is
ASCIIString = #BinValue

E
 
Hi J and E,
I am trying to make this as easy for me as possible, and firstly trying the 32BIT equasion in the BMP280 D/S. If I don't suceed, I'll re-look at Python.

I noticed that many of the components, in the equasion are fixed i,e, dig_t1. dig_t1 to dig_p9 are settings built into each module (I assume callibration) so I have READ my 1st BMP280 module for those READings. If they are applied to the equasion, I'm no mathematician, but I think it can be distilled down quite a bit. (This will need to be done for each BMP280, so perhaps not best?) I'm slowly working through it.

E, Looking at programs as in #378 I notice that for similar .LB .HB READings there is no ' * 256 = ' component in them. Which is correct, or are they different?
C.
 
Morning C;
The 256 multiplier is applied by the Basic when you use .HB

I put the 256 in as comment to show you what OSH will do with it.
Is that what you mean,?
E
 
Tx = b1×256 +b0 is the same thing as Tx.HB = b1, Tx.LB = b0
Probably .HB / .LB method is faster and uses less memory.
I will look at it.

Anyway with 32 bit calculations you need to take care of the signed 16bit variables, which Oshonsoft can't do directly.
I think the easiest way is by converting the 16 bit T1, T2 etc.
to single variables.
 
Yes, I just meant, that strings are not needed in calculations.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…