Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Осваиваем датчик BME280


Осваиваем датчик BME280

Сообщений 1 страница 30 из 30

1

Итак, приобретён BME280. Необходимо приручить его в васике. Опрос выполнен. Формулы прописаны, но вот результат пока удручает. Видимо с типом переменных это связано, но понять пока не могу.
Код не причёсан (не оптимизирован), но это вопрос последний.
Переменные описаны так.

Код:
'**************************BME280***************************************
Dim T1 As Word
Dim T1_low As Byte At T1 Overlay
Dim T1_high As Byte At T1 + 1 Overlay
Dim T2 As Integer
Dim T2_low As Byte At T2 Overlay
Dim T2_high As Byte At T2 + 1 Overlay
Dim T3 As Integer
Dim T3_low As Byte At T3 Overlay
Dim T3_high As Byte At T3 + 1 Overlay
Dim P1 As Word
Dim P1_low As Byte At P1 Overlay
Dim P1_high As Byte At P1 + 1 Overlay
Dim P2 As Integer
Dim P2_low As Byte At P2 Overlay
Dim P2_high As Byte At P2 + 1 Overlay
Dim P3 As Integer
Dim P3_low As Byte At P3 Overlay
Dim P3_high As Byte At P3 + 1 Overlay
Dim P4 As Integer
Dim P4_low As Byte At P4 Overlay
Dim P4_high As Byte At P4 + 1 Overlay
Dim P5 As Integer
Dim P5_low As Byte At P5 Overlay
Dim P5_high As Byte At P5 + 1 Overlay
Dim P6 As Integer
Dim P6_low As Byte At P6 Overlay
Dim P6_high As Byte At P6 + 1 Overlay
Dim P7 As Integer
Dim P7_low As Byte At P7 Overlay
Dim P7_high As Byte At P7 + 1 Overlay
Dim P8 As Integer
Dim P8_low As Byte At P8 Overlay
Dim P8_high As Byte At P8 + 1 Overlay
Dim P9 As Integer
Dim P9_low As Byte At P9 Overlay
Dim P9_high As Byte At P9 + 1 Overlay
Dim H1 As Byte
Dim H2 As Integer
Dim H2_low As Byte At H2 Overlay
Dim H2_high As Byte At H2 + 1 Overlay
Dim H3 As Byte
Dim H4 As Integer
Dim H4_low As Byte At H4 Overlay
Dim H4_high As Byte At H4 + 1 Overlay
Dim H5 As Integer
Dim H5_low As Byte At H5 Overlay
Dim H5_high As Byte At H5 + 1 Overlay
Dim H6 As Byte                                              '

Dim Press As Long
Dim Press_xlow As Byte At Press Overlay
Dim Press_low As Byte At Press + 1 Overlay
Dim Press_high As Byte At Press + 2 Overlay

Dim Temp As Long
Dim Temp_xlow As Byte At Temp Overlay
Dim Temp_low As Byte At Temp + 1 Overlay
Dim Temp_high As Byte At Temp + 2 Overlay

Dim Hum As Long
Dim Hum_low As Byte At Hum Overlay
Dim Hum_high As Byte At Hum + 1 Overlay

Dim P_single As Single
Dim T_single As Single
Dim H_single As Single

Dim Var1 As Single
Dim Var2 As Single
Dim T_fine As Single
Dim Temp_bme1 As Single
Dim Temp_bme2 As Single

Результаты в переменных:
P_single - давление
T_single - температура
H_single - влажность
Далее идут подпрограммы конфигурации, калибровочные данные, сырые данные и сам расчёт:

Код:
Getbme280:
   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HF7                                            ' À
   I2crepstart
   I2cwbyte &HED
   I2crbyte Press_high , Ack                                ' 
   I2crbyte Press_low , Ack                                 '
   I2crbyte Press_xlow , Ack
   I2crbyte Temp_high , Ack                                 ' 
   I2crbyte Temp_low , Ack                                  '
   I2crbyte Temp_xlow , Ack
   I2crbyte Hum_high , Ack                                  ' 
   I2crbyte Hum_low , Nack
   I2cstop
'Температура
   Var1 = T1 / 1024
   Var1 = Var1 * T2
   Temp_bme1 = Temp / 16384
   Print Temp_bme1
   Var1 = Temp_bme1 - Var1
   Temp_bme1 = T1 / 8192
   Temp_bme1 = Temp_bme1 * T3
   Temp_bme2 = Temp / 131072
   Temp_bme2 = Temp_bme2 - temp_bme1
   Temp_bme1 = T1 / 8192
   Temp_bme1 = Temp_bme1 * Temp_bme2
   Temp_bme2 = Temp / 131072
   Var2 = Temp_bme2 - Temp_bme1
   T_fine = Var1 + Var2
   T_single = T_fine / 5120
