LINUX.ORG.RU

Проблема с автозапуском программы на Raspberry Pi

 


0

1

Есть программа, которая выводит список файлов на текстовый экран и листает его тактовыми кнопками. Нужно добавить ее в автозапуск. Выполняю эту последовательность команд:

sudo nano /etc/init.d/autostart.sh

Пишу скрипт:
#!/bin/bash
### BEGIN INIT INFO
# Provides:          autostart.sh
# Required-Start:
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      1 0 6
# Short-Description: simple description.
### END INIT INFO
export USER='pi'
sudo python /home/pi/prog21.py
exit 0

sudo chmod 755 /etc/init.d/autostart.sh

sudo update-rc.d autostart.sh defaults

Ответ:update-rc.d: using dependency based boot sequencing

insserv myscript

И ничего не происходит при запуске raspberry. Только исчезают черные квадраты из первой строчки, значит инициализация дисплея прошла. Но списка файлов нет. Программа нормально работает только при запуске вручную. Код программы на всякий случай:

#import
import RPi.GPIO as GPIO
import os
import socket
import fcntl
import struct
import time
from time import gmtime, strftime, sleep

directory = '/media/TRANSCEND'
files = os.listdir(directory) 
images = filter(lambda x: x.endswith('.jpg'), files)  

# Define GPIO to LCD mapping
LCD_RS = 7
LCD_E  = 8
LCD_D4 = 25
LCD_D5 = 24
LCD_D6 = 23
LCD_D7 = 18


# Define some device constants
LCD_WIDTH = 16    # Maximum characters per line
LCD_CHR = True
LCD_CMD = False

LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line
LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line

# Timing constants
E_PULSE = 0.0005
E_DELAY = 0.0005

def main():
  # Main program block
  
  GPIO.setwarnings(False)
  GPIO.setmode(GPIO.BCM)       # Use BCM GPIO numbers
  GPIO.setup(LCD_E, GPIO.OUT)  # E
  GPIO.setup(LCD_RS, GPIO.OUT) # RS
  GPIO.setup(LCD_D4, GPIO.OUT) # DB4
  GPIO.setup(LCD_D5, GPIO.OUT) # DB5
  GPIO.setup(LCD_D6, GPIO.OUT) # DB6
  GPIO.setup(LCD_D7, GPIO.OUT) # DB7


  # Initialise display
  lcd_init()
  i=0
  GPIO.setmode(GPIO.BCM)
  GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)
  while True:
    try:
        if GPIO.input(21) == False:
          i=i+1
          j=i+1
          g=8
          if j < g:
            lcd_string(images[i], LCD_LINE_1)
            lcd_string(images[j], LCD_LINE_2)
          else:
            i = g - 2
            j = g - 1
            lcd_string(images[i], LCD_LINE_1)
            lcd_string(images[j], LCD_LINE_2)
        if GPIO.input(16) == False:
			i=i-1
			j=i+1
			k=abs(i)
				if k == i:
					lcd_string(images[i], LCD_LINE_1)
					lcd_string(images[j], LCD_LINE_2)
				else:
					i=0
					j=1
					lcd_string(images[i], LCD_LINE_1)
					lcd_string(images[j], LCD_LINE_2)
        sleep(0.2)
    except KeyboardInterrupt:
        exit()
		  
def lcd_init():
  # Initialise display
  lcd_byte(0x33,LCD_CMD) # 110011 Initialise
  lcd_byte(0x32,LCD_CMD) # 110010 Initialise
  lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction
  lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off
  lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size
  lcd_byte(0x01,LCD_CMD) # 000001 Clear display
  time.sleep(E_DELAY)

