Ganjanouille
Posts: 19
Joined: Sat Feb 03, 2018 11:00 am

[SOVED] Start python on RPi Zero startup

Wed Apr 04, 2018 1:45 pm

Hi folks!

I finished my script and tried to make it launch on startup but it does'nt work.

I first tried with rc.local file and second with cronetab.

rc.local content:

Code: Select all

#!/bin/bash
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

#Midi controller programm
python /home/pi/oled/threadingOledMidiA1.py&

touch /tmp/test.txt
echo "$(date) => It's running" > /tmp/test.txt

So the test file works just fine. Why isn't my python script?

command "cronetab -e" content:

Code: Select all

# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command

@reboot python /home/pi/oled/threadingOledMidiA1.py 

And yes I suppose there is an empty line at the end of cronetab.

uname -a output:
Linux raspberrypi 4.9.80+ #1098 Fri Mar 9 18:51:28 GMT 2018 armv6l GNU/Linux
And finally my python script:

Code: Select all

##############################################
#														#								#
#	This programm shows Waldorf Blofeld informations on SSD1306	#
#														#								#
##############################################

import serial
import sys, math, time
from threading import Thread

import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306

from PIL import Image, ImageFont, ImageDraw

#Blofeld control change mapping
blofeld_B0 = 	[	
						"Bank MSB",
						"ModWheel",
						"Brth Ctrl",
						"Undef",
						"Ft Ctrl",
						"Glide rate"
				]

blofeld_B1 = 	[	
						"Dta Entry",
						"Chnl Vol",
						"Balance",
						"Undef",
						"Pan",
						"Expr.",
				]

blofeld_B2 = 	[	
						"Arp rnge",
						"Arp length",
						"Arp Active",
						"LFO1 Shape",
						"LFO1 Speed",
						"LFO1 Sync"
				]

blofeld_B3 = 	[	
						"LFO1 Delay",
						"LFO2 Shape",
						"LFO2 Speed",
						"LFO2 Sync",
						"LFO2 Delay",
						"LFO3 Shape"
				]

blofeld_B4 = 	[	
						"LFO3 Speed",
						"LFO3 Sync",
						"LFO3 Delay",
						"OSC1 Oct.",
						"OSC1 Semi.",
						"OSC1 Detu."
				]

blofeld_B5 = 	[	
						"OSC1 FM",
						"OSC1 Shape",
						"Bank LSB",
						"OSC1 PW",
						"OSC1 PWM",
						"OSC2 Oct."
				]

blofeld_B6 = 	[	
						"OSC2 Semi.",
						"OSC2 Detu.",
						"OSC2 FM",
						"OSC2 Shape",
						"OSC2 PW",
						"OSC2 PWM"
				]

blofeld_B7 = 	[	
						"OSC3 Oct.",
						"OSC3 Semi.",
						"OSC3 Detu.",
						"OSC3 FM",
						"OSC3 Shape",
						"OSC3 PW"
				]

blofeld_B8 = 	[	
						"OSC3 PWM",
						"Sync",
						"Pitch modu",
						"Glide mode",
						"OSC1 level",
						"OSC1 balance"
				]

blofeld_B9 = 	[	
						"RingMod lvl",
						"RngMod balnc",
						"OSC2 level",
						"OSC2 balance",
						"OSC3 level",
						"OSC3 balance"
				]				
				
blofeld_B10 = 	[	
						"Noise level",
						"Noise balnc",
						"Noise colour",
						"Undef",
						"Sustain pedal",
						"Glide active"
				]		
blofeld_B11 = 	[	
						"Sostenuto",
						"Rt (ser/par)",
						"F1 Type",
						"F1 cutoff",
						"F1 resonance",
						"F1 Drive"
				]		

blofeld_B12 = 	[	
						"F1 Keytrack",
						"F1 env. amount",
						"F1 env. velocity",
						"F1 cutoff mod.",
						"F1 FM",
						"F1 pan"
				]		

blofeld_B13 = 	[	
						"F1 panMod",
						"F2 Type",
						"F2 cutoff",
						"F2 resonance",
						"F2 Drive",
						"F2 Keytrack"
				]		
				
blofeld_B14 = 	[	
						"F2 env. amount",
						"F2 env. velocity",
						"F2 cutoff mod.",
						"F2 FM",
						"F2 pan",
						"F2 panMod"
				]		
				
blofeld_B15 = 	[	
						"Amp volume",
						"Amp velocity",
						"Amp mod.",
						"FX1 mix",
						"FX2 mix",
						"FE attack"
				]		
				
blofeld_B16 = 	[	
						"FE decay",
						"FE sustain",
						"FE decay2",
						"FE sustain2",
						"FE release",
						"AE attack"
				]		
				
blofeld_B17 = 	[	
						"AE decay",
						"AE sustain",
						"AE decay2",
						"AE sustain2",
						"AE release",
						"E3 attack"
				]		
				
