Python Code for Controller Raspberry Pi

Code for the Moto-Mast Raspberry Pi Controller is comprised of three modules plus a launching script. The main program, MotoMast2.py runs in the forground process. There are two background processes which are launched first. These are RPMZero.py and SW-Shutdown3.py. All of these are loaded in the correct order by the script Launcher.sh. There is also a file named ids.json which contains the count for the height of the mast in "clicks" on the winch drive shaft. If the mast is docked, this file just contains the number 0.

 

All of these files are available on the Download page. Contact KD6X if you would like to receive a complete image of the 8 GB MicroSD card containing the Raspbian OS and integrated Moto-Mast program files.

 

Code for main program MotoMast2

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/usr/bin/python
#--------------------------------------
#    ___  ___  _ ____
#   / _ \/ _ \(_) __/__  __ __
#  / , _/ ___/ /\ \/ _ \/ // /
# /_/|_/_/  /_/___/ .__/\_, /
#                /_/   /___/
#
#  lcd_16x2.py
#  16x2 LCD Test Script 
#
# Author : Matt Hawkins
# Date   : 06/04/2015
#
# http://www.raspberrypi-spy.co.uk/
#
#  Modified and extended for the MotoMast Control
#  By Courtney E. Krehbiel, October 2015
#
#  Ver. 1.02 change in Dec. 2015 to modify rpmzero.py "SmallSleep" delay variable to 3 from 5
#  Ver. 1.10 change on 2/23/2016 to add docking zero function to rpmzero.py and changes to how nCount is handled in MotoMast2.
#
#--------------------------------------

# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 6 : Enable or Strobe
# 7 : Data Bit 0             - NOT USED
# 8 : Data Bit 1             - NOT USED
# 9 : Data Bit 2             - NOT USED
# 10: Data Bit 3             - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: LCD Backlight +5V**
# 16: LCD Backlight GND

#import
import RPi.GPIO as GPIO
import time
import json

# Define GPIO to LCD mapping
LCD_RS = 14
LCD_E  = 15
LCD_D4 = 17
LCD_D5 = 18
LCD_D6 = 27
LCD_D7 = 22


# 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

#CEK Global Variables for MotoMast
BtnPin = 23	# pin 16 for pushbutton, GPIO 23  (GPIO 25, pin 22 on blown new board)
SwUpDown = 24	# pin 18 for up/down switch, GPIO 24  (GPIO 16, pin 36 on blown new board)
# BtnPin = 25	# pin 16 for pushbutton, GPIO 23  (GPIO 25, pin 22 on blown new board)
# SwUpDown = 16	# pin 18 for up/down switch, GPIO 24  (GPIO 16, pin 36 on blown new board)
sHeightLabel = "Height Ft: "
sRPM = "RPM: 0.00"
nRPM = 0
Height = 0
HeightFeet = 0
sHeightFeet = ""
StartTime = 0



def setup():
	# Setup 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()
  
	global sRPM
	global StartTime

	GPIO.setup(BtnPin, GPIO.IN, pull_up_down=GPIO.PUD_UP)	#RPM indicator switch
	GPIO.setup(SwUpDown, GPIO.IN, pull_up_down=GPIO.PUD_UP)				# Up/Down indicator switch

	lcd_string('KD6X Moto-Mast', LCD_LINE_1)		# Provide display initialization info
	lcd_string('Firmware v1.10', LCD_LINE_2)
	time.sleep(4)						# 4 second delay	

	displayheight()						# Initial display of data on display
	lcd_string(sRPM, LCD_LINE_2)				# Display RPM: 0.00 from initial string variable
	sRPM = 'RPM: '						# Reset the string for when running to eliminate extra zeros
	StartTime = time.time()					# Set the clock for RPM timing
	


def displayheight():
	global Height
	global HeightFeet
	global sHeightFeet

	with open('ids.json', 'r') as fp:			# Get current position count from disk
		nCount = json.load(fp)
	fp.close()
#	print 'Ncount: ', str(nCount)
	Height = 120 + (nCount * 1.026)	# Mast goes up 1.026 inches per revolution of winch shaft
	HeightFeet = Height / 12
	HeightFeet = round(HeightFeet,2)
	sHeightFeet = str("%.2f" % HeightFeet)		# Convert to feet, round to one decimal point, and then string
	sNewHeightString = ''.join([sHeightLabel, sHeightFeet])
	lcd_string(sNewHeightString, LCD_LINE_1)

