commit
6ca0deda2c
4 changed files with 297 additions and 0 deletions
@ -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 <<EOT > "$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 |
|||
@ -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/[email protected] |
|||
#nano /etc/systemd/system/[email protected]/autologin.conf |
|||
cat <<EOT > /etc/systemd/system/[email protected]/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 <<EOT >> /home/gsd/.bashrc |
|||
|
|||
# Автозапуск X сервера при логине в tty1 |
|||
if [ -z "$DISPLAY" ] && [ $(tty) = /dev/tty1 ]; then |
|||
startx -- -nocursor |
|||
fi |
|||
EOT |
|||
|
|||
cat <<EOT > /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 <<EOT >> /boot/firmware/config.txt |
|||
dtoverlay=disable-bt |
|||
enable_uart=1 |
|||
dtoverlay=uart0 |
|||
EOT |
|||
|
|||
sudo systemctl stop [email protected] |
|||
sudo systemctl disable [email protected] |
|||
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 |
|||
@ -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); |
|||
} |
|||
@ -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]) |
|||
Loading…
Reference in new issue