blofeld_B18 = 	[	
						"E3 decay",
						"E3 sustain",
						"E3 decay2",
						"E3 sustain2",
						"E3 release",
						"E4 attack"
				]		
				
blofeld_B19 = 	[	
						"E4 decay",
						"E4 sustain",
						"E4 decay2",
						"E4 sustain2",
						"E4 release",
						"undef"
				]		




# Raspberry Pi SPI pin configuration:
RST = 25

# Note the following are only used with SPI:
DC = 24
SPI_PORT = 0
SPI_DEVICE = 0

# 128x64 display with hardware SPI:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=16000000))

# Initialize library.
disp.begin()

# Get display width and height.
width = disp.width
height = disp.height
mid = (width /2, height /2)

# Clear display.
disp.clear()
disp.display()

# Create image buffer.
# Make sure to create image with mode '1' for 1-bit color.
image = Image.new('1', (width, height))
flower = Image.new('1', (width, height))

#Controller bank pages
page = 	[]
for i in range(20):
	page.append(Image.new('1', (width, height)))

#Create Drawing object
draw = []
for i in range(20):
	draw.append(ImageDraw.Draw(page[i]))

#Display logo and wait 2 seconds
flower = Image.open('floweroflife.ppm').convert('1')
disp.image(flower)
disp.display()

#Wait 1s to observe this beautiful logo (:
time.sleep(1)

# Create serial instance on ttyAMA0
ser = serial.Serial('/dev/ttyAMA0', baudrate=38400) 
   
# Clear image buffer by drawing a black filled box.
draw[0].rectangle((0,0,width,height), outline=0, fill=0)

#Garbage
#draw.text((0, 0), "Control ", fill = 255)
#txtsz = draw.textsize("Controller")

#Some variables definitions
message = [0, 0, 0]
storeValue = 0
txtHeight = draw[0].textsize("H")[1]-2
row = 0
coloumn1 = 0
coloumn2 = 127 -  draw[0].textsize("127")[0]
exit = False

#Prepare buffer by drawing each page
#Draw header (same for each pages)
for i in range(20):
	draw[i].text((coloumn1, row), "Midi Channel: ", fill=255)
	
row += 1

#Draw paramter names (not the same!) on each page
for i in range(len(blofeld_B0)):
	draw[0].text((coloumn1, txtHeight*row), blofeld_B0[i], fill=255)
	row += 1

row = 1
for i in range(len(blofeld_B1)):
	draw[1].text((coloumn1, txtHeight*row), blofeld_B1[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B2)):
	draw[2].text((coloumn1, txtHeight*row), blofeld_B2[i], fill=255)
	row += 1

row = 1
for i in range(len(blofeld_B3)):
	draw[3].text((coloumn1, txtHeight*row), blofeld_B3[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B4)):
	draw[4].text((coloumn1, txtHeight*row), blofeld_B4[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B5)):
	draw[5].text((coloumn1, txtHeight*row), blofeld_B5[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B6)):
	draw[6].text((coloumn1, txtHeight*row), blofeld_B6[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B7)):
	draw[7].text((coloumn1, txtHeight*row), blofeld_B7[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B8)):
	draw[8].text((coloumn1, txtHeight*row), blofeld_B8[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B9)):
	draw[9].text((coloumn1, txtHeight*row), blofeld_B9[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B10)):
	draw[10].text((coloumn1, txtHeight*row), blofeld_B10[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B11)):
	draw[11].text((coloumn1, txtHeight*row), blofeld_B11[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B12)):
	draw[12].text((coloumn1, txtHeight*row), blofeld_B12[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B13)):
	draw[13].text((coloumn1, txtHeight*row), blofeld_B13[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B14)):
	draw[14].text((coloumn1, txtHeight*row), blofeld_B14[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B15)):
	draw[15].text((coloumn1, txtHeight*row), blofeld_B15[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B16)):
	draw[16].text((coloumn1, txtHeight*row), blofeld_B16[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B17)):
	draw[17].text((coloumn1, txtHeight*row), blofeld_B17[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B18)):
	draw[18].text((coloumn1, txtHeight*row), blofeld_B18[i], fill=255)
	row += 1
	
row = 1
for i in range(len(blofeld_B19)):
	draw[19].text((coloumn1, txtHeight*row), blofeld_B19[i], fill=255)
	row += 1
	
row = 1

