В мире технологий Raspberry Pi 5 стал незаменимым помощником для различных проектов, от автоматизации до создания цифровых устройств. Он часто используется в качестве домашнего сервера, обеспечивая доступ к файлам, медиаконтенту и даже удаленное управление. В этой статье мы рассмотрим, как подключить символьный LCD-дисплей к Raspberry Pi 5 и использовать его для отображения в реальном времени загруженности процессора, оперативной памяти и температуры процессора. Это позволит удобно следить за её состоянием без необходимости подключать монитор или использовать SSH-соединение.
Подключение дисплея
Чтобы сэкономить пины GPIO и упростить подключение других устройств, мы выбрали модуль LCD с I2C интерфейсом. Подключение очень простое: пины SDA и SCL модуля LCD подключаем к соответствующим пинам на плате Raspberry Pi.
Модуль LCD | Raspberry Pi 5 |
---|---|
VCC | 5V |
GND | GND |
SDA | GPIO3 (SDA) |
SCL | GPIO5 (SCL) |
Подготовка Raspberry Pi 5
Да, для использования интерфейса I2C на Raspberry Pi сначала необходимо настроить его:
- Откройте терминал на Raspberry Pi или подключитесь к нему по SSH.
- Введите команду
sudo raspi-config
. - Используйте стрелки на клавиатуре для навигации в меню. Выберите “Interfacing Options” (Опции интерфейса) и нажмите Enter.
- Затем выберите “I2C” и нажмите Enter.
- Вам будет предложено включить I2C. Выберите “Yes” (Да) и нажмите Enter.
- После завершения процесса выберите “Finish” (Завершить) и перезагрузите Raspberry Pi для применения изменений.
Далее нам необходимо установить библиотеки для работы с I2C:
1 2 |
sudo apt update sudo apt install -y i2c-tools python-smbussudo gpiozero |
Чтобы избежать использования sudo при каждом обращении к I2C, добавьте вашего пользователя в группу i2c:
1 |
sudo adduser <ваше_имя_пользователя> i2c |
Теперь нужно отредактировать файл “/etc/modprobe.d/raspi-blacklist.conf“, чтобы малины при загрузку также загружала драйвер I2C:
1 |
sudo nano /etc/modprobe.d/raspi-blacklist.conf |
Найдите строку blacklist spi-bcm2708blacklist i2c-bcm2708
и закомментируйте (#).
Осталось перезагрузить Raspberry Pi, чтобы применить изменения:
1 |
sudo reboot |
Программирование Raspberry Pi 5
Для начала импортируем необходимые библиотеки:
1 2 3 4 |
import smbus import psutil from time import * from gpiozero import CPUTemperature |
Далее создадим класс, в котором опишем функции для управления шиной I2C:
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class i2c_device: def __init__(self, addr, port=1): self.addr = addr self.bus = smbus.SMBus(port) # Запись одной команды def write_cmd(self, cmd): self.bus.write_byte(self.addr, cmd) sleep(0.0001) # Запись команды и аргумента def write_cmd_arg(self, cmd, data): self.bus.write_byte_data(self.addr, cmd, data) sleep(0.0001) # Запись блока данных def write_block_data(self, cmd, data): self.bus.write_block_data(self.addr, cmd, data) sleep(0.0001) # Чтение одного байта def read(self): return self.bus.read_byte(self.addr) # Чтение данных def read_data(self, cmd): return self.bus.read_byte_data(self.addr, cmd) # Чтение блока данных def read_block_data(self, cmd): return self.bus.read_block_data(self.addr, cmd) |
Определим константы для команд дисплея:
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# Адрес LCD ADDRESS = 0x27 # команды LCD_CLEARDISPLAY = 0x01 LCD_RETURNHOME = 0x02 LCD_ENTRYMODESET = 0x04 LCD_DISPLAYCONTROL = 0x08 LCD_CURSORSHIFT = 0x10 LCD_FUNCTIONSET = 0x20 LCD_SETCGRAMADDR = 0x40 LCD_SETDDRAMADDR = 0x80 # флаги для режима ввода LCD_ENTRYRIGHT = 0x00 LCD_ENTRYLEFT = 0x02 LCD_ENTRYSHIFTINCREMENT = 0x01 LCD_ENTRYSHIFTDECREMENT = 0x00 # флаги для управления дисплеем LCD_DISPLAYON = 0x04 LCD_DISPLAYOFF = 0x00 LCD_CURSORON = 0x02 LCD_CURSOROFF = 0x00 LCD_BLINKON = 0x01 LCD_BLINKOFF = 0x00 # флаги для сдвига дисплея/курсора LCD_DISPLAYMOVE = 0x08 LCD_CURSORMOVE = 0x00 LCD_MOVERIGHT = 0x04 LCD_MOVELEFT = 0x00 # флаги для установки функций LCD_8BITMODE = 0x10 LCD_4BITMODE = 0x00 LCD_2LINE = 0x08 LCD_1LINE = 0x00 LCD_5x10DOTS = 0x04 LCD_5x8DOTS = 0x00 # флаги для управления подсветкой LCD_BACKLIGHT = 0x08 LCD_NOBACKLIGHT = 0x00 En = 0b00000100 # Бит Enable Rw = 0b00000010 # Бит Чтение/Запись Rs = 0b00000001 # Бит выбора регистра |
Далее создадим класс lcd_driver, который будет содержать все необходимые функции для управления дисплеем:
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
class lcd_driver: # инициализирует объекты и lcd def __init__(self): self.device = i2c_lib.i2c_device(ADDRESS) self.write(0x03) self.write(0x03) self.write(0x03) self.write(0x02) self.write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE) self.write(LCD_DISPLAYCONTROL | LCD_DISPLAYON) self.write(LCD_CLEARDISPLAY) self.write(LCD_ENTRYMODESET | LCD_ENTRYLEFT) sleep(0.2) # переключает EN для установки команды def strobe(self, data): self.device.write_cmd(data | En | LCD_BACKLIGHT) sleep(.0005) self.device.write_cmd(((data & ~En) | LCD_BACKLIGHT)) sleep(.0001) def write_four_bits(self, data): self.device.write_cmd(data | LCD_BACKLIGHT) self.strobe(data) # запись команды в lcd def write(self, cmd, mode=0): self.write_four_bits(mode | (cmd & 0xF0)) self.write_four_bits(mode | ((cmd << 4) & 0xF0)) # функция вывода строки def display_string(self, string, line): if line == 1: self.write(0x80) if line == 2: self.write(0xC0) if line == 3: self.write(0x94) if line == 4: self.write(0xD4) for char in string: self.write(ord(char), Rs) # очистка lcd и установка в начальное положение def lcd_clear(self): self.write(LCD_CLEARDISPLAY) self.write(LCD_RETURNHOME) |
И наконец создадим точку входа, откуда будет начинаться наша программ и будем выводить данные на дисплей:
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
if __name__ == '__main': main() def main(): my_lcd = lcd_driver() # Инициализируем дисплей while True: # Получаем загруженность процессора cpu_usage = psutil.cpu_percent() # Запрашиваем температуру памяти cpu = CPUTemperature() cpu_temp = cpu.temperature # Получаем загруженность памяти mem_info = psutil.virtual_memory() mem_usage = (mem_info.used / mem_info.total) * 100 # Формируем строки, которые будем выводить line_one = 'CPU: ' + str(cpu_usage) + '% ,' + 'T: ' + str(cpu_temp) ' deg' line_two = 'MEM: ' + str(mem_usage) + '% ,' # Выводи информацию на дисплей my_lcd.clear() my_lcd.display_string(line_one, 1) my_lcd.display_string(line_two, 2) # Добавляем задержку, чтобы не перегружать процессор sleep(1) |
Программа готова, теперь, чтобы её запустить, введите следующую команду:
1 |
python your_script_name.py |
Создание системного сервиса
Сейчас для запуска скрипта после каждого включения Raspberry Pi требуется ручное выполнение команды в терминале. Однако такой подход не очень удобен. Было бы лучше, если бы скрипт автоматически запускался при загрузке системы. Это можно достичь путем создания службы Systemd, которая автоматически запускает нашу программу.
Создайте новый файл в папке “/etc/systemd/system/” и назовите его, например, lcd_monitor.service. Далее отредактируйте его, вставив следующий код:
1 2 3 4 5 6 7 8 9 10 11 |
[Unit] Description=LCD monitor script [Service] ExecStart=/usr/bin/python3 /path/to/your_script_name.py Restart=always User=pi Group=pi [Install] WantedBy=multi-user.target |
Замените /path/to/your_script_name.py
на путь до вашего скрипта.
Сервис создан, осталось его активировать:
1 2 |
sudo systemctl enable lcd_monitor.service sudo systemctl start lcd_monitor.service |
Всё готово, теперь сервис будет автоматически запускаться при включении Raspberry Pi, и вы сможете легко и удобно мониторить загруженность вашей системы.