'Давление P
   Var1 = T_fine / 2
   Var1 = Var1 - 64000
   Var2 = P6 / 32768
   Temp_bme1 = Var1 * Var1
   Var2 = Var2 * Temp_bme1
   Temp_bme1 = P5 * 2
   Temp_bme1 = Temp_bme1 * Var1
   Var2 = Var2 + Temp_bme1
   Temp_bme1 = P4 * 65536
   Temp_bme2 = Var2 / 4
   Var2 = Temp_bme2 + Temp_bme1
   Temp_bme1 = Var1 * Var1
   Temp_bme1 = P3 * Temp_bme1
   Temp_bme1 = Temp_bme1 / 524288
   Temp_bme2 = P2 * Var1
   Temp_bme2 = Temp_bme2 / 524288
   Var1 = Temp_bme1 + Temp_bme2
   Var1 = Var1 / 32768
   Var1 = Var1 * P1
   Var1 = Var1 + 1
   If Var1 = 0 Then Goto Error
   P_single = 1048576 - press
   Temp_bme1 = Var2 / 4096
   Temp_bme2 = P_single - Temp_bme1
   P_single = Temp_bme2 * 6250
   P_single = P_single / Var1
   Var1 = P9 * P_single
   Var1 = Var1 * P_single
   Var1 = Var1 / 2147483648
   Var2 = P_single * P8
   Var2 = Var2 / 32768
   Temp_bme1 = Var1 + Var2
   Temp_bme1 = Temp_bme1 + P7
   Temp_bme1 = Temp_bme1 / 16
   P_single = P_single + Temp_bme1
   P_single = P_single * 0.0075006
Error:
'Влажность H
   H_single = T_fine - 76800
   Temp_bme1 = H3 / 67108864
   Temp_bme1 = Temp_bme1 * H_single
   Temp_bme1 = 1 + Temp_bme1
   Temp_bme2 = H6 / 67108864
   Temp_bme2 = Temp_bme2 * H_single
   Temp_bme2 = Temp_bme2 * Temp_bme1
   Temp_bme2 = Temp_bme2 + 1
   Temp_bme1 = H2 / 65536
   Temp_bme1 = Temp_bme1 * Temp_bme2
   Temp_bme2 = H5 / 16384
   Temp_bme2 = Temp_bme2 * H_single
   Temp_bme2 = Temp_bme2 * Temp_bme1
   Temp_bme1 = H4 * 64
   Temp_bme1 = Temp_bme1 + Temp_bme2
   H_single = Hum - Temp_bme1
   Temp_bme1 = H1 * H_single
   Temp_bme1 = Temp_bme1 / 524288
   Temp_bme1 = 1 - Temp_bme1
   H_single = H_single * Temp_bme1
   If H_single > 100 Then H_single = 100
   If H_single < 0 Then H_single = 0
Return

Ctrl_hum:
   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HF2                                            ' 
   I2cwbyte &H01                                            'osrs_h 100 oversampling *1
   I2cstop
Return

Ctrl_meas:
   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HF4                                            'osrs_t  100 oversampling *1
   I2cwbyte &H27                                            'osrs_p  100 oversampling *1
   I2cstop                                                  'Mode Normal 11
Return                                                      '  10010011

Configbme:
   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HF5                                            't_sb 000 0.5ms
   I2cwbyte &H00                                            'filter settings off 000
   I2cstop                                                  'bit 0=0 SPI disable
Return                                                      '00001100




Bme280calibratedata:
   I2cstart
   I2cwbyte &HEC
   I2cwbyte &H88                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte T1_low , Ack                                    '  &H88
   I2crbyte T1_high , Ack                                   ' &H89
   I2crbyte T2_low , Ack
   I2crbyte T2_high , Ack
   I2crbyte T3_low , Ack
   I2crbyte T3_high , Ack
   I2crbyte P1_low , Ack
   I2crbyte P1_high , Ack
   I2crbyte P2_low , Ack
   I2crbyte P2_high , Ack
   I2crbyte P3_low , Ack
   I2crbyte P3_high , Ack
   I2crbyte P4_low , Ack
   I2crbyte P4_high , Ack
   I2crbyte P5_low , Ack
   I2crbyte P5_high , Ack
   I2crbyte P3_low , Ack
   I2crbyte P3_high , Ack
   I2crbyte P4_low , Ack
   I2crbyte P4_high , Ack
   I2crbyte P5_low , Ack
   I2crbyte P5_high , Ack
   I2crbyte P6_low , Ack
   I2crbyte P6_high , Ack
   I2crbyte P7_low , Ack
   I2crbyte P7_high , Ack
   I2crbyte P8_low , Ack
   I2crbyte P8_high , Ack
   I2crbyte P9_low , Ack
   I2crbyte P9_high , Nack
   I2cstop

   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HA1                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte H1 , Nack
   I2cstop

   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HE1                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte H2_low , Ack                                    '
   I2crbyte H2_high , Nack                                  '
   I2cstop

   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HE3                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte H3 , Nack
   I2cstop

   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HE4                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte H4_high , Ack                                   '
   I2crbyte H4_low , Nack                                   '
   I2cstop

   I2cstart
   I2cwbyte &HEC
   I2cwbyte &HE5                                            ' 
   I2crepstart
   I2cwbyte &HED
   I2crbyte H5_low , Ack                                    '
   I2crbyte H5_high , Ack                                   '
   I2crbyte H6 , Nack
   I2cstop
Return

На данный момент калибровочные данные считываются (подпрограмма Bme280calibratedata:). Сырые данные и сам расчёт (подпрограмма Getbme280:).
Всё собрано на макете, поэтому Ваши предложения смогу быстро проверить.
Даташит тутСсылка
У кого какие мысли.

