czwartek, 5 listopada 2020

Raspberry pi - DS18B20 Yocto

W tym poście chciałbym kontynuować obsługę termometru DS18B20 na Raspberry Pi z użyciem systemu Yocto.

Znalezione obrazy dla zapytania raspberry pi 3

Yocto:


Tutaj system generowany jest standardowo. Zmiany należy wykonać w pliku local.conf. Gdzie przed generacją informujemy system żeby wykorzystywał wbudowany sterownik występujący już w obsłudze systemu.

W linuxie obsługę interfejsu 1-wire zajmuje się sterownik w1-gpio. Do którego podłączony jest sterownik urządzeń czujników temperatury w1-therm.

Wobec tego należy wprowadzić odpowiednie instrukcję we wspomnianym pliku tak aby był on poprawnie rozpoznawany.

Podstawowe ustawienia wyglądają następująco:

  1. RPI_EXTRA_CONFIG = ' \n \
  2. dtoverlay=w1-gpio \n \
  3. '

Powyższe ustawienie uruchamia standardową obsługę interfejsu 1-Wire. Czujniki należy w tym przypadku podłączyć pod pin 4. 

  1. RPI_EXTRA_CONFIG = ' \n \
  2. dtoverlay=w1-gpio,pullup=1,gpiopin=22 \n \
  3. '

Powyżej wprowadzamy dodatkowe ustawienia do pinu zmieniając pin 4 na pin 22.

Cały plik local.conf wygląda następująco:

  1. BBMASK = "meta-networking/recipes-kernel/wireguard"
  2.  
  3. LICENSE_FLAGS_WHITELIST = "commercial"
  4.  
  5. DISTRO_FEATURES = "ext2 opengl usbhost ${DISTRO_FEATURES_LIBC}"
  6.  
  7. DISTRO_FEATURES_BACKFILL_CONSIDERED += "pulseaudio"
  8.  
  9. PREFERRED_PROVIDER_jpeg = "libjpeg-turbo"
  10. PREFERRED_PROVIDER_jpeg-native = "libjpeg-turbo-native"
  11.  
  12. PREFERRED_PROVIDER_udev = "eudev"
  13. VIRTUAL-RUNTIME_init_manager = "sysvinit"
  14.  
  15. MACHINE_FEATURES_remove = "apm"
  16.  
  17. IMAGE_FSTYPES = "tar.xz"
  18.  
  19. MACHINE = "raspberrypi3"
  20.  
  21. KERNEL_IMAGETYPE = "zImage"
  22.  
  23. WIREGUARD_COMPAT = "1"
  24.  
  25. DISABLE_VC4GRAPHICS = "1"
  26. DISABLE_OVERSCAN = "1"
  27. ENABLE_UART = "1"
  28. ENABLE_RPI3_SERIAL_CONSOLE = "1"
  29. SERIAL_CONSOLES = "115200;ttyAMA0"
  30. ENABLE_SPI_BUS = "1"
  31. ENABLE_I2C = "1"
  32. # SERIAL_CONSOLES_forcevariable = ""
  33.  
  34. # default is still 4.19, uncomment the following for 5.4
  35. # PREFERRED_VERSION_linux-raspberrypi = "5.4.%"
  36.  
  37. # DL_DIR = "/src/oe"
  38. # SSTATE_DIR = "/oe6/rpi/sstate-cache"
  39. # TMPDIR = "/oe6/rpi/tmp-dunfell"
  40.  
  41. DISTRO = "poky"
  42. PACKAGE_CLASSES = "package_ipk"
  43.  
  44. # i686 or x86_64
  45. SDKMACHINE = "x86_64"
  46.  
  47. # for no root passwd uncomment the following and comment the two extra user lines
  48. #EXTRA_IMAGE_FEATURES = "debug-tweaks"
  49.  
  50. # for a root passwd, change jumpnowtek below to your password
  51. INHERIT += "extrausers"
  52. EXTRA_USERS_PARAMS = "usermod -P dev dev; "
  53.  
  54. # this will force root to change password on first login
  55. INHERIT += "chageusers"
  56. CHAGE_USERS_PARAMS = "chage -d0 root; "
  57.  
  58. USER_CLASSES = "image-mklibs image-prelink"
  59. PATCHRESOLVE = "noop"
  60. RM_OLD_IMAGE = "1"
  61. INHERIT += "rm_work"
  62. CONF_VERSION = "1"
  63.  
  64. RPI_EXTRA_CONFIG = ' \n \
  65. dtoverlay=w1-gpio,pullup=1,gpiopin=22 \n \
  66. '

W celu odczytania danych dla czujnika należy przejść do odpowiedniej lokalizacji i odczytać wartość parametru za pomocą konsoli:

  1. ls /sys/bus/w1/devices #wyswietlenie dostępnych urządzeń
  2. cat /sys/bus/w1/devices/28-0000059373c9/w1_slave    #wyswietlenie danych z czujnika

Lub wykorzystać skrypt opisany we wcześniejszej części korzystający z biblioteki glob i pobierający parametry dla czujnika z pliku.

  1. import glob
  2.  
  3. #Convert Celsius to Fahrenheit:
  4. def CelsiusToFahrenheit(cel):
  5.     return ((cel * 9.0/5.0) + 32.0)
  6.  
  7. #Convert Fahrenheit to Celsius:
  8. def FahrenheitToCelsius(fah):
  9.     return ((fah - 32) * 5.0/9.0)
  10.  
  11. #Convert Celsius to Kelvin:
  12. def CelsiusToKelvin(cel):
  13.     return (cel + 273.15)
  14.  
  15. #Search for connected DS18B20
  16. def find_devices():
  17.     return glob.glob('/sys/bus/w1/devices/28-*')
  18.  
  19. #Read temperature for device
  20. def read_temp(path):
  21.     lines = []
  22.     with open(path + '/w1_slave') as f:
  23.         lines = f.readlines()
  24.     #Not all lines has been readed
  25.     if len(lines) != 2:
  26.         return False, 0
  27.  
  28.     #Device return CRC Error
  29.     if lines[0].find('YES') == -1:
  30.         return False, 0
  31.  
  32.     d = lines[1].strip().split('=')
  33.  
  34.     #two strings in array
  35.     if len(d) != 2:
  36.         return False, 0
  37.  
  38.     celTemp = int(d[1])
  39.     #return operation status, readed temperature
  40.     return True, celTemp
  41.  
  42. if __name__ == '__main__':
  43.     #Get connected devices
  44.     devices = find_devices()
  45.  
  46.     #Print data from all connected devices
  47.     for device in devices:
  48.         print('Device Data Loc - ' + device)
  49.         valid, raw = read_temp(device)
  50.         if valid:
  51.             cel = raw / 1000.0
  52.             far = CelsiusToFahrenheit(cel)
  53.             kel = CelsiusToKelvin(cel)
  54.             print('%i [RAW] - %0.2f [F] - %0.2f [K] - %0.3f [C]' % (raw, far, kel,  cel))