2

I've written some python code that should start and stop another python script (Datalogger) when a button is pressed. So when the Pi is booted up I'm wanting the button script to run and then once I press the button it will start another python script. Then when I press the button again it will stop the other script from running and exit safely. Then if I press it again I want the other script to start up again etc.

My datalogger script creates a CSV file and then continuously writes data to it as long as it receives a square wave signal at the input pin. When the button is pushed it starts this script and when it is pushed again it is supposed to stop it cleanly (so the CSV is saved after the last write). However when I press the button it allows the other script to create the CSV but when I press it again it doesn't seem to stop the script (the CSV isn't populated with data) and it creates a brand new CSV (also empty when pushed again etc). Does anyone know what the problem could be? And do I possibly need to change/add some code to the script that I want to run when the button is pushed? The code for the button and datalogger scripts are shown below. Thanks.

Button script:

import RPi.GPIO as GPIO
import time
import subprocess, os
import signal

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO_switch = 24 # select pin to connect button
GPIO.setup(GPIO_switch, GPIO.IN, pull_up_down=GPIO.PUD_UP)

try:

    run = 0
    while True:
        if GPIO.input(GPIO_switch)==0 and run == 0:
            rpistr = "python3 /home/pi/Documents/DataloggerV2.py"
            p=subprocess.Popen(rpistr, shell=True, preexec_fn=os.setsid)
            run=1
            while GPIO.input(GPIO_switch)==0:
                time.sleep(0.01)
        if GPIO.input(GPIO_switch)==0 and run == 1:
            run = 0
            os.killpg(p.pid, signal.SIGTERM)
            while GPIO.input(GPIO_switch)==0:
                time.sleep(0.01)


except KeyboardInterrupt:

    GPIO.cleanup()

Datalogger Script:

import RPi.GPIO as GPIO
import datetime
from datetime import timedelta, datetime
import time
from time import sleep
import csv
from csv import writer
import signal


datestring = datetime.strftime(datetime.now(), '%Y_%m_%d-%H_%M_%S')

def my_callback(channel):
     data_writer.writerow([GPIO.input(26), datetime.now()])      # writes the detected
     # edge event to a CSV file with columns of rise/fall and the date & time of detection


if __name__ == '__main__':

    GPIO.setmode(GPIO.BOARD)       # set up GPIO numbering (BOARD = physical pins on Pi)
    GPIO.setup(26, GPIO.IN)         # set physical pin 26 as input


# create CSV file to write edge detection data to called Datalogger, with data on new line
    with open('/media/pi/KINGSTON/Datalogger_' + datestring + '.csv', 'w', newline='') as Datalogger:
        data_writer = writer(Datalogger)

        data_writer.writerow(["Edge type (0 = Falling)", "Date & Time"])       # create headers in CSV file


        GPIO.add_event_detect(26, GPIO.BOTH, callback=my_callback, bouncetime=20)     # edge detection function
        # detects both rise and fall in signal on pin 26, then runs my callback

        signal.pause()


        while True:
# main program loop here - loops detection of edges then runs my callback

          time.sleep(0.01)
4
  • it doesn't seem to be working What is 'it'? Secondary script doesn't start? Doesn't stop? Anything else?
    – Dirk
    Nov 19, 2018 at 15:40
  • My other script creates a CSV file and then continuously writes data to it as long as it receives a square wave signal at the input pin. When the button is pushed it starts this script and when it is pushed again it is supposed to stop it cleanly (so the CSV is saved after the last write). However when I press the button it allows the other script to create the CSV but when I press it again it doesn't seem to stop the script (the CSV isn't populated with data) and it creates a brand new CSV (also empty when pushed again etc)
    – user93154
    Nov 19, 2018 at 15:45
  • Please update your question with these details so that users don't have to get bits and pieces in different places
    – Dirk
    Nov 19, 2018 at 15:46
  • 1
    BTW: looks like you need some additional debug output: add print statements at stategic places in your scripts so that you can follow the flow (e.g. button pressed, script started, script stopped, file created, file updated,etc) so you don't have to guess and use words like 'it doesn't seem to', etc
    – Dirk
    Nov 19, 2018 at 15:50

1 Answer 1

2

I solved this by putting

except KeyboardInterrupt:
     print("Program stopped")
     exit(0)

at the end of my Data logger script, after signal.pause() and before the while True: statement.

1
  • Please accept your own answer. Only that will finish the question and it will not pop up again and again after months.
    – Ingo
    Nov 17, 2019 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.