Отредактировано Tankor (2015-12-13 19:09:06)

+1

2

Mrshilov написал(а):

Исходник.
Оверсемплинг и фильтр выставлены на максимум, время "отдыха" - 250мс. Сотые доли с такими параметрами стоят как вкопанные при опросе 1 раз в сек.

Ух-ты, вот это подарок. Огромная благодарность.  :flag:

0

3

Уважаемый Mrshilov
Опробовал. Всё супер. Макет чешит как надо.
http://s6.uploads.ru/t/ikHN3.jpg

Отредактировано Tankor (2015-12-13 23:05:23)

0

4

Mrshilov написал(а):

Как-то 743мм маловато. Живете высоко?

г.Нижнекамск, Татарстан

0

5

Всем Доброго Здоровья!

Нужны считанные калибрационные константы датчика BME280, у кого есть данное железо, поделитесь пожалуйста.

0

6

Нужен код, чтобы их считать.

0

7

max написал(а):

Нужен код, чтобы их считать.

Нет, нужны константы с разных датчиков.

0

8

sasha_1973 написал(а):

Нет, нужны константы с разных датчиков.

Я имел ввиду, что мне нужен код, чтобы их считать. Датчик имеется в наличии.

0

9

max написал(а):

Я имел ввиду, что мне нужен код, чтобы их считать

Попробуйте этот

$map       ' Получаем карту распределения памяти
  $regfile = "m328pdef.dat"       ' Используемый контроллер - http://www.atmel.com/images/Atmel-8271- … mplete.pdf
  $crystal = 1000000       ' 1 МГц
  $framesize = 32       'размер области используемой и необходимой для преобразований
  $hwstack = 40       ' Размер аппаратного стека
  $swstack = 16       ' Размер программного стека

  $baud = 4800
  Ucsr0a.1 = 1

  Config Sda = Portc.4       ' I2C Data
  Config Scl = Portc.5       ' I2C Clock
  I2cinit

  Const Slave = &HEC       ' I2C Address (5pin=0)

  Dim Count As Byte
  Dim Temp(24) As Byte

  I2cstart
  I2cwbyte Slave
  I2cwbyte &H88

  For Count = 1 To 23
      I2crbyte Temp(count) , Ack
  Next Count

  I2crbyte Temp(24) , Nack
  I2cstop

  For Count = 1 To 23

      Print "Temp" ; Count ; " = " ; Temp(count)

  Next Count

End

Отредактировано sasha_1973 (2016-01-16 13:37:32)

0

10

Хорошо.

0

11

Mrshilov написал(а):

Тогда уж так

Хорошо. Сейчас макетку соберу и попробую. Позже отпишусь.

0

12

http://s017.radikal.ru/i416/1601/5c/e315666a25c7t.jpg

Отредактировано max (2016-01-16 16:08:39)

0

13

У меня вот такое выдаёт в железе, или не это нужно?
T1=28028
T2=26193
T3=50
P1=37652
P2=-10905
P3=3024
P4=6028
P5=43
P6=-7
P7=9900
P8=-10230
P9=4285
H1=75
H2=355
H3=0
H4=337
H5=14
H6=207

Отредактировано Tankor (2016-01-16 18:24:17)

+1

14

Tankor написал(а):

или не это нужно

Именно это, СПАСИБО!

0

15

BMP280 кто нибудь приручал в бэйсике. Поделитесь если у кого исходник есть.

0

16

Ага, Mrshilov "приручал".
Вы походу тему не читали.

-1

17

Mrshilov написал(а) Возьмите исходник из поста 2 и выкиньте все связанное с влажностью. Должно работать.

Спасибо я понял.

0

18

Исходник моего Логгера температуры заточен под Bascom_AVR_1.11.9.8. и под BMP085. Я переписал данные под ВМР280 используя исходник из поста 2, выкинул все связанное с влажностью, только Bascom_AVR_1.11.9.8 не понимает новые коды а более новый компилятор не хоче компилять старую прогу. Может у кого есть библиотека для ВМЕ280 под Bascom_AVR_1.11.9.8

0

19

Без вашего кода вам никто не поможет.

0

20

Доброе время суток.
Подскажите чтото нужно менять в коде, если датчик BMP280? (Влажность не покажет- это я понял)
Подскажите где найти код целиком (не могу сообразить как эти куски соединить в рабочий файл)

0

21

Ничего и нечего там менять. В даташите всё довольно просто описано и можно самому написать за вечер.
Думаю, что с небольшими переделками должен подойти от 180-того. Тут есть исходник в качестве "каркаса"
Сам использовал этот "каркас" для написания библиотеки. Если нужно прям срочно - могу поискать. Но там будет только "матаматика" , опрос по шине сделан не на баскоме (из-за его глюков с шиной I2C)

0

22

Подпрограмма работы с BMP280

