Czujniki jakości powietrza SGP40 i BME680

Pytania, kody i porady dotyczące nie tylko Bascom.
ODPOWIEDZ
elektronik
Posty: 1
Rejestracja: 20 cze 2018, 21:07

Czujniki jakości powietrza SGP40 i BME680

Post autor: elektronik » 20 maja 2025, 9:42

Witam

Czy uruchamiał ktoś czujniki jakości powietrza SGP40 lub BME680,
szukałem w Internecie przykładów ale nie ma nic w Bascomie

Pozdrawiam
Awatar użytkownika
niveasoft
Posty: 1266
Rejestracja: 17 sie 2015, 12:13
Kontakt:

Re: Czujniki jakości powietrza SGP40 i BME680

Post autor: niveasoft » 20 maja 2025, 17:34

Tych nie znam. Coś tam działałem z PMS1003
Awatar użytkownika
Karlos128@nos
Posty: 64
Rejestracja: 18 sie 2015, 13:32

Re: Czujniki jakości powietrza SGP40 i BME680

Post autor: Karlos128@nos » 07 wrz 2025, 15:18

Witaj, SGP40 to czujnik jakości powietrza (VOC) na I²C, więc w Bascomie trzeba ogarnąć komunikację I²C, inicjację i odczyt danych.

SGP40 jest trochę specyficzny, bo wymaga wysłania odpowiedniej komendy startu pomiaru (measure_raw), a potem odczytuje się dane (2 bajty + CRC).
Poniżej masz prostą inicjalizację i przykład odczytu surowej wartości z SGP40 w Bascomie. Zakładam, że masz już skonfigurowaną magistralę I²C (np. Soft I2C lub sprzętową).
Adres SGP40 na I²C: 0x59 (czyli 0xB2 do zapisu, 0xB3 do odczytu w formacie 8-bitowym)
wypróbuj ten kawałek i ewentualnie rozbuduj:
  1. $lib "i2c_twi.lbx"      ' jeśli używasz sprzętowego I2C
  2. Const Sgp40_addr = &H59 ' 7-bitowy adres SGP40
  3.  
  4. '--- Zmienna na wynik ---
  5. Dim Raw_voc As Word
  6.  
  7. '--- Bufor na dane ---
  8. Dim Buf(3) As Byte
  9.  
  10. '--- Funkcja do wysłania komendy MeasureRaw ---
  11. Sub Sgp40_measure_raw()
  12.     I2cstart
  13.     I2cwbyte Sgp40_addr * 2           ' Adres + Write (0xB2)
  14.     I2cwbyte &H26                     ' Komenda MSB
  15.     I2cwbyte &H0F                     ' Komenda LSB
  16.     I2cwbyte &H00                     ' RH MSB (wilgotność, 0 - domyślnie)
  17.     I2cwbyte &H00                     ' RH LSB
  18.     I2cwbyte &H00                     ' CRC RH
  19.     I2cwbyte &H00                     ' Temp MSB (temperatura, 0 - domyślnie)
  20.     I2cwbyte &H00                     ' Temp LSB
  21.     I2cwbyte &H00                     ' CRC Temp
  22.     I2cstop
  23. End Sub
  24.  
  25. '--- Funkcja do odczytu wyniku ---
  26. Sub Sgp40_read_raw()
  27.     Waitms 30                         ' Czas pomiaru (min. 20ms)
  28.     I2cstart
  29.     I2cwbyte Sgp40_addr * 2 + 1       ' Adres + Read (0xB3)
  30.     Buf(1) = I2crbyte(1)              ' MSB
  31.     Buf(2) = I2crbyte(1)              ' LSB
  32.     Buf(3) = I2crbyte(0)              ' CRC
  33.     I2cstop
  34.     Raw_voc = Makeint(Buf(1), Buf(2)) ' Składamy wynik
  35. End Sub
  36.  
  37. '--- Przykład użycia ---
  38. Call Sgp40_measure_raw()
  39. Call Sgp40_read_raw()
  40. Print,"Wartosc: "; Raw_voc
nie mam czujnika więc nie mam na czym wyprubować.
jak byś potrzebował to mam kody działające za to do ENS160 lib AHT21 tego moduliku walającego się po alle-drogo.
Awatar użytkownika
Karlos128@nos
Posty: 64
Rejestracja: 18 sie 2015, 13:32

Re: Czujniki jakości powietrza SGP40 i BME680

Post autor: Karlos128@nos » 07 wrz 2025, 15:27

