Pi

Материал из wiki.nntc.nnov.ru
Версия от 17:07, 23 февраля 2026; Vovan (обсуждение | вклад) (Raspberry Pi Zero 2 W)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к навигации Перейти к поиску

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

Pi gpio.jpg

Занять первый 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 входовыходов!

Pi-17-inouts.jpg

TP-Link MR-3020 GPIOs

gpio на этой железке

Освободить занятые модулями ядра 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