Код:
$nocompile
'-------------------------------------------------------------------------------
' Initialization BMP280
'-------------------------------------------------------------------------------
Bmp280_init:

   Dim T1 As Word , T2 As Integer , T3 As Integer
   Dim P1 As Word , P2 As Integer , P3 As Integer
   Dim P4 As Integer , P5 As Integer , P6 As Integer
   Dim P7 As Integer , P8 As Integer , P9 As Integer
   Dim Dtemp As Dword , Dpress As Dword
   Dim Temp1 As Long , Temp2 As Long , Temp3 As Long
   Dim Press As Dword , T_mem As Long

   Temp(1) = &HF4 : Temp(2) = &H57                                              ' Temperature oversampling x16, Pressure oversampling x16, Normal mode
   I2csend Write_bmp280 , Temp(1) , 2
   Temp(1) = &HF5 : Temp(2) = &H70                                              ' Standby 250ms, Filter x16
   I2csend Write_bmp280 , Temp(1) , 2
   Temp(1) = &H88                                                               ' Read Temperature and Pressure calibration
   I2creceive Write_bmp280 , Temp(1) , 1 , 24

   T1 = Makeint(temp(1) , Temp(2))
   T2 = Makeint(temp(3) , Temp(4))
   T3 = Makeint(temp(5) , Temp(6))
   P1 = Makeint(temp(7) , Temp(8))
   P2 = Makeint(temp(9) , Temp(10))
   P3 = Makeint(temp(11) , Temp(12))
   P4 = Makeint(temp(13) , Temp(14))
   P5 = Makeint(temp(15) , Temp(16))
   P6 = Makeint(temp(17) , Temp(18))
   P7 = Makeint(temp(19) , Temp(20))
   P8 = Makeint(temp(21) , Temp(22))
   P9 = Makeint(temp(23) , Temp(24))

'-------------------------------------------------------------------------------
Return
'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
' Read data and calculate results
'-------------------------------------------------------------------------------
Bmp280_read:

 Temp(1) = &HF7                                                                 ' Data registers address
 I2creceive Write_bmp280 , Temp(1) , 1 , 6
 Dpress = Temp(1) : Shift Dpress , Left , 8
 Dpress = Dpress + Temp(2) : Shift Dpress , Left , 8
 Dpress = Dpress + Temp(3) : Shift Dpress , Right , 4
 Dtemp = Temp(4) : Shift Dtemp , Left , 8
 Dtemp = Dtemp + Temp(5) : Shift Dtemp , Left , 8
 Dtemp = Dtemp + Temp(6) : Shift Dtemp , Right , 4

 '-------------------------- Temperature

 Shift Dtemp , Right , 3 : Temp1 = Dtemp - T1 : Temp1 = Temp1 - T1
 Temp1 = Temp1 * T2 : Shift Temp1 , Right , 11 , Signed
 Shift Dtemp , Right , 1 : Temp2 = Dtemp - T1
 Temp2 = Temp2 * Temp2 : Shift Temp2 , Right , 12 , Signed
 Temp2 = Temp2 * T3 : Shift Temp2 , Right , 14 , Signed
 T_mem = Temp1 + Temp2 : Temp2 = T_mem * 5
 Temp2 = Temp2 + 128 : Shift Temp2 , Right , 8 , Signed
 Temperature = Temp2 / 100
 Var_str = Fusing(temperature , "#.#")                                          ' Округление
 Temp_bmp280 = Format(var_str , "    ")                                         ' Формат на 4 знакоместа

 '-------------------------- Pressure

 Temp1 = T_mem : Shift Temp1 , Right , 1 , Signed
 Temp1 = Temp1 - 64000
 Temp2 = Temp1 : Shift Temp2 , Right , 2 , Signed
 Temp2 = Temp2 * Temp2 : Shift Temp2 , Right , 11 , Signed
 Temp2 = Temp2 * P6
 Temp3 = Temp1 * P5 : Shift Temp3 , Left , 1
 Temp2 = Temp2 + Temp3
 Temp3 = P4 : Shift Temp3 , Left , 16
 Shift Temp2 , Right , 2 , Signed
 Temp2 = Temp2 + Temp3
 Temp3 = Temp1 * P2 : Shift Temp3 , Right , 1 , Signed
 Shift Temp1 , Right , 2 , Signed
 Temp1 = Temp1 * Temp1 : Shift Temp1 , Right , 13
 Temp1 = Temp1 * P3 : Shift Temp1 , Right , 3 , Signed
 Temp1 = Temp1 + Temp3 : Shift Temp1 , Right , 18 , Signed
 Temp1 = Temp1 + 32768
 Temp1 = Temp1 * P1 : Shift Temp1 , Right , 15 , Signed
 If Temp1 = 0 Then Goto Press_out                                               'To avoid zero division
 Press = 1048576 - Dpress : Shift Temp2 , Right , 12 , Signed
 Press = Press - Temp2 : Press = Press * 3125
 Press = Press / Temp1 : Press = Press + Press
 Temp1 = Press : Shift Temp1 , Right , 3
 Temp1 = Temp1 * Temp1 : Shift Temp1 , Right , 13
 Temp1 = Temp1 * P9 : Shift Temp1 , Right , 12 , Signed
 Temp2 = Press : Shift Temp2 , Right , 2
 Temp2 = P8 * Temp2 : Shift Temp2 , Right , 13 , Signed
 Temp1 = Temp1 + Temp2 : Temp1 = Temp1 + P7
 Shift Temp1 , Right , 4 , Signed
 Press = Press + Temp1

Press_out:

Pressure = Press * 0.0075006
Pressure_round = Pressure                                                       ' Округление до целых
Var_str = Str(pressure_round)                                                   ' Перевод в строковую переменную
Press_bmp280 = Format(var_str , "   ")                                          ' Формат на 3 знакоместа
'-------------------------------------------------------------------------------
Return
'-------------------------------------------------------------------------------


Вызов ПП из основного цикла

Код:
Gosub Bmp280_read


Определить остальные переменные и все.

+1

23

Спасибо попробую в выходные.

0

24

С новым Годом! А исходник со второго поста есть у кого? Спасибо.   Еще есть вопрос. При касании "280"-го с повышением температуры падает давление в работе с BMP 180 такого не наблюдается  !?

Отредактировано qewin (2018-01-03 21:08:35)

0

25

Вот. Последние изменения на март 2017.

+1

26

max написал(а):

Вот. Последние изменения на март 2017.

Антивирус ругается и блокирует доступ...
Можно куда-нибудь в другое место положить ?

0

27

qewin написал(а):

Еще есть вопрос.
При касании "280"-го с повышением температуры падает давление в работе с BMP 180 такого не наблюдается  !?


Наблюдается, наверное.
От себя скажу так: датчик "реагирует" на открытие дверей или окон в доме, на ветер и на перемещения. Наверное так и должно быть, физику ведь не обманешь... верно...?
Для себя сделал как: усредняем показания с датчика, допустим, с 10-ти измерений и всё работает ровно.

0

28

Nord написал(а):

Можно куда-нибудь в другое место положить ?

http://rgho.st/6qkMYFPKl

0

29

max написал(а):

Nord написал(а):Можно куда-нибудь в другое место положить ?http://rgho.st/6qkMYFPKl

Биг сенкс !  :flag:

0

30

max   Спасибо, я  нашел от Mrshilov его тестовая хорошо работает!

Я с начала пробовал по этой

Код:
'******************************************

'  BME280 Beispiel Code

'  (c) 2015 by Michael Lehmann
'  mlehmann(a)mgkulm.ch


'******************************************





'MCU config
$regfile = "m328def.dat"
$crystal = 8000000
$hwstack = 256
$swstack = 256
$framesize = 256



'I2C config
Config Sda = Portc.0
Config Scl = Portc.1


'UART config
Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
Open "com1:" For Binary As #1





'******************************************
' Einstellungen fьr den BME280 Sensor

'Bitte dazu das Datenblatt lesen

'Sensoradresse
Const Bme280_adress = &HEC

'Oversampling
Const Osrs_t = &B101
Const Osrs_p = &B101
Const Osrs_h = &B101

'Mode Register
Const Mode_reg = &B11                                       'Normal Mode

't_sb
Const T_sb = &B000                                          't_sb = 0.5ms

'IIR Filter
Const Filter = &B100                                        'Filter = 16


'******************************************




'Variablen dimensionieren
Dim Txt As String * 10

'Datenarray fьr die i2c komunikation
Dim Wert_array(24) As Byte

'Kalibrierwerte vom Sensor
Dim Dig_t1 As Word
Dim Dig_t2 As Integer
Dim Dig_t3 As Integer
Dim Dig_p1 As Word
Dim Dig_p2 As Integer
Dim Dig_p3 As Integer
Dim Dig_p4 As Integer
Dim Dig_p5 As Integer
Dim Dig_p6 As Integer
Dim Dig_p7 As Integer
Dim Dig_p8 As Integer
Dim Dig_p9 As Integer
Dim Dig_h1 As Byte
Dim Dig_h2 As Integer
Dim Dig_h3 As Byte
Dim Dig_h4 As Integer
Dim Dig_h5 As Integer
Dim Dig_h6 As Byte

'unkompensierte Sensor Werte
Dim Ut As Long
Dim Up As Long
Dim Uh As Long

'kompensierte Sensor Werte
Dim T_fine As Long
Dim P_fine As Dword
Dim H_fine As Dword
Dim Pressure_old As Dword

'SUBs und FUNCTONs declarieren
Declare Sub I2c_write(byval Device_adres As Byte , Byval Reg_adres As Byte , Byval Wert As Byte)
Declare Sub I2c_read(byval Device_adres As Byte , Byval Reg_adres As Byte , Byval Wert_count As Byte )
Declare Sub Setup_bme280()
Declare Sub Read_bme280_value()
Declare Function Temp() As Long
Declare Function Pressure_64() As Dword
Declare Function Pressure_32() As Dword
Declare Function Humidity() As Dword




'Initialisierung des BME280 Sensor
Call Setup_bme280()
'Kalibrierwerte vom Sensor lesen, Filterwerte schreiben




'*** Startup Info
Print #1 , "BME280 Test Programm"
Print #1 , "(c) 2015 by Michael Lehmann"
Print #1 , ""


'*** Kalibrierwerte anzeigen
Print #1 , "Kalibrierwerte:"
Print #1 , "Dig_t1: " ; Dig_t1
Print #1 , "Dig_t2: " ; Dig_t2
Print #1 , "Dig_t3: " ; Dig_t3
Print #1 , "Dig_p1: " ; Dig_p1
Print #1 , "Dig_p2: " ; Dig_p2
Print #1 , "Dig_p3: " ; Dig_p3
Print #1 , "Dig_p4: " ; Dig_p4
Print #1 , "Dig_p5: " ; Dig_p5
Print #1 , "Dig_p6: " ; Dig_p6
Print #1 , "Dig_p7: " ; Dig_p7
Print #1 , "Dig_p8: " ; Dig_p8
Print #1 , "Dig_p9: " ; Dig_p9
Print #1 , "Dig_h1: " ; Dig_h1
Print #1 , "Dig_h2: " ; Dig_h2
Print #1 , "Dig_h3: " ; Dig_h3
Print #1 , "Dig_h4: " ; Dig_h4
Print #1 , "Dig_h5: " ; Dig_h5
Print #1 , "Dig_h6: " ; Dig_h6
Print #1 , ""







'*** Hauptprogramm

Do


  '** BME280 auslesen
  Call Read_bme280_value()
  'List die unkompensierten Wert vom Sensor,
  'diese werden in Ut, Up, Uh abgelegt


  '** Temperatur
  T_fine = Temp()
  'Gibt die Temperatur in °C zurьck, die Auflцsung betrдgt 0.01°C
  'Der Wert 2415 entspricht 24.15°C
  Txt = str(t_fine)
  Txt = Format(txt , "00.00")
  Print #1 , "Temperatur:        " ; Txt ; "°C"


  '** Luftdruck mit 64bit Berechnung
  P_fine = Pressure_64()
  'Gibt den Luftdruck in hPa zurьck, die Auflцsung betrдgt 0.001hPa
  'Der Wert 963861 entspricht 963.861hPa
  Txt = Str(p_fine)
  Txt = Format(txt , "00.000")
  Print #1 , "Luftdruck 64bit:   " ; Txt ; "hPa"


  '** Luftdruck mit 32bit Berechnung
  P_fine = Pressure_32()
  'Gibt den Luftdruck in hPa zurьck, die Auflцsung betrдgt 0.01hPa
  'Der Wert 96386 entspricht 963.86hPa
  Txt = Str(p_fine)
  Txt = Format(txt , "00.00")
  Print #1 , "Luftdruck 32bit:   " ; Txt ; "hPa"


  '** Luftfeuchte
  H_fine = Humidity()
  'Gibt die Luftfeuchtigkeit in % zurьck, die Auflцsung betrдgt 0.001hPa
  'Der Wert 46333 entspricht 46.333%
  Txt = Str(h_fine)
  Txt = Format(txt , "00.000")
  Print #1 , "Luftfeuchtigkeit:  " ; Txt ; "%"


  Print #1 , ""

  Wait 1
Loop


End







Sub I2c_write(device_adres As Byte , Reg_adres As Byte , Wert As Byte)
  I2cstart
  I2cwbyte Device_adres
  I2cwbyte Reg_adres
  I2cwbyte Wert
  I2cstop
  Waitms 10
End Sub


Sub I2c_read(device_adres As Byte , Reg_adres As Byte , Wert_count As Byte )
  Local X As Byte
  Local Y As Byte
  Y = Wert_count - 1

  I2cstart                                                  'Start I2C
  I2cwbyte Device_adres                                     'Sende Slave Adresse
  I2cwbyte Reg_adres                                        'Register Adresse
  I2cstart
  Incr Device_adres
  I2cwbyte Device_adres                                     'sende Slave Adresse +1 fьr Lesen
  If Wert_count > 1 Then
    For X = 1 To y
      I2crbyte Wert_array(x) , Ack                          'lese Wert
    Next
  End If
  I2crbyte Wert_array(wert_count) , Nack                    'lese Wert
  I2cstop
  Waitms 10
End Sub


Sub Read_bme280_value()
  Call I2c_read(bme280_adress , &HF7 , 8 )

  'unkompensierter Druckwert
  Up = Wert_array(1)
  Shift Up , Left , 8
  Up = Up + Wert_array(2)
  Shift Up , Left , 8
  Up = Up + Wert_array(3)
  Shift Up , Right , 4

  'unkompensierter Temperaturwert
  Ut = Wert_array(4)
  Shift Ut , Left , 8
  Ut = Ut + Wert_array(5)
  Shift Ut , Left , 8
  Ut = Ut + Wert_array(6)
  Shift Ut , Right , 4

  'unkompensierter Feuchtewert
  Uh = Wert_array(7)
  Shift Uh , Left , 8
  Uh = Uh + Wert_array(8)
End Sub


Function Temp() As Long
  Local Var1 As Long
  Local Var2 As Long
  Local X As Long

  Var1 = Ut
  Shift Var1 , Right , 3 , Signed
  X = Dig_t1
  Shift X , Left , 1 , Signed
  Var1 = Var1 - X
  Var1 = Var1 * Dig_t2
  Shift Var1 , Right , 11 , Signed

  Var2 = Ut
  Shift Var2 , Right , 4 , Signed
  Var2 = Var2 - Dig_t1
  Var2 = Var2 * Var2
  Shift Var2 , Right , 12 , Signed
  Var2 = Var2 * Dig_t3
  Shift Var2 , Right , 14 , Signed

  T_fine = Var1 + Var2
  Temp = T_fine * 5
  Temp = Temp + 128
  Shift Temp , Right , 8 , Signed
End Function



Function Pressure_64() As Dword
  Local Var1 As Double
  Local Var2 As Double
  Local X As Double
  Local Y As Double
  Local Z As Double
  Local S1 As Single
  Local L1 As Long

  'var1 = t_fine - 128000
  S1 = T_fine
  Y = S1
  X = 128000
  Var1 = Y - X

  'var2 = var1 * var1 * dig_P6
  Var2 = Var1 * Var1
  S1 = Dig_p6
  X = S1
  Var2 = Var2 * X

  'var2 = var2 + ((var1*dig_P5)<<17);
  S1 = Dig_p5
  X = S1
  X = Var1 * X
  'shift x << 17
  Y = 2 ^ 17
  X = X * Y
  Var2 = Var2 + X

  'var2 = var2 + (dig_P4<<35);
  S1 = Dig_p4
  X = S1
  'shift x << 35
  Y = 2 ^ 35
  X = X * Y
  Var2 = Var2 + X

  'var1 = ((var1 * var1 * dig_P3)>>8) + ((var1 * dig_P2)<<12);
  X = Var1 * Var1
  S1 = Dig_p3
  Z = S1
  X = X * Z
  'shift x >> 8
  Y = 2 ^ 8
  X = X / Y

  S1 = Dig_p2
  Z = S1
  Y = Var1 * Z
  'shift y << 12
  Z = 2 ^ 12
  Y = Y * Z
  Var1 = X + Y

  'var1 = ((1<<47)+var1)*dig_P1>>33;
  X = &H800000000000
  X = X + Var1
  S1 = Dig_p1
  Z = S1
  Var1 = X * Z
  'shift var1 >> 33
  Y = 2 ^ 33
  Var1 = Var1 / Y

  L1 = Var1
  If L1 = 0 Then
    Pressure_64 = Pressure_old
    Exit Function
  End If

  'x = 1048576-up;
  X = 1048576
  S1 = Up
  Z = S1
  X = X - Z

  'x = (((x<<31)-var2)*3125)/var1;
  'shift x << 31
  Y = 2 ^ 31
  X = X * Y
  X = X - Var2
  Y = 3125
  X = X * Y
  X = X / Var1

  'var1 = (dig_P9 * (x>>13) * (x>>13)) >> 25;
  Z = X
  'shift z >> 13
  Y = 2 ^ 13
  Z = Z / Y
  S1 = Dig_p9
  Y = S1
  Var1 = Y * Z
  Var1 = Var1 * Z
  'shift var1 >> 25
  Y = 2 ^ 25
  Var1 = Var1 / Y

  'var2 = (dig_P8 * x) >> 19;
  S1 = Dig_p8
  Y = S1
  Var2 = Y * X
  'shift var2 >> 19
  Y = 2 ^ 19
  Var2 = Var2 / Y

  'x = ((x + var1 + var2) >> 8) + (dig_P7<<4);
  X = X + Var1
  X = X + Var2
  'shift x >> 8
  Y = 2 ^ 8
  X = X / Y
  S1 = Dig_p7
  Y = S1
  'shift Y << 4
  Z = 2 ^ 4
  Y = Y * Z
  X = X + Y

  Y = 25.6
  X = X / Y

  Pressure_64 = X
  Pressure_old = Pressure_64
End Function


Function Pressure_32() As Dword
  Local Var1 As Long
  Local Var2 As Long
  Local X As Long
  Local Y As Long
  Local Z As Dword

  Var1 = T_fine
  Shift Var1 , Right , 1 , Signed
  Var1 = Var1 - 64000

  X = Var1
  Shift X , Right , 2
  Var2 = X * X
  Shift Var2 , Right , 11 , Signed
  Var2 = Var2 * Dig_p6

  X = Var1 * Dig_p5
  Shift X , Left , 1 , Signed
  Var2 = Var2 + X

  X = Var2
  Shift X , Right , 2 , Signed
  Y = Dig_p4
  Shift Y , Left , 16 , Signed
  Var2 = X + Y

  X = Var1
  Shift X , Right , 2 , Signed
  X = X * X
  Shift X , Right , 13 , Signed
  X = X * Dig_p3
  Shift X , Right , 3 , Signed
  Y = Dig_p2 * Var1
  Shift Y , Right , 1 , Signed
  Var1 = X + Y
  Shift Var1 , Right , 18 , Signed

  Var1 = 32756 + Var1
  Var1 = Var1 * Dig_p1
  Shift Var1 , Right , 15 , Signed

  If Var1 = 0 Then
    Pressure_32 = 0
    Exit Function
  End If

  X = 1048576 - Up
  Y = Var2
  Shift Y , Right , 12 , Signed
  X = X - Y
  Pressure_32 = X * 3125

  If Pressure_32 < &H80000000 Then
    Shift Pressure_32 , Left , 1 , Signed
    Pressure_32 = Pressure_32 / Var1
  Else
    Pressure_32 = Pressure_32 / Var1
    Pressure_32 = Pressure_32 * 2
  End If

  Z = Pressure_32
  Shift Z , Right , 3 , Signed
  Z = Z * Z
  Shift Z , Right , 13 , Signed
  Z = Z * Dig_p9
  Shift Z , Right , 12 , Signed
  Var1 = Z

  Z = Pressure_32
  Shift Z , Right , 2 , Signed
  Z = Z * Dig_p8
  Shift Z , Right , 13 , Signed
  Var2 = Z

  Z = Var1 + Var2
  Z = Z + Dig_p7
  Shift Z , Right , 4 , Signed
  Pressure_32 = Pressure_32 + Z