def displayrpm():
	global nRPM
	global StartTime
	global RPMStartUp

	NowTime = time.time()
	nRPM = 60 / (NowTime - StartTime)
#	print 'Start:', str(StartTime), 'Now:', str(NowTime), 'RPM:', str(nRPM)
	nRPM = round(nRPM,2)
	sActualRPM = str("%.2f" % nRPM)
	sNewRPMString = ''.join([sRPM, sActualRPM])
	lcd_string(sNewRPMString, LCD_LINE_2)
	StartTime = NowTime		# Setup start time for accurate RPM capture on next revolution.  First one will be pretty close to 0.


def swcount(ev=None):	#This is the routine that runs everytime the winch shaft rotates on revolution

#	print 'Button pressed: ', str(nCount)

	with open('ids.json', 'r') as fp:			# Get current position count from disk
		nCount = json.load(fp)
	fp.close()

	if GPIO.input(SwUpDown) == GPIO.HIGH:
		nCount = nCount + 1					# Increment or decrement the position counter
	else:
		nCount = nCount - 1

	with open('ids.json', 'w') as fp:	# Write current count to disk just in case motor is stopped
		json.dump(nCount, fp)
	fp.close()

	displayheight()							# Do the math and formatting to output the data
	displayrpm()

		
	

# A few more lines from CEK to set the overall loop
	
def loop():
	while True:	
		GPIO.wait_for_edge(BtnPin, GPIO.FALLING, bouncetime=200)	#Triggers swcount function on debounced falling edge of count pulse.
		swcount()

def destroy():
	lcd_byte(0x01, LCD_CMD)				#Clear display
	lcd_string("Goodbye!",LCD_LINE_1)

	GPIO.cleanup()			#Release resources



# End of CEK code
  
  
  
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__':
	setup()
	try:
		loop()
	except KeyboardInterrupt:  #When 'Ctrl-C' is pressed, the child program destroy() will be executed.
		pass
	finally:
		destroy()
	
	

 

Code for background module SW-Shutdown3

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#!/bin/python
#
#
# Written by Courtney Krehbiel
# October 2015
#
#
# Purpose is to run as a background program and monitor GPIO 21 to see if it is grounded.
# If high to low (ground) detected it will perform an orderly shutdown of the Raspberry Pi
#
#
import RPi.GPIO as GPIO
import os
import sys
import time

switchpin = 21		# Using GPIO 21, physical pin 40 since it's close to a ground pin.

GPIO.setmode(GPIO.BCM)	# Using BCM numbers, not physical pin numbers

GPIO.setup(switchpin, GPIO.IN, pull_up_down=GPIO.PUD_UP)	# Set as input, and pulled high by default

GPIO.wait_for_edge(switchpin, GPIO.FALLING, bouncetime=200)	# Program will stop at this line and wait for falling edge, if ever.

# If program ever gets here, we're shutting down.

# Define GPIO to LCD mapping
LCD_RS = 14
LCD_E  = 15
LCD_D4 = 17
LCD_D5 = 18
LCD_D6 = 27
LCD_D7 = 22


# 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

  
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


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)


def haltsystem(ev=None):
	lcd_string("Halting RPi...  ", LCD_LINE_1)
	lcd_string("Pse wait 30 sec.", LCD_LINE_2)
	os.system("sudo shutdown -h now")		# Send command to shutdown the system
#	print 'System being halted'
	sys.exit(0)

# Initialise display
lcd_init()


GPIO.remove_event_detect(switchpin)

# Send some test
lcd_byte(0x01,LCD_CMD) # 000001 Clear display
lcd_string("REBOOT in 15 sec",LCD_LINE_1)
lcd_string("Push agn to HALT",LCD_LINE_2)

time.sleep(2)						# Debounce the keypress to make sure there are two distinct pushes.

GPIO.add_event_detect(switchpin, GPIO.FALLING)  	# wait for any activity

CountDown = 1500

while CountDown > 0:
	if GPIO.event_detected(switchpin):
		haltsystem()
	time.sleep(0.01)
	CountDown = CountDown - 1

# Button not pressed 2nd time, so will reboot instead 
lcd_string("Rebooting RPi...", LCD_LINE_1)
lcd_string("Pse wait 30 sec.", LCD_LINE_2)
#print 'System being rebooted'

