Python scripts works but not when as a cronjob


6 posts
by Yiannis » Fri Feb 17, 2017 12:59 pm
Dear all,

Any help will be much appreciated. I do not know if this is the right forum but if not can moderators please move it to the right place?

Hardware:
    Raspberry Pi B V1.1
    Breadboard
    3 momentary push buttons

The project:
    2 people have one button each
    button presses are recorded in the form of time stamps
    differences in time between presses for each participant are recorded.
    3rd button will close the file and clean gpios - this is because it will run as a cronjob - see below

The script is below and it seems to be working fine when run either through terminal or from within idle

If however the script is placed as a cronjob (sudo crontab -e and then @reboot sudo python /path/to/my/script/) the the third button (value3 in my script) seems to take the value of True straight away and I get an empty file (with the headers)

I am really baffled and i tried to troubleshoot it for several days but with no luck...
So, why a script that works when ran through terminal or idle does not when in a cronjob?

Many thanks in advance.

Code: Select all
import RPi.GPIO as GPIO
import time
from datetime import datetime, timedelta
import os


count = 0
key_press1 = 0 # secondary  pushbutton
key_press0 = 0 # main pushbutton
key_press1_list = []
key_press0_list = []


start=time.time()
now= datetime.now()
current_date_time = now.strftime('%d_%m_%Y_%H_%M_%S')

key_press1_list.append(start)# initial timestamp i.e. from running the script - not very relevant
                             # as it will start as cron and no way to check
key_press0_list.append(start)
list_direc = os.listdir("/media")

# This will search for a USB in the media directory where it will save the data
# If no USB is present then it will save the data on Desktop
# Data files are saved in the following format: data_date_time.txt
# Also, in the media directory there is another folder called SETTINGS and I want to leave it alone
if len(list_direc) < 3:
    datafile=open("/home/pi/Desktop/"+"data_"+current_date_time+".txt", 'a+')
else:     
    for i in list_direc:
        if i == "SETTINGS" or i == "SETTINGS_":
            continue
        else:
            my_usb = i
            datafile=open("/media/"+my_usb+"/"+"data_"+current_date_time+".txt", 'a+')
datafile.write("TimeCode"+"\t"+"Count"+"\t"+"1st Press"+"\t"+"2nd Press"+"\t"+"Duration"+"\t"+"User (1=Exp, 0= Sub)"+"\n")
outPin = 37 #main push button's redlight
outPin2 = 29 # secondary push button's bluelight
inPin2 = 31 # secondary pushbutton
inPin = 33 # main pushbutton
inPin3 = 7 # reset button - saves the data in a file and kills gracefully the programme
GPIO.setmode(GPIO.BOARD)
GPIO.setup(outPin, GPIO.OUT)
GPIO.setup(outPin2, GPIO.OUT)
GPIO.setup(inPin, GPIO.IN)
GPIO.setup(inPin2, GPIO.IN)
GPIO.setup(inPin3, GPIO.IN)

try:
   
    while True:
       
        value = GPIO.input(inPin) # this is 1
        value2 = GPIO.input(inPin2) # this is 0
        value3 = GPIO.input(inPin3) # this is 0
        GPIO.output(outPin2, 0)
        GPIO.output(outPin, 0)
        if value3 == False:
           
            if value == True and value2 == False:
                GPIO.output(outPin, 0)
               
            elif value == False and value2 == False:
               
                GPIO.output(outPin, 1)
                count += 1

                key_press0 = time.time()
                key_press0_list.append(key_press0)
                rec_diff_key_press0 = key_press0_list[-1]-key_press0_list[-2]
                datafile.write(str(current_date_time)+"\t"+str(count)+"\t" + str(key_press0_list[-2]) +"\t"+str(key_press0_list[-1])+"\t"+str(rec_diff_key_press0)+"\t"+str(value)+"\n")
                time.sleep(0.4)
               
            elif value == True and value2 == False:
                GPIO.output(outPin2, 0)
                #print value2
               
            elif value == True and value2 == True:
                GPIO.output(outPin2, 1)
               
                count += 1

                key_press1 = time.time()
                key_press1_list.append(key_press1)
                rec_diff_key_press1 = key_press1_list[-1]-key_press1_list[-2]
                datafile.write(str(current_date_time)+"\t"+str(count)+"\t" + str(key_press1_list[-2]) +"\t"+str(key_press1_list[-1])+"\t"+str(rec_diff_key_press1)+"\t"+str(value2)+"\n")
                time.sleep(0.4)
        else:
            GPIO.cleanup()
            datafile.close()
   