End Function


Function Humidity() As Dword
  Local Var1 As Long
  Local X As Long
  Local Y As Long
  Local Z As Long

  Var1 = T_fine - 76800

  X = Uh
  Shift X , Left , 14 , Signed
  Y = Dig_h4
  Shift Y , Left , 20 , Signed
  X = X - Y
  Y = Dig_h5 * Var1
  X = X - Y
  X = X + 16384
  Shift X , Right , 15 , Signed

  Y = Var1 * Dig_h6
  Shift Y , Right , 10 , Signed

  Z = Var1 * Dig_h3
  Shift Z , Right , 11 , Signed
  Z = Z + 32768

  Y = Y * Z
  Shift Y , Right , 10 , Signed
  Y = Y + 2097152
  Y = Y * Dig_h2
  Y = Y + 8192
  Shift Y , Right , 14 , Signed

  Var1 = X * Y

  X = Var1
  Shift X , Right , 15 , Signed
  X = X * X
  Shift X , Right , 7 , Signed
  X = X * Dig_h1
  Shift X , Right , 4 , Signed
  Var1 = Var1 - X

  If Var1 < 0 Then
    Var1 = 0
  End If

  If Var1 > 419430400 Then
    Var1 = 419430400
  End If

  Shift Var1 , Right , 12 , Signed
  Humidity = Var1 / 1.024
End Function




Sub Setup_bme280()
  Local X As Byte

  'BME280 schreibe Filter Wert und t_sb Einstellung
  X = T_sb
  Shift X , Left , 3
  X = X + Filter
  Shift X , Left , 2
  Call I2c_write(bme280_adress , &HF5 , X)

  'BME280 schreibe OSRS_h Wert (ctrl_hum register)
  Call I2c_write(bme280_adress , &HF2 , Osrs_h)

  'BME280 schreibe OSRS_t, OSRS_p, Mode Wert (ctrl_meas register)
  X = Osrs_t
  Shift X , Left , 3
  X = X + Osrs_p
  Shift X , Left , 2
  X = X + Mode_reg

  Call I2c_write(bme280_adress , &HF4 , X)

  'BME280 lese Kalibrierwerte
  Call I2c_read(bme280_adress , &H88 , 24 )

  Dig_t1 = Wert_array(2)
  Shift Dig_t1 , Left , 8
  Dig_t1 = Dig_t1 + Wert_array(1)

  Dig_t2 = Wert_array(4)
  Shift Dig_t2 , Left , 8
  Dig_t2 = Dig_t2 + Wert_array(3)

  Dig_t3 = Wert_array(6)
  Shift Dig_t3 , Left , 8
  Dig_t3 = Dig_t3 + Wert_array(5)

  Dig_p1 = Wert_array(8)
  Shift Dig_p1 , Left , 8
  Dig_p1 = Dig_p1 + Wert_array(7)

  Dig_p2 = Wert_array(10)
  Shift Dig_p2 , Left , 8
  Dig_p2 = Dig_p2 + Wert_array(9)

  Dig_p3 = Wert_array(12)
  Shift Dig_p3 , Left , 8
  Dig_p3 = Dig_p3 + Wert_array(11)

  Dig_p4 = Wert_array(14)
  Shift Dig_p4 , Left , 8
  Dig_p4 = Dig_p4 + Wert_array(13)

  Dig_p5 = Wert_array(16)
  Shift Dig_p5 , Left , 8
  Dig_p5 = Dig_p5 + Wert_array(15)

  Dig_p6 = Wert_array(18)
  Shift Dig_p6 , Left , 8
  Dig_p6 = Dig_p6 + Wert_array(17)

  Dig_p7 = Wert_array(20)
  Shift Dig_p7 , Left , 8
  Dig_p7 = Dig_p7 + Wert_array(19)

  Dig_p8 = Wert_array(22)
  Shift Dig_p8 , Left , 8
  Dig_p8 = Dig_p8 + Wert_array(21)

  Dig_p9 = Wert_array(24)
  Shift Dig_p9 , Left , 8
  Dig_p9 = Dig_p9 + Wert_array(23)

  Call I2c_read(bme280_adress , &HA1 , 1 )

  Dig_h1 = Wert_array(1)

  Call I2c_read(bme280_adress , &HE1 , 8 )

  Dig_h2 = Wert_array(2)
  Shift Dig_h2 , Left , 8
  Dig_h2 = Dig_h2 + Wert_array(1)

  Dig_h3 = Wert_array(3)

  Dig_h4 = Wert_array(4)
  Shift Dig_h4 , Left , 4
  X = Wert_array(5)
  Shift Dig_h4 , Left , 4
  Shift Dig_h4 , Right , 4
  Dig_h4 = Dig_h4 + X

  Dig_h5 = Wert_array(6)
  Shift Dig_h5 , Left , 4
  X = Wert_array(5)
  Shift Dig_h5 , Right , 4
  Dig_h5 = Dig_h5 + X

  Dig_h6 = Wert_array(7)
End Sub

Отредактировано qewin (2018-01-05 14:12:54)

0


Вы здесь » Программирование ATMEL в BASCOM. » Вопросы - ответы » Осваиваем датчик BME280