A tu masz do wszelakiej przeróbki i modyfikacji tak z marszu do BME680, z tym że ten kawałek kodu walnął mi mój asystent AI i nie ręczę że będzie dobry ale jest za to punkt wstępu, ja tak robię od dłuższego czasu
Wyniki są surowe – do przeliczenia na °C, %RH, hPa potrzebne są stałe kalibracyjne z czujnika (to trochę więcej kodu, ale mogę dorzucić, jeśli chcesz).
Odczyt gazu (VOC) wymaga dodatkowych rejestrów i przeliczeń – na początek polecam skupić się na temp/wilgotności/ciśnieniu.
kod:
  1. '--- Adres czujnika BME680 (zmień na 0x77 jeśli masz podciągnięty SDO do VCC) ---
  2. Const BME680_ADDR = &H76
  3.  
  4. '--- Bufory ---
  5. Dim Buf(8) As Byte
  6. Dim Temp_raw As Long
  7. Dim Press_raw As Long
  8. Dim Hum_raw As Word
  9.  
  10. '--- Inicjalizacja magistrali I2C ---
  11. Config Twi = 400000
  12.  
  13. '--- Funkcja do odczytu rejestru ---
  14. Sub BME680_ReadReg(byval reg As Byte , byref val As Byte)
  15.     I2cstart
  16.     I2cwbyte BME680_ADDR * 2
  17.     I2cwbyte reg
  18.     I2cstart
  19.     I2cwbyte BME680_ADDR * 2 + 1
  20.     val = I2crbyte(0)
  21.     I2cstop
  22. End Sub
  23.  
  24. '--- Funkcja do zapisu rejestru ---
  25. Sub BME680_WriteReg(byval reg As Byte , byval val As Byte)
  26.     I2cstart
  27.     I2cwbyte BME680_ADDR * 2
  28.     I2cwbyte reg
  29.     I2cwbyte val
  30.     I2cstop
  31. End Sub
  32.  
  33. '--- Inicjalizacja BME680 ---
  34. Sub BME680_Init()
  35.     ' Soft reset
  36.     Call BME680_WriteReg(&HE0, &HB6)
  37.     Waitms 10
  38.     ' Ustawienie oversamplingu i trybu pracy
  39.     Call BME680_WriteReg(&H74, &H10)  ' Tryb sleep, osrs_t=1x
  40.     Call BME680_WriteReg(&H72, &H01)  ' osrs_h=1x
  41.     Call BME680_WriteReg(&H75, &H24)  ' osrs_p=1x, filter=2
  42.     ' Tryb forced (pojedynczy pomiar)
  43.     Call BME680_WriteReg(&H74, &H11)
  44. End Sub
  45.  
  46. '--- Odczyt danych ---
  47. Sub BME680_ReadData()
  48.     ' Odczytaj 8 bajtów od rejestru 0x1D (temp, press, hum)
  49.     I2cstart
  50.     I2cwbyte BME680_ADDR * 2
  51.     I2cwbyte &H1D
  52.     I2cstart
  53.     I2cwbyte BME680_ADDR * 2 + 1
  54.     For i = 1 To 8
  55.         If i < 8 Then
  56.             Buf(i) = I2crbyte(1)
  57.         Else
  58.             Buf(i) = I2crbyte(0)
  59.         End If
  60.     Next
  61.     I2cstop
  62.     ' Składamy surowe dane (przykładowo, uproszczone)
  63.     Press_raw = (Buf(1) * 65536) + (Buf(2) * 256) + (Buf(3) And &HF0)
  64.     Temp_raw  = (Buf(4) * 65536) + (Buf(5) * 256) + (Buf(6) And &HF0)
  65.     Hum_raw   = (Buf(7) * 256) + Buf(8)
  66. End Sub
  67.  
  68. '--- Przykład użycia ---
  69. Call BME680_Init()
  70. Waitms 100
  71. Call BME680_ReadData()
  72. Lcd "Traw:" ; Temp_raw ; "Praw:" ; Press_raw ; "Hraw:" ; Hum_raw
a tu masz :
  1. Uproszczony przelicznik (na start, do testów)
  2.  
  3. ' Założenie: Temp_raw, Press_raw, Hum_raw już odczytane
  4.  
  5. '--- Temperatura ---
  6. ' Temp_raw to 20-bitowa liczba, trzeba przesunąć o 4 bity w prawo
  7. Dim Temp_C As Single
  8. Temp_C = (Temp_raw / 16.0 - 51200) / 100
  9.  
  10. '--- Ciśnienie ---
  11. ' Press_raw to 20-bitowa liczba, przesuwamy o 4 bity w prawo
  12. Dim Press_hPa As Single
  13. Press_hPa = (Press_raw / 16.0) / 100
  14.  
  15. '--- Wilgotność ---
  16. Dim Hum_perc As Single
  17. Hum_perc = Hum_raw / 1024.0 * 100
  18.  
  19. Lcd "T:" ; Fusing(Temp_C , "#.##") ; "C"
  20. Lcd " P:" ; Fusing(Press_hPa , "#.##") ; "hPa"
  21. Lcd " H:" ; Fusing(Hum_perc , "#.##") ; "%"
ODPOWIEDZ