except KeyboardInterrupt:
        print "Done"
        GPIO.cleanup()
        datafile.close()
        key_press0 = 0
        key_press0_list = [0]
        key_press1 = 0
        key_press1_list = [0]
Posts: 12
Joined: Mon Jan 05, 2015 2:39 pm
Location: Edinburgh, UK
by texy » Fri Feb 17, 2017 1:21 pm
Hi,
maybe its the way that GPIO's are configured during the boot up process. Have you measured the voltage on those pins when you apply power to the pi?
What about pull up resistors - are those GPIO lines floating?

Texy
Various male/female 40- and 26-way GPIO header for sale here ( IDEAL FOR YOUR PiZero ):
https://www.raspberrypi.org/forums/viewtopic.php?f=93&t=147682#p971555
Forum Moderator
Forum Moderator
Posts: 4823
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by SkyRise » Fri Feb 17, 2017 1:25 pm
Also, cron uses a different set of environment variables than any user so may not know where to find 'sudo' and 'python'

try
Code: Select all
@reboot /path/to/sudo /path/to/python /path/to/my/script/


you can use the 'which' command to find out what the paths are...
Posts: 84
Joined: Tue Jan 24, 2012 1:20 pm
by Yiannis » Fri Feb 17, 2017 2:25 pm
Hi Texy,

Many thanks for the swift reply and your kind suggestions.
texy wrote:What about pull up resistors - are those GPIO lines floating?

With all honesty, someone else did the wiring and I only wanted to add a third button (not the reset one). So I did a bit of studying and experimenting to do so but what the other guy did confuses me. So, I haven't reached the chapter yet about "pull up resistors" and "lines floating" :oops:
texy wrote:maybe its the way that GPIO's are configured during the boot up process. Have you measured the voltage on those pins when you apply power to the pi?


Actually this helped. I run a script as cronjob to measure the state of the pins at boot (in case someone is interested see below):

Code: Select all
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
datafile=open("/home/pi/Desktop/mypins_state.txt", 'a+')
for i in (35,,35,7,11,13,15,19,21,23,29,31,33,37,40,38,26,32,26,24,22,18,16,12,10,8):
    GPIO.setup(i, GPIO.IN)
    state = GPIO.input(i)
    if state == True:
        datafile.write(str(i)+"\t"+"is HIGH\n")
    else:
        datafile.write(str(i)+"\t"+"is LOW\n")
datafile.close()


This showed that pin 7 was HIGH and not LOW as I initially thought and it worked. But still confuses me why when I inverted the if statement from False to True for pin 7 did not work.

Many thanks again
P.S. Is there a "Solved" or "Mark as Answer" button in this forum?
Last edited by Yiannis on Fri Feb 17, 2017 2:29 pm, edited 2 times in total.
Posts: 12
Joined: Mon Jan 05, 2015 2:39 pm
Location: Edinburgh, UK
by Yiannis » Fri Feb 17, 2017 2:27 pm
SkyRise wrote:Also, cron uses a different set of environment variables than any user so may not know where to find 'sudo' and 'python'

try
Code: Select all
@reboot /path/to/sudo /path/to/python /path/to/my/script/


you can use the 'which' command to find out what the paths are...


Hi SkyRise,

Many thanks for your helpful tip. It seems that cron understands both python and sudo (at least in my case with the default setup). The same for /etc/rc.local
Posts: 12
Joined: Mon Jan 05, 2015 2:39 pm
Location: Edinburgh, UK
by pcmanbob » Sat Feb 18, 2017 10:42 am
Hi

if you are running a cron job with sudo crontabe -e as per this line in your post
If however the script is placed as a cron job (sudo crontab -e and then @reboot sudo python /path/to/my/script/)

there is no need or point in putting sudo in the cron line as you are already running it as root so sudo can't elevate your command any further.

Regarding pull up or pull down resistors have a look at this page
https://www.raspberrypi.org/learning/ph ... l_up_down/
Please only ask questions in the forum
Posts: 589
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK