Pi: различия между версиями
Vovan (обсуждение | вклад) (→Управление первым gpio на вход) |
Vovan (обсуждение | вклад) (→Raspberry Pi Zero 2 W) |
||
| (не показано 45 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
| − | =Raspberry 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 флешки создать файл с содержимым: | ||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | и доступ по 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 | ||
| + | |||
| + | Два: | ||
| + | |||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | Три: | ||
| + | |||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | ===Сборка и запуск=== | ||
| + | |||
| + | export DISPLAY=:0 | ||
| + | |||
| + | cd FXApp/ | ||
| + | |||
| + | make | ||
| + | |||
| + | make run | ||
| + | |||
| + | ===Автоматический запуск через systemd=== | ||
| + | |||
| + | |||
| + | Раз: | ||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | Два: | ||
| + | |||
| + | <pre> | ||
| + | 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 | ||
| + | </pre> | ||
| + | |||
| + | |||
| + | Три: | ||
| + | |||
| + | 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== | ||
[[Файл:Pi_gpio.jpg]] | [[Файл:Pi_gpio.jpg]] | ||
| Строка 26: | Строка 283: | ||
==Освободить первый gpio== | ==Освободить первый gpio== | ||
echo "1" > /sys/class/gpio/unexport | echo "1" > /sys/class/gpio/unexport | ||
| + | |||
| + | Примечание: если gpio не освободить, то его нельзя переключить на противоположный режим и использовать | ||
==17 gpio входовыходов!== | ==17 gpio входовыходов!== | ||
[[Файл:pi-17-inouts.jpg]] | [[Файл:pi-17-inouts.jpg]] | ||
| + | |||
| + | =TP-Link MR-3020 GPIOs= | ||
| + | |||
| + | [http://wiki.openwrt.org/ru/toh/tp-link/tl-mr3020#gpios gpio на этой железке] | ||
| + | |||
| + | ==Освободить занятые модулями ядра gpio== | ||
| + | Для освобождения gpio контактов, занятых соответствующими модулями ядра, нужно выбросить эти подули из автозагрузки. Я это сделал так: | ||
| + | |||
| + | добавил строчки в файл /etc/rc.local перед строкой exit 0 | ||
| + | |||
| + | rmmod leds_gpio | ||
| + | rmmod gpio_button_hotplug | ||
| + | |||
| + | ==Скрипт== | ||
| + | <pre> | ||
| + | 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 | ||
| + | |||
| + | </pre> | ||
Текущая версия на 17:07, 23 февраля 2026
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

