My Question is for the very end, I am trying to get the script to clear the display and disable the backlight when Control + C is pressed in linux, half of the time the lcd display will not clear
I have tried to get the python to close properly and clear the display but it only works a portion of time, even with sleep(1) added
#!/usr/bin/env python
import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import fcntl
import time
import os
import re
from time import sleep
PIN = 23
COUNT = 0
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIN,GPIO.IN,pull_up_down=GPIO.PUD_UP)
print('Writing to Display!')
disp = lcd_driver.lcd()
def cputemp():
while True:
cputemp = os.popen("vcgencmd measure_temp").readline()
celsius = re.sub("[^0123456789/.]", "", cputemp)
fahrenheit = int(9.0/5.0*int(float(celsius)+32))
disp.lcdstring("Cpu : {} C".format(celsius), 1)
disp.lcdstring("Temp: {} F".format(fahrenheit), 2)
button = GPIO.input(PIN)
if button == False:
break
def curtime():
while True:
disp.lcdstring("Time: {}".format(time.strftime("%H:%M:%S")), 1)
disp.lcdstring("Date: {}".format(time.strftime("%m/%d/%Y")), 2)
button = GPIO.input(PIN)
if button == False:
break
def getaddr(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915,
struct.pack('256s', ifname[:15])
)[20:24])
def getip():
ip = getaddr('wlan0')
while True:
disp.lcdstring("IP Address: WiFi", 1)
disp.lcdstring(ip, 2)
button = GPIO.input(PIN)
if button == False:
break
try:
while True:
button = GPIO.input(PIN)
if button == True:
if COUNT == 0:
disp.lcdstring("Press the Button",1,0)
disp.lcdstring("To Start Demo!",2,1)
if COUNT == 1:
disp.clear()
cputemp()
if COUNT == 2:
disp.clear()
curtime()
if COUNT == 3:
disp.clear()
getip()
if COUNT == 4:
disp.clear()
COUNT = 1
if COUNT > 4:
disp.clear()
COUNT = 0
if button == False:
COUNT = COUNT +1
sleep(0.5)
except KeyboardInterrupt:
pass
finally:
disp.clear()
disp.backlight(0)
GPIO.cleanup()
import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep
def exit_handler():
print(' Cleaning Up!')
disp.clear()
disp.backlight(0)
GPIO.cleanup()
exit(1)
try:
while True:
button = GPIO.input(PIN)
if button == True:
if COUNT == 0:
disp.lcdstring("Press the Button",1,0)
disp.lcdstring("To Start Demo!",2,1)
if COUNT == 1:
disp.clear()
cputemp()
if COUNT == 2:
disp.clear()
curtime()
if COUNT == 3:
disp.clear()
getip()
if COUNT == 4:
disp.clear()
COUNT = 1
if COUNT > 4:
disp.clear()
COUNT = 0
if button == False:
COUNT = COUNT +1
sleep(0.5)
except KeyboardInterrupt:
pass
finally:
atexit.register(exit_handler)
You can add a shutdown hook using the atexit module
example code:
import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep
def exit_handler():
print(' Cleaning Up!')
disp.clear()
disp.backlight(0)
GPIO.cleanup()
exit(1)
atexit.register(exit_handler)
try:
while True:
button = GPIO.input(PIN)
if button == True:
if COUNT == 0:
disp.lcdstring("Press the Button",1,0)
disp.lcdstring("To Start Demo!",2,1)
if COUNT == 1:
disp.clear()
cputemp()
if COUNT == 2:
disp.clear()
curtime()
if COUNT == 3:
disp.clear()
getip()
if COUNT == 4:
disp.clear()
COUNT = 1
if COUNT > 4:
disp.clear()
COUNT = 0
if button == False:
COUNT = COUNT +1
sleep(0.5)
except KeyboardInterrupt:
pass
I use it on OrangePI to close a value when my code crash/exit and it works every time
Working code!!!
For Simplicity, being I can't vote yet
The difference is importing the atexit library
Adding in the event handler at top of code and replacing lcd.clear with lcd_driver.lcd()
And omitting the keyboard interrupt and following code to reflect how it is currently
#!/usr/bin/env python
import RPi.GPIO as GPIO
import lcd_driver
import socket
import struct
import atexit
import fcntl
import time
import os
import re
from time import sleep
PIN = 23
COUNT = 0
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(PIN,GPIO.IN,pull_up_down=GPIO.PUD_UP)
print('Writing to Display!')
disp = lcd_driver.lcd()
def exit_handler():
disp = lcd_driver.lcd()
disp.backlight(0)
GPIO.cleanup()
atexit.register(exit_handler)
def cputemp():
while True:
cputemp = os.popen("vcgencmd measure_temp").readline()
celsius = re.sub("[^0123456789/.]", "", cputemp)
fahrenheit = int(9.0/5.0*int(float(celsius)+32))
disp.lcdstring("Cpu : {} C".format(celsius), 1)
disp.lcdstring("Temp: {} F".format(fahrenheit), 2)
button = GPIO.input(PIN)
if button == False:
break
def curtime():
while True:
disp.lcdstring("Time: {}".format(time.strftime("%H:%M:%S")), 1)
disp.lcdstring("Date: {}".format(time.strftime("%m/%d/%Y")), 2)
button = GPIO.input(PIN)
if button == False:
break
def getaddr(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915,
struct.pack('256s', ifname[:15])
)[20:24])
def getip():
ip = getaddr('wlan0')
while True:
disp.lcdstring("IP Address: WiFi", 1)
disp.lcdstring(ip, 2)
button = GPIO.input(PIN)
if button == False:
break
try:
while True:
button = GPIO.input(PIN)
if button == True:
if COUNT == 0:
disp.lcdstring("Press the Button",1,0)
disp.lcdstring("To Start Demo!",2,1)
if COUNT == 1:
disp.clear()
cputemp()
if COUNT == 2:
disp.clear()
curtime()
if COUNT == 3:
disp.clear()
getip()
if COUNT == 4:
disp.clear()
COUNT = 1
if COUNT > 4:
disp.clear()
COUNT = 0
if button == False:
COUNT = COUNT +1
sleep(0.5)
except KeyboardInterrupt:
pass
Related
I have a Python script where I would like to replace the sleep() with wait in order to interrupt the threads instantly even when they are sleeping.
However I don't know how to transform my functions into Events.
I read that asyncio could also be used but I am not sure to understand how it works.
Here is the code :
from pynput import keyboard
from pynput.keyboard import Key, Controller
import datetime
import time
import threading
import random
import pyautogui
from threading import Event
# --- functions ---
keyboardCtrl = Controller()
def run():
print('Running thread')
time.sleep(random.randrange(150,350)/1000)
while running:
my_keylist1=['e']
while len(my_keylist1) > 0:
n = random.choice(my_keylist1)
keyboardCtrl.press(n)
#print('Time:',datetime.datetime.now(),n)
my_keylist1.remove(n)
time.sleep(random.randrange(10200,10450)/1000)
print('Exiting thread 1')
def run2():
time.sleep(random.randrange(150,350)/1000)
while running:
pyautogui.keyDown('z')
#print('T2',datetime.datetime.now())
#time.sleep(random.randrange(1000,3000)/1000)
print('Exiting thread 2')
pyautogui.keyUp('z')
def run3():
time.sleep(random.randrange(150,350)/1000)
while running:
my_keylist1=['f']
while len(my_keylist1) > 0:
n = random.choice(my_keylist1)
keyboardCtrl.press(n)
#print('Time:',datetime.datetime.now(),n)
my_keylist1.remove(n)
time.sleep(random.randrange(6250,6550)/1000)
print('Exiting thread 3')
def on_press(key):
global running # inform function that it has to assign value to external variable
global clicker
global clicker2,clicker3
try: # PEP8: don't put it in one line - it make code unreadable for human
k = key.char
except:
k = key.name
if key == keyboard.KeyCode(char='q'):
print("Key Pressed")
if not running: # the same as `if running == False:`
print("Starting thread")
clicker = threading.Thread(target=run)
clicker2 = threading.Thread(target=run2)
clicker3 = threading.Thread(target=run3)
running = True # it has to be before `start()`
clicker.start()
clicker2.start()
clicker3.start()
else:
print("Stopping thread")
running = False # it has to be before `join()`
clicker.join()
clicker2.join()
clicker3.join()
# press `F1` to exit
if key == keyboard.Key.f1:
return False
# --- main ---
running = False # default value at start
try:
print("Starting program")
print("- press E to start/stop thread")
print("- press F1 to exit")
print("- press Ctrl+C to exit")
lis = keyboard.Listener(on_press=on_press)
lis.start()
print("Listening ...")
lis.join()
print("Exiting program")
except KeyboardInterrupt:
print("Stoped by Ctrl+C")
else:
print("Stoped by F1")
finally:
if running:
running = False
clicker.join()
clicker2.join()
clicker3.join()
Maybe you can try something like, I am sure there is a better solution, I would suggest reading the documentation.
import asyncio
from pynput import keyboard
from pynput.keyboard import Key, Controller
import datetime
import time
import threading
import random
import pyautogui
from threading import Event
# --- functions ---
keyboardCtrl = Controller()
async def run():
print('Running thread')
await asyncio.sleep(random.randrange(150, 350) / 1000)
while running:
my_keylist1 = ['e']
while len(my_keylist1) > 0:
n = random.choice(my_keylist1)
keyboardCtrl.press(n)
# print('Time:',datetime.datetime.now(),n)
my_keylist1.remove(n)
#time.sleep(random.randrange(10200, 10450) / 1000)
await asyncio.sleep(random.randrange(10200, 10450) / 1000)
print('Exiting thread 1')
async def run2():
#time.sleep(random.randrange(150, 350) / 1000)
await asyncio.sleep(random.randrange(150, 350) / 1000)
while running:
pyautogui.keyDown('z')
# print('T2',datetime.datetime.now())
# time.sleep(random.randrange(1000,3000)/1000)
print('Exiting thread 2')
pyautogui.keyUp('z')
async def run3():
#time.sleep(random.randrange(150, 350) / 1000)
await asyncio.sleep(random.randrange(150, 350) / 1000)
while running:
my_keylist1 = ['f']
while len(my_keylist1) > 0:
n = random.choice(my_keylist1)
keyboardCtrl.press(n)
# print('Time:',datetime.datetime.now(),n)
my_keylist1.remove(n)
#time.sleep(random.randrange(6250, 6550) / 1000)
await asyncio.sleep(random.randrange(6250, 6550) / 1000)
print('Exiting thread 3')
async def on_press(key):
global running # inform function that it has to assign value to external variable
global clicker
global clicker2, clicker3
try: # PEP8: don't put it in one line - it make code unreadable for human
k = key.char
except:
k = key.name
if key == keyboard.KeyCode(char='q'):
print("Key Pressed")
if not running: # the same as `if running == False:`
print("Starting thread")
#await run()
#await run2()
#await run3()
await asyncio.gather(*[run(), run2(), run3()])
#clicker = threading.Thread(target=run)
#clicker2 = threading.Thread(target=run2)
#clicker3 = threading.Thread(target=run3)
running = True # it has to be before `start()`
#clicker.start()
#clicker2.start()
#clicker3.start()
else:
print("Stopping thread")
running = False # it has to be before `join()`
#clicker.join()
#clicker2.join()
#clicker3.join()
# press `F1` to exit
if key == keyboard.Key.f1:
return False
# --- main ---
running = False # default value at start
def main(*args, **kwargs):
asyncio.run(on_press(args[0]))
try:
print("Starting program")
print("- press E to start/stop thread")
print("- press F1 to exit")
print("- press Ctrl+C to exit")
lis = keyboard.Listener(on_press=main)
lis.start()
print("Listening ...")
lis.join()
print("Exiting program")
except KeyboardInterrupt:
print("Stoped by Ctrl+C")
else:
print("Stoped by F1")
finally:
if running:
running = False
#clicker.join()
#clicker2.join()
#clicker3.join()
My code will start (pressing p) and stop (pressing o) the loop once, but won't start the loop again, what am I doing wrong?
import pyautogui, time, keyboard
while True:
if keyboard.is_pressed('p'):
print("Rodando")
x=0
while True:
if x == 0:
pyautogui.press("F7")
pyautogui.press("F7")
print("a")
time.sleep(0.1)
pyautogui.press("F7")
pyautogui.press("F7")
print("b")
time.sleep(0.5)
if keyboard.is_pressed('o'):
print("abortando")
x = 1
Try this code.
import pyautogui, time, keyboard
A = False
def start_loop():
global A
while True:
if keyboard.is_pressed('p') or A:
print("Rodando")
A = True
x=0
while True:
if x == 0:
pyautogui.press("F7")
pyautogui.press("F7")
print("a")
time.sleep(0.1)
pyautogui.press("F7")
pyautogui.press("F7")
print("b")
time.sleep(0.5)
if keyboard.is_pressed('o'):
print("abortando")
x = 1
A = False
break
start_loop()
start_loop()
keyboard module does not always work if this happens then please press the key again😊.
I have not tried to find the last sector by multiplying the number of sectors by 10. I tried to find it by increasing 1 but the system was very tired and took a lot of time. I don't want to filter out the output of ready commands.
How can I find the number of cylinders, heads and sectors. I think I will get the number of sectors by converting from chs system to lba system.
import os
def main():
s=1
if os.name == "nt":
while True:
if read_sector(r"\\.\physicaldrive0",s)=='':
break
else:
s=s*10
print(s)
else:
while True:
if read_sector("/dev/sda",s)=='':
break
else:
s=s*10
print(s)
def read_sector(disk, sector_no=0):
f = open(disk, 'rb')
f.seek(sector_no * 1)
read = f.read(1)
return read
if __name__ == "__main__":
main()
or
import os
def main():
s=0
if os.name == "nt":
while True:
if read_sector(r"\\.\physicaldrive0",s)=='':
break
else:
s=s+1
print(s)
else:
while True:
if read_sector("/dev/sda",s)=='':
break
else:
s=s+1
print(s)
def read_sector(disk, sector_no=0):
f = open(disk, 'rb')
f.seek(sector_no * 1)
read = f.read(1)
return read
if __name__ == "__main__":
main()
import os
def end_sector(disk):
os.system("fdisk -l %s >fdisk.lst"%disk)
with open("fdisk.lst") as file:
dosya=file.read()
dosya=dosya.split()
j=0
for i in dosya:
j=j+1
for i in range(j):
if dosya[i]=="sektör":
max_sector=int(dosya[i-1])
for i in range(j):
if dosya[i]=="=" and dosya[i-1]==dosya[i+1]:
sector_size=int(dosya[i+1])
return max_sector,sector_size
dizi=end_sector("/dev/sdb")
print(dizi)
I have some Python for a Raspberry Pi where I test for a button press (first loop) and use it to start and stop a timer (second loop). However, if I run this program only the first loop in the sequence runs. How can I make it so both run at the same time? Code:
EDIT: made changes to code in attempt to accommodate threading. Would this work?
import os
os.chdir('/home/pi/Desktop/Python')
import lcd
lcd.lcd_init()
import time
import threading
from threading import Thread
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(23,GPIO.IN, pull_up_down=GPIO.PUD_UP)
latest_state = None
status = False
seconds = 0
minutes = 0
hours = 0
def button():
while True:
if status == True:
seconds +=1
if seconds == 59:
seconds = 0
minutes = minutes + 1
if minutes == 59:
minutes = 0
hours = hours + 1
tup = " H:",hours," M:",minutes," S:",seconds
display = ''.join(map(str, tup))
lcd.lcd_string(display,2)
time.sleep(0.99)
Thread(target = button).start()
while True:
inputValue = GPIO.input(23)
if inputValue != latest_state:
latest_state = inputValue
if latest_state:
print " "
else:
status = not status
print status
print " "
I'm trying to have a loop which increments and prints a value. While it's running I would like to press a key (eg. space or shift) and have it print that the key was pressed. Below is example code of what I would like.
def space():
print 'You pressed space'
def shift():
print 'You pressed shift'
x = 0
while True:
print(x)
#if space is pressed
space()
#if shift is pressed
shift()
x = x + 1;
time.sleep(1)
EDIT: Here is an example output
0
1
2
You pressed shift
3
4
5
You pressed space
6
7
.
.
.
I can help you with modified answer form here:
https://stackoverflow.com/questions/11918999/key-listeners-in-python
and for only space and enter:
import contextlib
import sys
import termios
import time
#contextlib.contextmanager
def raw_mode(file):
old_attrs = termios.tcgetattr(file.fileno())
new_attrs = old_attrs[:]
new_attrs[3] = new_attrs[3] & ~(termios.ECHO | termios.ICANON)
try:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, new_attrs)
yield
finally:
termios.tcsetattr(file.fileno(), termios.TCSADRAIN, old_attrs)
def space(ch):
if ord(ch) == 32:
print 'You pressed space'
def enter(ch):
if ord(ch) == 10:
print 'You pressed enter'
def main():
print 'exit with ^C or ^D'
with raw_mode(sys.stdin):
try:
x = 0
while True:
print(x)
ch = sys.stdin.read(1)
space(ch)
enter(ch)
x = x + 1;
time.sleep(1)
except (KeyboardInterrupt, EOFError):
pass
if __name__ == '__main__':
main()
If you're on windows, check out msvcrt:
import msvcrt
while True:
x += 1
sleep(x)
if msvcrt.kbhit():
print "You pressed: %s" % msvcrt.getch()