#Display class
class oled(Thread):
	def __init__(self):
		Thread.__init__(self)
		
	
	def run(self):
		controller = 0
		currentChannel = 100
		channel = 1
		bankIn = 0
		bank = 0
		init = True
		row = 1
		while not exit:
			try:
				#CC 127 and 126 are coming especially for RPi
				#CC 126 is for controller bank select
				if message[0] > 175 and message[0] < 192 and message[1] == 126:
					bankIn = message[2] 	#Bank info coming from ATmega 328
					if bankIn != 0:
						bank = bankIn / 6	#Real bank value
					else:
						bank = bankIn
					
					#Display header
					currentChannel = channel
					draw[bank].rectangle((draw[0].textsize("Midi Channel: ")[0], 0, width, txtHeight), outline=0, fill=0)
					draw[bank].text((draw[0].textsize("Midi Channel: ")[0], 0), str(channel), fill = 255)
				
				#CC 127 stands for midi channel select
				if message[0] > 175 and message[0] < 192 and message[1] == 127 or init:
					if not init:
						channel = message[0]-175
					
					#Display header
					if currentChannel != channel:
						currentChannel = channel
						draw[bank].rectangle((draw[0].textsize("Midi Channel: ")[0], 0, width, txtHeight), outline=0, fill=0)
						draw[bank].text((draw[0].textsize("Midi Channel: ")[0], 0), str(channel), fill = 255)

				#Recognize control change and act in consequence
				if init or message[0] > 175 and message[0] < 192 and message[1] != 127 and message[1] != 126:
					controller = message[1] - bankIn
					
					#Convert int to string for PIL imaging library
					value = str(message[2])
				
					#Display values on corresponding row to controller number
					draw[bank].rectangle((coloumn2, txtHeight*(controller+row), width,txtHeight*2*(controller+row)), outline = 0, 	fill = 0)
					draw[bank].text((coloumn2, txtHeight*(controller+row)), value, fill=255)
					
				disp.image(page[bank])
				disp.display()
				#Reset some values for next loop
				init = False

			except:
				print "Error, SOMETHING WENT WRONG (or not)! Here some info bredaaa: \n", sys.exc_info()
				print "Exit flag: ", exit
				sys.exit()


thread1 = oled()
thread1.start()

#Tell debuging user that programm is running
print "Crazy stuff going on..."

while True:
	try:
		i = 0
		while i < 3:
			data = ord(ser.read(1)) # read a byte
			if data >> 7 != 0:  
				i = 0      # status byte!   this is the beginning of a midi message!
			message[i] = data
			i += 1
		
	except:
		exit = True
		thread1.join()
		print "Error, SOMETHING WENT WRONG (or not)! Here some info bredaaa: \n", sys.exc_info()
		sys.exit()

Any clue why this issue? :geek:

Thank's!
Last edited by Ganjanouille on Wed Apr 04, 2018 4:33 pm, edited 1 time in total.

pcmanbob
Posts: 4380
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 3:03 pm

Try changing your cron line to this

Code: Select all


@reboot python /home/pi/oled/threadingOledMidiA1.py >>/home/pi/error.txt 2>&1

reboot and look in the error.txt file to see if there are any errors listed.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ganjanouille
Posts: 19
Joined: Sat Feb 03, 2018 11:00 am

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 3:32 pm

Ok I did that.

error.txtis:

Code: Select all

/etc/rc.local: line 15: @reboot: command not found
:o

I ask google for that output but found nothing for the moment.

Thank's for the help

pcmanbob
Posts: 4380
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 3:39 pm

Ganjanouille wrote:
Wed Apr 04, 2018 3:32 pm
Ok I did that.

error.txtis:

Code: Select all

/etc/rc.local: line 15: @reboot: command not found
That's because you are attempting to use a cron command in rc.local. remove the lines from rc.local.

the do crontab -e and add the line I suggested.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ganjanouille
Posts: 19
Joined: Sat Feb 03, 2018 11:00 am

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 4:09 pm

So I did the correction. Still don't work (it was correct when I tested it first time)

So know it's become clearer, error.txt content is:

Code: Select all

/etc/rc.local: line 15: @reboot: command not found
/etc/rc.local: line 19: @reboot: command not found
Traceback (most recent call last):
  File "/home/pi/oled/threadingOledMidiA1.py", line 238, in <module>
    flower = Image.open('floweroflife.ppm').convert('1')
  File "/usr/lib/python2.7/dist-packages/PIL/Image.py", line 2312, in open
    fp = builtins.open(filename, "rb")
IOError: [Errno 2] No such file or directory: 'floweroflife.ppm'
Strange is that the file is in the same directory. What else I have to specifiy?

Code: Select all

[email protected]:~/oled $ ls
animate.py               beforConvert.png  fractFougere.py   stats.py                threadingOledMidi.py~
ArduiPi_OLED-master      convert.ppm       oledMidi.py       threadingOledMidiA1.py  threadingOledMidi.pyc
ArduiPi_OLED-master.zip  floweroflife.ppm  pointParPoint.py  threadingOledMidi.py
Thank's!

pcmanbob
Posts: 4380
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 4:14 pm

Cron operates in a different environment to the command line, your python program needs to use full paths to all files.

for example

Code: Select all

flower = Image.open('floweroflife.ppm').convert('1')
you need to add the full path to floweroflife.ppm
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

Ganjanouille
Posts: 19
Joined: Sat Feb 03, 2018 11:00 am

Re: Start python on RPi Zero startup

Wed Apr 04, 2018 4:20 pm

I just added full path in python script!


Now it's working. Thank's a lot!

Return to “General programming discussion”

Who is online

Users browsing this forum: No registered users and 5 guests