#time.sleep(5)

#lcd_init()		# Clean up display
#GPIO.cleanup()		# Tidy up before exit
os.system("sudo reboot")		# Send command to reboot the system


# To run as a background program which takes very few resources, use the command: sudo python sw-shutdown.py &

 

Code for background module RPMZero

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/python
#--------------------------------------
#  RPM Zero.
#  A program meant to run in the background, and
#  reset the RPM display to 0 RPM if there haven't been
#  any changes in about 5 seconds.
#
#  Modified and extended for the MotoMast Control
#  By Courtney E. Krehbiel, October 2015
#
#--------------------------------------

# The wiring for the LCD is as follows:
# 1 : GND
# 2 : 5V
# 3 : Contrast (0-5V)*
# 4 : RS (Register Select)
# 5 : R/W (Read Write)       - GROUND THIS PIN
# 6 : Enable or Strobe
# 7 : Data Bit 0             - NOT USED
# 8 : Data Bit 1             - NOT USED
# 9 : Data Bit 2             - NOT USED
# 10: Data Bit 3             - NOT USED
# 11: Data Bit 4
# 12: Data Bit 5
# 13: Data Bit 6
# 14: Data Bit 7
# 15: LCD Backlight +5V**
# 16: LCD Backlight GND

#import
import RPi.GPIO as GPIO
import time
import json

# Define GPIO to LCD mapping
LCD_RS = 14
LCD_E  = 15
LCD_D4 = 17
LCD_D5 = 18
LCD_D6 = 27
LCD_D7 = 22


# 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

#CEK Global Variables for MotoMast
sRPM = "RPM: 0.00"
SavedHeight = 0
JustClearedRPM = 0
MovementDetected = 0
SmallSleep = 3
def setup():
	# Setup 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()
  

	with open('ids.json', "r") as fp:	# Get current position count from disk
		SavedHeight = json.load(fp)	
	fp.close()



def swcount(ev=None):	#This is the routine that runs and checks to see if there's activity in ids.json
	global SavedHeight
	global MovementDetected
	
	with open('ids.json', "r") as fp:	# Get current position count from disk
		HeightNow = json.load(fp)	
	fp.close()

	if HeightNow == SavedHeight:		# No movement has occurred.
		MovementDetected = 0
		time.sleep(SmallSleep)		# No sense checking every millisecond
		pass
	else: 
		MovementDetected = 1		# ids.json has changed, so movement is occurring.
		SavedHeight = HeightNow		# Setup to see if it keeps moving
		time.sleep(SmallSleep)		# wait 5 seconds 
		with open('ids.json', "r") as fp:	# Get current position count from disk
			HeightNow = json.load(fp)	
		fp.close()
		if HeightNow == SavedHeight:	# No movement for 5 seconds, so let's set RPM display to 0
			lcd_string(sRPM, LCD_LINE_2)
						# Let's also check to see if we should reset height at 10 feet to eliminate small click errors.
			if abs(HeightNow) <= 3:
				with open ('ids.json', 'w') as fp:	# If we are within 3 revs of bottom, reset height to 0 which is 10 foot dock height.
					json.dump(0, fp)
				fp.close()
				lcd_string("Height Ft: 10.00", LCD_LINE_1)	# Write this out to the display too
				HeightNow = 0
				SavedHeight = 0					# Update these guys too
		else:
			pass			# Must still be moving

	

# A few more lines from CEK to set the overall loop
	
def loop():
	while True:	
		swcount()

def destroy():
	lcd_byte(0x01, LCD_CMD)				#Clear display
	lcd_string("Goodbye!",LCD_LINE_1)

	GPIO.cleanup()			#Release resources



# End of CEK code
  
  
  
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__':
	setup()
	try:
		loop()
	except KeyboardInterrupt:  #When 'Ctrl-C' is pressed, the child program destroy() will be executed.
		pass
	finally:
		destroy()
	
	

 

Code for launching script, Launcher.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#!/bin/sh
# launcher.sh
# Navigate to home directory, then to this directory, then execute python script, then back home.

cd /
cd /home/pi/code
sudo python sw-shutdown3.py &
sudo python rpmzero.py &
sudo python motomast2.py
cd /
cd home/pi/code