W tym poście chciałbym kontynuować obsługę termometru DS18B20 na Raspberry Pi z użyciem systemu Yocto.
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:
- RPI_EXTRA_CONFIG = ' \n \
- dtoverlay=w1-gpio \n \
- '
Powyższe ustawienie uruchamia standardową obsługę interfejsu 1-Wire. Czujniki należy w tym przypadku podłączyć pod pin 4.
- RPI_EXTRA_CONFIG = ' \n \
- dtoverlay=w1-gpio,pullup=1,gpiopin=22 \n \
- '
Powyżej wprowadzamy dodatkowe ustawienia do pinu zmieniając pin 4 na pin 22.
Cały plik local.conf wygląda następująco:
- BBMASK = "meta-networking/recipes-kernel/wireguard"
- LICENSE_FLAGS_WHITELIST = "commercial"
- DISTRO_FEATURES = "ext2 opengl usbhost ${DISTRO_FEATURES_LIBC}"
- DISTRO_FEATURES_BACKFILL_CONSIDERED += "pulseaudio"
- PREFERRED_PROVIDER_jpeg = "libjpeg-turbo"
- PREFERRED_PROVIDER_jpeg-native = "libjpeg-turbo-native"
- PREFERRED_PROVIDER_udev = "eudev"
- VIRTUAL-RUNTIME_init_manager = "sysvinit"
- MACHINE_FEATURES_remove = "apm"
- IMAGE_FSTYPES = "tar.xz"
- MACHINE = "raspberrypi3"
- KERNEL_IMAGETYPE = "zImage"
- WIREGUARD_COMPAT = "1"
- DISABLE_VC4GRAPHICS = "1"
- DISABLE_OVERSCAN = "1"
- ENABLE_UART = "1"
- ENABLE_RPI3_SERIAL_CONSOLE = "1"
- SERIAL_CONSOLES = "115200;ttyAMA0"
- ENABLE_SPI_BUS = "1"
- ENABLE_I2C = "1"
- # SERIAL_CONSOLES_forcevariable = ""
- # default is still 4.19, uncomment the following for 5.4
- # PREFERRED_VERSION_linux-raspberrypi = "5.4.%"
- # DL_DIR = "/src/oe"
- # SSTATE_DIR = "/oe6/rpi/sstate-cache"
- # TMPDIR = "/oe6/rpi/tmp-dunfell"
- DISTRO = "poky"
- PACKAGE_CLASSES = "package_ipk"
- # i686 or x86_64
- SDKMACHINE = "x86_64"
- # for no root passwd uncomment the following and comment the two extra user lines
- #EXTRA_IMAGE_FEATURES = "debug-tweaks"
- # for a root passwd, change jumpnowtek below to your password
- INHERIT += "extrausers"
- EXTRA_USERS_PARAMS = "usermod -P dev dev; "
- # this will force root to change password on first login
- INHERIT += "chageusers"
- CHAGE_USERS_PARAMS = "chage -d0 root; "
- USER_CLASSES = "image-mklibs image-prelink"
- PATCHRESOLVE = "noop"
- RM_OLD_IMAGE = "1"
- INHERIT += "rm_work"
- CONF_VERSION = "1"
- RPI_EXTRA_CONFIG = ' \n \
- dtoverlay=w1-gpio,pullup=1,gpiopin=22 \n \
- '
W celu odczytania danych dla czujnika należy przejść do odpowiedniej lokalizacji i odczytać wartość parametru za pomocą konsoli:
- ls /sys/bus/w1/devices #wyswietlenie dostępnych urządzeń
- 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.
- import glob
- #Convert Celsius to Fahrenheit:
- def CelsiusToFahrenheit(cel):
- return ((cel * 9.0/5.0) + 32.0)
- #Convert Fahrenheit to Celsius:
- def FahrenheitToCelsius(fah):
- return ((fah - 32) * 5.0/9.0)
- #Convert Celsius to Kelvin:
- def CelsiusToKelvin(cel):
- return (cel + 273.15)
- #Search for connected DS18B20
- def find_devices():
- return glob.glob('/sys/bus/w1/devices/28-*')
- #Read temperature for device
- def read_temp(path):
- lines = []
- with open(path + '/w1_slave') as f:
- lines = f.readlines()
- #Not all lines has been readed
- if len(lines) != 2:
- return False, 0
- #Device return CRC Error
- if lines[0].find('YES') == -1:
- return False, 0
- d = lines[1].strip().split('=')
- #two strings in array
- if len(d) != 2:
- return False, 0
- celTemp = int(d[1])
- #return operation status, readed temperature
- return True, celTemp
- if __name__ == '__main__':
- #Get connected devices
- devices = find_devices()
- #Print data from all connected devices
- for device in devices:
- print('Device Data Loc - ' + device)
- valid, raw = read_temp(device)
- if valid:
- cel = raw / 1000.0
- far = CelsiusToFahrenheit(cel)
- kel = CelsiusToKelvin(cel)
- print('%i [RAW] - %0.2f [F] - %0.2f [K] - %0.3f [C]' % (raw, far, kel, cel))