def lcd_byte(bits, mode):
  # Send byte to data pins
  # bits = data
  # mode = True  for character
  #        False for command

  GPIO.output(LCD_RS, mode) # RS

  # High bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x10==0x10:
    GPIO.output(LCD_D4, True)
  if bits&0x20==0x20:
    GPIO.output(LCD_D5, True)
  if bits&0x40==0x40:
    GPIO.output(LCD_D6, True)
  if bits&0x80==0x80:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

  # Low bits
  GPIO.output(LCD_D4, False)
  GPIO.output(LCD_D5, False)
  GPIO.output(LCD_D6, False)
  GPIO.output(LCD_D7, False)
  if bits&0x01==0x01:
    GPIO.output(LCD_D4, True)
  if bits&0x02==0x02:
    GPIO.output(LCD_D5, True)
  if bits&0x04==0x04:
    GPIO.output(LCD_D6, True)
  if bits&0x08==0x08:
    GPIO.output(LCD_D7, True)

  # Toggle 'Enable' pin
  lcd_toggle_enable()

def lcd_toggle_enable():
  # Toggle enable
  time.sleep(E_DELAY)
  GPIO.output(LCD_E, True)
  time.sleep(E_PULSE)
  GPIO.output(LCD_E, False)
  time.sleep(E_DELAY)

def lcd_string(message,line):
  # Send string to display


  message = message.ljust(LCD_WIDTH," ")

  lcd_byte(line, LCD_CMD)

  for i in range(LCD_WIDTH):
    lcd_byte(ord(message[i]),LCD_CHR)

if __name__ == '__main__':

  try:
    main()
  except KeyboardInterrupt:
    pass
  finally:
    lcd_byte(0x01, LCD_CMD)
    lcd_string("Goodbye!",LCD_LINE_1)
    GPIO.cleanup()

Можно ещё запустить программу не как сервис, а как автостартуемое приложение в KDE, gnome или что там у тебя.

adamantan ()

самый просто способ это не создавать init скрипт, а просто добавить запуск скрипта в /etc/rc.local

JB ★★★★★ ()
Ответ на: комментарий от varikayu574636

тогда я тебя разочарую - твой init скрипт тоже запустится в фоновом режиме :)

как вариант, подменить getty на твой скрипт, тогда должно получится так как ты хочешь - сразу после окончания загрузки появится твое приложение

JB ★★★★★ ()
Ответ на: комментарий от JB

Можно поподробнее про «подменить getty на твой скрипт» ? Я новичок в Линуксе. Я знаю, что такое getty, но никогда не слышал про такие манипуляции. Хотя бы в общих чертах, как мне действовать.

varikayu574636 ()
Ответ на: комментарий от varikayu574636

ты сначала максимально подробно опиши какой результат хочешь получить, а мы тебе тогда предложим варианты

JB ★★★★★ ()
Ответ на: комментарий от JB

Суть: есть Raspberry Pi с установленной программой Pronterface (управляет 3D-принтером). Я хочу: 1) приделать к Raspberry текстовый дисплей на HD44780, чтобы он выводил список файлов на SD-карте в принтере, параметры принтера и прочую инфу (написать ПО для этого) 2) приделать к Raspberry 3-4 кнопки, которыми можно листать список файлов на дисплее и запускать печать и т.д. (тоже написать ПО для этого) 3) вкорячить программу, выполняющую пункты 1 и 2 в код Pronterface (Pronterface написана на Пайтоне и имеет открытый код). 4) Сделать так, чтобы Pronterface стартовала автоматически при включении устройства. Ведь клавиатуры, мыши и монитора потом не будет. Будет только текстовый дисплейчик и блок из 3-5 тактовых кнопок.

1 и 2 пункты я выполнил. 3 пункт на стадии отладки. С 4 пунктом траблы, ибо все способы автозапуска в Линуксе, которые я знаю и которые предлагает Гугл предполагают работу в фоном режиме. Но тогда нет взаимодействия ни с кнопками, ни дисплеем. Значит, фоновый режим не катит, нужно чтобы Pronterface запускалась полноценно, вместе с GUI. Запускается в ручную она просто:

sudo python /home/pi/Printrun/pronterface.py

varikayu574636 ()
Ответ на: комментарий от varikayu574636

например можно в /etc/inittab поменять вызов getty на первом терминале на вызов твоего скрипта. Но я не уверен что это правильный способ

JB ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.