Pi
Raspberry Pi Zero 2 W
Подключить дисплей 480x320 SPI с тач-скрином
Шаг 1
Через Imager залить на флешку вот этот образ:
https://downloads.raspberrypi.org/raspios_oldstable_armhf/images/raspios_oldstable_armhf-2025-05-07/2025-05-06-raspios-bullseye-armhf.img.xz
, настроить подключение к Wi-Fi. Для этого в разделе bootfs флешки создать файл с содержимым:
cat << 'EOF' > wpa_supplicant.conf
country=RU
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="test"
psk="testtest143"
}
EOF
и доступ по ssh. Для этого в разделе bootfs флешки создать пустой файл:
touch ssh
И в /home/pi/.ssh/authorized_keys сразу положить открытую часть ssh ключа или подключить к системе монитор и клавиатуру и установить пароль пользователю pi.
Шаг 2
Запустить команду
sudo raspi-config
и далее выбрать разделы последовательно:
3 Interface Options Configure connections to peripherals
затем
I4 SPI Enable/disable automatic loading of SPI kernel module
потом
<Yes>
потом
<Ok>
затем
<Finish>
Потом нужно перезагрузиться:
sudo reboot
Шаг 3
git clone https://github.com/waveshare/LCD-show.git
cd LCD-show/
chmod +x LCD35-show
./LCD35-show
После перезагрузи видео будет на дисплее и тач будет работать.
Разработка на JavaFX
Ставим необходимые пакеты:
sudo apt update && sudo apt install -y openjdk-17-jdk maven libopenjfx-java libopenjfx-jni
Пакет для отключения курсора
sudo apt update && sudo apt install -y unclutter
Создаём минимально рабочий проект
Раз:
mkdir -p ~/FXApp/src/main/java/app/my
Два:
cat << 'EOF' > ~/FXApp/Makefile APP_NAME = MyApp SRC_DIR = src/main/java OUT_DIR = target/classes MAIN_CLASS = app.my.Main FX=/usr/share/java/javafx-base-11.jar:/usr/share/java/javafx-graphics-11.jar:/usr/share/java/javafx-controls-11.jar:/usr/share/java/javafx-fxml-11.jar all: compile compile: mkdir -p $(OUT_DIR) javac \ --module-path $(FX) \ --add-modules javafx.controls,javafx.fxml \ -d $(OUT_DIR) \ $(shell find $(SRC_DIR) -name "*.java") run: java \ --module-path $(FX) \ --add-modules javafx.controls,javafx.fxml \ -cp $(OUT_DIR) \ $(MAIN_CLASS) clean: rm -rf target EOF
Три:
cat << 'EOF' > ~/FXApp/src/main/java/app/my/Main.java
package app.my;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
// Создаем две большие кнопки
Button btn1 = new Button("Кнопка 1");
Button btn2 = new Button("Кнопка 2");
btn1.setPrefSize(200, 100);
btn2.setPrefSize(200, 100);
// Обработчики нажатий
btn1.setOnAction(e -> System.out.println("Нажата Кнопка 1"));
btn2.setOnAction(e -> System.out.println("Нажата Кнопка 2"));
// Размещаем кнопки горизонтально
HBox hbox = new HBox(20, btn1, btn2);
hbox.setAlignment(Pos.CENTER);
// Если нужно можно обернуть в VBox для вертикального центрирования
VBox root = new VBox(hbox);
root.setAlignment(Pos.CENTER);
// Сцена 480x320 (под экран)
Scene scene = new Scene(root, 480, 320);
primaryStage.setTitle("Минимальный JavaFX пример");
primaryStage.setScene(scene);
// Полный экран
primaryStage.setFullScreen(true);
primaryStage.setFullScreenExitHint(""); // скрыть ESC-подсказку
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
EOF
Сборка и запуск
export DISPLAY=:0
cd FXApp/
make
make run
Автоматический запуск через systemd
Раз:
cat << 'EOF' > /home/pi/FXApp/start.sh #!/bin/bash export DISPLAY=:0 export XAUTHORITY=/home/pi/.Xauthority cd /home/pi/FXApp # скрыть курсор unclutter -idle 0 -root & # отключить гашение экрана xset s off xset -dpms xset s noblank EOF chmod +x /home/pi/FXApp/start.sh
Два:
cat << 'EOF' > /etc/systemd/system/fxapp.service [Unit] Description=JavaFX App After=graphical.target [Service] User=pi Environment=DISPLAY=:0 Environment=XAUTHORITY=/home/pi/.Xauthority ExecStart=/home/pi/FXApp/start.sh Restart=always RestartSec=5 [Install] WantedBy=graphical.target EOF
Три:
sudo systemctl daemon-reload
sudo systemctl enable -now fxapp.service
Оптимизация производительности
Отключить стек bluetooth:
sudo systemctl disable bluetooth.service sudo systemctl disable hciuart.service sudo systemctl stop bluetooth
Проверить:
hciconfig
Raspberry Pi ver. 1
Схема расположения GPIO
Занять первый gpio
echo "1" > /sys/class/gpio/export
Управление первым gpio на выход
echo "1" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio1/direction echo "1" > /sys/class/gpio/gpio1/value echo "0" > /sys/class/gpio/gpio1/value
Управление первым gpio на вход
echo "1" > /sys/class/gpio/export echo "in" > /sys/class/gpio/gpio1/direction cat /sys/class/gpio/gpio1/value
Комментарий: читаем катом (или можно watch "cat /sys/class/gpio/gpio1/value") порт, подавая на него 3.3 вольта с нижней левой ноги (замыкая проводом на нужный порт).
При замыкании - в файле /sys/class/gpio/gpio1/value будет единичка, при размыкании — ноль.
Освободить первый gpio
echo "1" > /sys/class/gpio/unexport
Примечание: если gpio не освободить, то его нельзя переключить на противоположный режим и использовать
17 gpio входовыходов!
TP-Link MR-3020 GPIOs
Освободить занятые модулями ядра gpio
Для освобождения gpio контактов, занятых соответствующими модулями ядра, нужно выбросить эти подули из автозагрузки. Я это сделал так:
добавил строчки в файл /etc/rc.local перед строкой exit 0
rmmod leds_gpio rmmod gpio_button_hotplug
Скрипт
root@OpenWrt:~# cat gpio.sh
############
# settings #
############
GPIOS="29 7 0 26"
INOROUT=out
SLEEP=3s
#########################
# blink - test finction #
#########################
blink() {
echo "1" > /sys/class/gpio/gpio$1/value
sleep $SLEEP
echo "0" > /sys/class/gpio/gpio$1/value
sleep $SLEEP
blink $1
}
#################
# stop function #
#################
stop() {
for GPIO in $(echo $GPIOS)
do
echo "0" > /sys/class/gpio/gpio$GPIO/value
done
for k in $(ps | grep gpio.sh | grep -v grep | awk {'print $1 '})
do
kill $k
done
}
##################
# start finction #
##################
start() {
for GPIO in $(echo $GPIOS)
do
echo $GPIO > /sys/class/gpio/export
echo $INOROUT > /sys/class/gpio/gpio$GPIO/direction
blink $GPIO&
sleep $SLEEP
done
}
##############################
# run function after test $1 #
##############################
[ -z $1 ]||$1

