From 6ca0deda2c74cd20b7d71e48f106f47618a3f774 Mon Sep 17 00:00:00 2001 From: gsd Date: Mon, 10 Nov 2025 21:33:37 +0300 Subject: [PATCH] init --- pipboyIO/config.sh | 117 +++++++++++++++++++++++++++++++++++++++ pipboyIO/pipboy-setup.sh | 84 ++++++++++++++++++++++++++++ pipboyIO/pipboyIO.ino | 32 +++++++++++ pipboyIO/serialTest.py | 64 +++++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 pipboyIO/config.sh create mode 100644 pipboyIO/pipboy-setup.sh create mode 100644 pipboyIO/pipboyIO.ino create mode 100644 pipboyIO/serialTest.py diff --git a/pipboyIO/config.sh b/pipboyIO/config.sh new file mode 100644 index 0000000..49a619d --- /dev/null +++ b/pipboyIO/config.sh @@ -0,0 +1,117 @@ +# Check if running as root +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root. Use sudo ./setup_tft.sh" + exit 1 +fi + +# Define the configuration file path +CONFIG_FILE="/boot/firmware/config.txt" +if [ ! -f "$CONFIG_FILE" ]; then + CONFIG_FILE="/boot/config.txt" +fi + +update_config() { + local key=$1 + local value=$2 + + # Check if the line already exists + if grep -q "^$key" "$CONFIG_FILE"; then + # Remove any preceding # and update value if necessary + sed -i "s/^#$key/$key/" "$CONFIG_FILE" + if [ -n "$value" ]; then + sed -i "s|^$key.*|$key=$value|" "$CONFIG_FILE" + fi + else + # Add the line if it doesn't exist + if [ -z "$value" ]; then + echo "$key" >> "$CONFIG_FILE" + else + echo "$key=$value" >> "$CONFIG_FILE" + fi + fi +} + +remove_duplicates() { + local file=$1 + # Retain line breaks and remove duplicate lines + awk '!seen[$0]++' "$file" > "${file}.tmp" + mv "${file}.tmp" "$file" +} + +# Comment the line max_framebuffers=2 if it exists +if grep -q "^max_framebuffers=2" "$CONFIG_FILE"; then + sed -i "s|^max_framebuffers=2|#max_framebuffers=2 (line commented for TFT ILI9488 installation on $(date +%m/%d/%Y))|" "$CONFIG_FILE" +fi + +# Comment the dtoverlay=vc4-kms-v3d line +sed -i "s|^dtoverlay=vc4-kms-v3d|#dtoverlay=vc4-kms-v3d (line commented for TFT ILI9488 installation on $(date +%m/%d/%Y))|" "$CONFIG_FILE" + +# Add required configuration lines +echo "#Modifications for ILI9488 installation implemented by the script on $(date +%m/%d/%Y)" >> "$CONFIG_FILE" +update_config "dtoverlay" "spi0-0cs" +update_config "dtparam" "spi=on" +update_config "hdmi_force_hotplug" "1" +update_config "hdmi_cvt" "480 320 60 1 0 0 0" +update_config "hdmi_group" "2" +update_config "hdmi_mode" "87" +update_config "framebuffer_width" "480" +update_config "framebuffer_height" "320" +update_config "dtoverlay" "fbtft_device,name=ili9488,rotate=0,fps=30,speed=16000000" +update_config "dtparam" "dc_pin=22" +update_config "dtparam" "reset_pin=11" +update_config "gpu_mem" "128" +echo "# Utilized for TFT ILI9488 setup script by AdamoMD" >> "$CONFIG_FILE" +echo "# https://github.com/adamomd/4inchILI9488RpiScript/" >> "$CONFIG_FILE" +echo "# Feel free to send feedback and suggestions." >> "$CONFIG_FILE" + +# Remove duplicates in config.txt +echo "Removing duplicate lines in config.txt..." +remove_duplicates "$CONFIG_FILE" + +# Configure sudoers for fbcp-ili9341 +echo "Setting permissions in sudoers..." +VISUDO_FILE="/etc/sudoers.d/fbcp-ili9341" +if [ ! -f "$VISUDO_FILE" ]; then + echo "ALL ALL=(ALL) NOPASSWD: /usr/local/bin/fbcp-ili9341" > "$VISUDO_FILE" + chmod 440 "$VISUDO_FILE" +fi + +# Set binary permissions +echo "Configuring permissions for fbcp-ili9341..." +chmod u+s /usr/local/bin/fbcp-ili9341 + +# Configure rc.local to start fbcp-ili9341 +echo "Configuring /etc/rc.local..." +RC_LOCAL="/etc/rc.local" +if [ ! -f "$RC_LOCAL" ]; then + cat < "$RC_LOCAL" +#!/bin/bash +# rc.local +# This script is executed at the end of each multi-user runlevel. + +# Start fbcp-ili9341 +/usr/local/bin/fbcp-ili9341 >> /var/log/fbcp-ili9341.log 2>&1 & + +exit 0 +EOT + chmod +x "$RC_LOCAL" +else + if ! grep -q "fbcp-ili9341" "$RC_LOCAL"; then + sed -i '/exit 0/i \\n# Start fbcp-ili9341\n/usr/local/bin/fbcp-ili9341 >> /var/log/fbcp-ili9341.log 2>&1 &' "$RC_LOCAL" + fi +fi + +# Remove duplicates in rc.local +echo "Removing duplicate lines in rc.local..." +remove_duplicates "$RC_LOCAL" + +# Enable and start rc.local service +echo "Enabling rc.local service..." +sudo chmod +x /etc/rc.local +sudo systemctl enable rc-local +sudo systemctl start rc-local + +# Finish and force reboot +echo "Finalizing processes..." +killall -9 fbcp-ili9341 2>/dev/null || true +sync \ No newline at end of file diff --git a/pipboyIO/pipboy-setup.sh b/pipboyIO/pipboy-setup.sh new file mode 100644 index 0000000..4c8276a --- /dev/null +++ b/pipboyIO/pipboy-setup.sh @@ -0,0 +1,84 @@ +#raspOS Bookworm lite + +#screen support +# Enable SPI using raspi-config +echo "Enabling SPI interface using raspi-config..." +raspi-config nonint do_spi 0 + +# Update system and install dependencies +echo "Updating the system and installing dependencies..." +apt update && apt upgrade -y +apt install -y cmake git build-essential nano + +#build deps and remove raspi features +sudo apt install -y libraspberrypi-dev +git clone https://github.com/juj/fbcp-ili9341.git +cd fbcp-ili9341 +mkdir build && cd build + +#append to fix -DDISPLAY_INVERT_COLORS=ON -DSTATISTICS=0 +cmake -DUSE_GPU=ON -DSPI_BUS_CLOCK_DIVISOR=12 -DGPIO_TFT_DATA_CONTROL=25 -DGPIO_TFT_RESET_PIN=17 -DILI9488=ON -DUSE_DMA_TRANSFERS=OFF -DDISPLAY_INVERT_COLORS=ON -DSTATISTICS=0 .. +make -j$(nproc) +sudo install fbcp-ili9341 /usr/local/bin/ +./config.sh + +#make autologin +sudo su +mkdir -pv /etc/systemd/system/getty@tty1.service.d +#nano /etc/systemd/system/getty@tty1.service.d/autologin.conf +cat < /etc/systemd/system/getty@tty1.service.d/autologin.conf +[Service] +ExecStart= +ExecStart=-/sbin/agetty --autologin gsd --noclear %I $TERM +EOT + +#Xserver and chromium +apt install -y --no-install-recommends xserver-xorg x11-xserver-utils xinit chromium-browser + +cat <> /home/gsd/.bashrc + +# Автозапуск X сервера при логине в tty1 +if [ -z "$DISPLAY" ] && [ $(tty) = /dev/tty1 ]; then + startx -- -nocursor +fi +EOT + +cat < /home/gsd/.xinitrc +#!/bin/sh + +# Ждем сеть +#while ! ping -c1 google.com &>/dev/null; do +# sleep 1 +#done + +# Настройки отключения энергосбережения +xset s off +xset -dpms +xset s noblank + +# Запуск Chromium +exec chromium-browser --no-memcheck --noerrdialogs --disable-infobars --disable-background-timer-throttling --disable-renderer-backgrounding --disable-backgrounding-occluded-windows --check-for-update-interval=31536000 --no-first-run --kiosk http://tf2.pblr-nyk.pro +EOT + +#uart + +cat <> /boot/firmware/config.txt +dtoverlay=disable-bt +enable_uart=1 +dtoverlay=uart0 +EOT + +sudo systemctl stop serial-getty@ttyS0.service +sudo systemctl disable serial-getty@ttyS0.service +sudo apt install python3-serial + +#sound https://withrow.io/simpsons-tv-build-guide-waveshare#parts-list +dtparam=audio=on +dtoverlay=audremap,enable_jack,pins_18_13 +#dtparam=audio=off +# dtparam=audio=on # закомментируйте или удалите эту строку +#dtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4 +#apt install git build-essential autoconf automake libtool libasound2-dev + +#rtc +#sudo apt-get install -y i2c-tools \ No newline at end of file diff --git a/pipboyIO/pipboyIO.ino b/pipboyIO/pipboyIO.ino new file mode 100644 index 0000000..a7cc6cc --- /dev/null +++ b/pipboyIO/pipboyIO.ino @@ -0,0 +1,32 @@ +const int input[] = {36, 39, 34 ,35 ,32 ,33 ,25 ,26}; +int inputValue[] = {0, 0, 0, 0, 0, 0, 0, 0}; +const int numPins = sizeof(input) / sizeof(input[0]); + +#define RXD2 (16) +#define TXD2 (17) + +void setup() { + //Serial.begin(115200); + Serial2.begin(9600, SERIAL_8N1, RXD2, TXD2); + analogReadResolution(12); + analogSetAttenuation(ADC_11db); +} + +void values2uart() { + for (int i = 0; i < numPins; i++) { + Serial2.print(input[i]); + Serial2.print("-"); + Serial2.print(inputValue[i]); + Serial2.print("\n"); + + } +} + +void loop() { + for (int i = 0; i < numPins; i++) { + inputValue[i] = analogRead(input[i]) / 100; + } + + values2uart(); + delay(50); +} diff --git a/pipboyIO/serialTest.py b/pipboyIO/serialTest.py new file mode 100644 index 0000000..03f4f64 --- /dev/null +++ b/pipboyIO/serialTest.py @@ -0,0 +1,64 @@ +import serial +import sys + +class Const: + S5 = 35 + S2 = 36 + S1 = 32 + S3 = 39 + S4 = 34 + + B1 = 26 + +class Pin: + def __init__(self, id, initValue): + self.id = id + self.value = initValue + + def updateValue(self, value): + if (self.value > value): + diff = self.value - value + self.value = value + return (self, -1 * diff) + elif (self.value < value): + diff = value - self.value + self.value = value + return (self, diff) + else: + return (self, 0) + +class SerialListener: + ser: serial.Serial = None + pins = {} + def __init__(self, device = '/dev/serial0', rate = 9600): + self.ser = serial.Serial(device, rate) + + def reInit(self): + if self.ser: + self.ser.close() + self.ser.open() + + def listen(self): + while True: + try: + if self.ser.in_waiting > 0: + data = self.ser.readline().decode().split("\n")[0].split("-") + pin = int(data[0]) + value = int(data[1]) + if pin not in self.pins: + self.pins[pin] = Pin(pin, value) + else: + yield self.pins[pin].updateValue(value) + except KeyboardInterrupt: + print("exit from main loop") + sys.exit(0) + except: + self.reInit() + +if __name__ == "__main__": + listener = SerialListener() + for pin in listener.listen(): + if (pin[1] == 0): + continue + + print(pin[0].id, pin[1])