I'm currently writing a Python Telegram bot which is used to monitor Raspi IOs and send messages to a channel. So basically it has a function that will update a logging variable llog.
This function (logUpdate), as it's named, will remove entries that are more than 5 mins old. In it, I tried to check the content of the global variable. Upon printing, it just hangs.
This doesn't seem to block any other functionalities of the bot because I can still call out other bot commands.
I don't think it's the bot. It must be some kind of data access problems.
I attach some code snippet below:
#!usr/bin/python
##
### RF Security bot start script
##
##
### Imports
##
import telegram as tg
import telegram.ext as tgExt
import RPi.GPIO as gpio
import time
from datetime import datetime as dt
##
### Common variables
##
NULLSENSOR = 0
PRESSENSOR = 1
MAGSENSOR = 2
sensDict = {NULLSENSOR:"No sensor",
PRESSENSOR:"Pressure sensor",
MAGSENSOR:"Magnetic sensor"}
# Event class
class ev(object):
timestamp = 0
sType = NULLSENSOR
def __init__(self, ts=0, st=NULLSENSOR):
self.timestamp = ts
self.sType = st
def toString(self):
if(sType == PRESSENSOR):
return str("-> #"+timestamp.strftime('%c')+
": Pressure sensor triggered\n")
elif(sType == MAGSENSOR):
return str("-> #"+timestamp.strftime('%c')+
": Magnetic sensor triggered\n")
else:
return ""
# Report log
llog = [] # Data log
lmutex = True # Log mutex for writing
##
### Hardware configuration
##
# GPIO callbacks
def pressureCallback(channel):
global llog
global lmutex
global trigCntGlobal
global trigCntPress
ep = ev(ts=dt.now(), st=PRESSENSOR)
print("---> Pressure sensor triggered at "+
ep.timestamp.strftime("%c"))
rfSecuBot.sendMessage('#channel', "Pressure sensor "+
"triggered.")
while(not lmutex):
pass
lmutex = False
llog.insert(0, ep)
trigCntGlobal = trigCntGlobal + 1
trigCntPress = trigCntPress + 1
lmutex = True
def magneticCallback(channel):
global llog
global lmutex
global trigCntGlobal
global trigCntMag
global rfSecuBot
em = ev(ts=dt.now(), st=PRESSENSOR)
print("---> Magnetic sensor triggered at "+
em.timestamp.strftime("%c"))
rfSecuBot.sendMessage('#channel', "Magnetic sensor "+
"triggered.")
while(not lmutex):
pass
lmutex = False
llog.insert(0, em)
trigCntGlobal = trigCntGlobal + 1
trigCntMag = trigCntMag + 1
lmutex = True
# Periodic logging function
def logUpdate():
global llog
global lmutex
updTime = dt.now()
print("---> Updating log\n")
while(not lmutex):
pass
lmutex = False
for i in llog: ########### STUCK HERE
print(i.toString()) ###########
# Check log timestamps
for i in llog:
if((updTime - i.timestamp).total_seconds() > 300):
llog.remove(i)
for i in llog: ########### WAS STUCK HERE
print(i.toString()) ########### TOO
lmutex = True
print("---> Log updated\n")
# Formatting function
def logFormat():
global llog
global lmutex
logUpdate() # Asynchronous call to logUpdate to make sure
# that the log has been updated at the time
# of formatting
while(not lmutex):
pass
lmutex = False
flog = []
cnt = 0
for i in llog:
if(cnt < 10):
flog.append(i.toString())
cnt = cnt + 1
else:
break
lmutex = True
print("----> Formatted string:")
print(flog+"\n")
return flog
def listFormat():
global llog
global lmutex
logUpdate() # Asynchronous call to logUpdate to make sure
# that the log has been updated at the time
# of formatting
while(not lmutex):
pass
lmutex = False
flog = []
flog.append(" Sensors \n")
dLen = len(sensDict.keys())
if(dLen <= 1):
flog.append(sensDict.get(NULLSENSOR))
else:
sdItr = sensDict.iterkeys()
st = sdItr.next() # Had to add extra var
while(dLen > 1):
st = sdItr.next()
trigCnt = 0
for i in llog:
if(i.sType == st):
trigCnt = trigCnt + 1
if(trigCnt < 1):
pass
else:
flog.append("-> "+st+"\n")
flog.append(" No. of times tripped: "+
trigCnt+"\n")
lmutex = True
print("----> Formatted string:")
print(flog+"\n")
return flog
##
### Software configuration
##
def blist(bot, update):
print("--> List command received\n")
listString = "List of sensor trips in the last 5 minutes:\n"
listString = listString+listFormat()
print("> "+listString+"\n")
bot.sendMessage('#channel', listString)
def log(bot, update):
print("--> Log command received\n")
logString = "Log of last 10 occurrences:\n"
logString = logString+logFormat()
print("> "+logString+"\n")
bot.sendMessage('#channel', logString)
rfSecuBotUpd.start_polling(poll_interval=1.0,clean=True)
while True:
try:
time.sleep(1.1)
except KeyboardInterrupt:
print("\n--> Ctrl+C key hit\n")
gpio.cleanup()
rfSecuBotUpd.stop()
rfSecuBot = 0
quit()
break
## Callback registration and handlers are inserted afterwards
# Just in case...
print("--> Bot exiting\n")
gpio.cleanup()
rfSecuBotUpd.stop()
rfsecuBot = 0
print("\n\n\t *** EOF[] *** \t\n\n")
quit()
# EOF []
P.S. I think someone might suggest a 'class' version of this. Think it'll work?
In the toString function, I forgot to put self in front of the should-be members sType and timestamp:
def toString(self):
if(sType == PRESSENSOR):
return str("-> #"+timestamp.strftime('%c')+
": Pressure sensor triggered\n")
elif(sType == MAGSENSOR):
return str("-> #"+timestamp.strftime('%c')+
": Magnetic sensor triggered\n")
else:
return ""
Which is why the value returned was always an empty string.
Note to self: check your variables!!!
On that note, that kind of explained why it didn't seem to block the thread.
Related
ive been trying to create a stream client using tweepy to fetch new tweets under a user-given hashtag. I've managed to achieve this using the following code successfully.
import tweepy
class IDPrinter(tweepy.StreamingClient):
def on_tweet(self,tweet):
#now = datetime.now()
#current_time = now.strftime("%H:%M:%S")
#print("Current Time =", current_time)
print(f"{tweet.id} \n {tweet.created_at} \n {tweet.author_id} \n {tweet.text}")
#https://docs.tweepy.org/en/v3.4.0/streaming_how_to.html
def on_error(self, tweet_code):
if tweet_code == 420:
return False
def cleanUP(self,printer):
print("test")
rule_ids = []
rules = printer.get_rules()
if str(rules).find("id") == -1:
print(rules)
return
else:
for rule in rules.data:
rule_ids.append(rule.id)
if(len(rule_ids) > 0):
printer.delete_rules(rule_ids)
print("rules have been reset")
else:
print("no rules to delete")
def Caller(self,value,printer):
#print("test")
printer.add_rules(tweepy.StreamRule(f"#{value} lang:en -is:retweet"))
printer.filter(expansions="author_id", tweet_fields="created_at")
But I want the user to be able to stop the stream of new tweets whenever he wants to. Ive been testing the following code but I can't get the tweepy stream loop to terminate on button click. This is my current attempt but I can't understand why is not working.
def on_button_clicked(event):
global break_cicle
break_cicle = False
print("Button pressed: break_cicle:", break_cicle)
class IDPrinter(tweepy.StreamingClient):
def on_tweet(self,tweet):
print(f"{tweet.id} \n {tweet.created_at} \n {tweet.author_id} \n {tweet.text}")
#https://docs.tweepy.org/en/v3.4.0/streaming_how_to.html
def on_error(self, tweet_code):
if tweet_code == 420:
return False
def cleanUP(self,printer):
print("test")
rule_ids = []
rules = printer.get_rules()
if str(rules).find("id") == -1:
print(rules)
return
else:
for rule in rules.data:
rule_ids.append(rule.id)
if(len(rule_ids) > 0):
printer.delete_rules(rule_ids)
print("rules have been reset")
else:
print("no rules to delete")
def Call(self,value,printer):
while break_cicle:
button.on_click(on_button_clicked)
printer.add_rules(tweepy.StreamRule(f"#{value} lang:en -is:retweet"))
printer.filter(expansions="author_id", tweet_fields="created_at")
time.sleep(1)
printer = IDPrinter("bearer key")
printer.cleanUP(printer)
hashtag = input("Give a hashtag: ")
button = widgets.Button(description="STOP!")
output = widgets.Output()
display(button, output)
break_cicle = True
button.on_click(on_button_clicked)
threading.Thread(target=printer.Call(hashtag,printer)).start()
basically i tried to create a button which on event click will change the variable break_circle and terminate the while loop onside def call.
Please let me know if I need to provide more info. This is for a soundboard setup- it's a raspberry-pi 4 with an attached 10-key. It works insofar as it plays the correct sound when I press a key, but the sound plays on a loop.
I see a section that says "Play an audio track indefinitely" but I have no idea if this is what I need to edit. Is this correct?
#!/usr/bin/python3
import os
import sys
import vlc
import time
inputs = ['\'1\'', '\'2\'', '\'3\'', '\'4\'', '\'5\'', '\'6\'', '\'7\'', '\'8\'', '\'9\'', '\'0\'']
special = ['\'*\'', '\'+\'', '\'-\'', '\'+\'', '\'/\'', '\'.\'']
instance = vlc.Instance('--input-repeat=999999')
player = instance.media_player_new()
def loadPresets():
''' Get all the Presets in the current directory '''
l = []
for file in os.listdir(os.getcwd()):
if file.endswith(".preset"):
print("Preset Found:", os.path.join(os.getcwd(), file))
l.append(os.path.join(os.getcwd(), file))
return l
def getPresetTracks(preset):
''' Get all the links inside of a preset track '''
l = []
with open(preset) as file:
for line in file:
# Need to get rid of those pesky \n's
print(str(len(l)) + ': ', line[:-1])
l.append(line[:-1])
if len(l) < 10:
print("Too little links. Cannot correctly populate.")
l = []
elif len(l) > 10:
print("Too many links. Cannot correctly populate.")
l = []
return l
def isYouTubeAudio(link):
import re
if re.match(r'http[s]:\/\/www\.youtube\.com/watch\?v=([\w-]{11})', link) == None:
return False
else:
return True
def getYouTubeAudioTrack(link):
''' Get Audio track of a link '''
import pafy
video = pafy.new(link)
bestaudio = video.getbestaudio()
# print(bestaudio.url)
return bestaudio.url
def playQuick(num):
''' Make quick sound '''
l = ['up.mp3', 'down.mp3', 'preset_change.mp3', 'startup.mp3']
s = instance.media_new(os.path.join(os.getcwd(), l[num]))
player.set_media(s)
player.play()
if num == 3:
time.sleep(4)
else:
time.sleep(1)
player.stop()
def switchPresets(readyPresets):
playQuick(2)
print("Ready to swap the preset. Loaded presets:")
i = 0
for link in readyPresets:
print(i, "-", link)
i += 1
newPreset = input("What would you like your preset to be?: ")
if newPreset.isdigit() and int(newPreset) < len(presetList):
# Number preset. We're goood
numPre = int(newPreset)
print("New Preset: ", numPre)
playQuick(0)
return numPre
else:
# It's a character. Stop
print("Invalid preset. Skipping.")
playQuick(1)
return None
def playTrack(track):
''' Play an audio track indefinetly. Also awaits response so it can detect a change in information '''
from readchar import readkey
# Load and add media file
media = instance.media_new(track)
player.set_media(media)
# Play
player.play()
# Pause before getting the status, to update everything
print(str(player.get_state()) + " ", end='\r')
sys.stdout.flush()
time.sleep(1)
print(str(player.get_state()) + " ")
if __name__ == '__main__':
presetList = loadPresets()
preset = getPresetTracks(presetList[0])
# Start Up and initial setup
active = False
playQuick(3)
import readchar
keyInput = '\'0\''
# Start Main loop
print("Ready for input")
while keyInput not in inputs or keyInput not in special:
keyInput = repr(readchar.readkey())
# Sanitize input
if keyInput in inputs:
# Play sound
santized = int(keyInput[1])
player.stop()
active = True
# print(preset[santized])
if isYouTubeAudio(preset[santized]):
playTrack(getYouTubeAudioTrack(preset[santized]))
else:
playTrack(preset[santized])
# Special Characters
elif keyInput == special[0]: # '\'*\'
# Preset
active = False
player.stop()
np = switchPresets(presetList)
if np != None:
preset = getPresetTracks(presetList[np])
elif keyInput == special[1]: # '\'+\''
# Play/Pause. +
if active:
player.pause()
active = False
else:
player.play()
active = True
elif keyInput == special[2]: # '\'-\''
pass
elif keyInput == '\'x\'':
# End case
exit()
I have the following Python code that has an if condition that checks to see if current_ident is the same as last ident and if so then not print the current_ident value.
What I would like to do is add a time-out to this check so only check to see if the current and last is the same for 7 seconds after that let it print if it's the same. I'm thinking possible by adding a global variable last_read which saves the time and then maybe use something like last_read + [timeout] > [current_time]?
from nfc import ContactlessFrontend
from time import sleep
ident = ''
def connected(tag):
global ident
current_ident = ''.join('{:02x}'.format(ord(c)) for c in tag.identifier)
if current_ident != ident:
print(current_ident)
ident = current_ident
return False
clf = ContactlessFrontend('usb')
while True:
clf.connect(rdwr={'on-connect': connected})
sleep(1)
You should be able to keep a track of time as well as the last ident:
from nfc import ContactlessFrontend
from time import sleep
import time
ident = ''
next_time = None
def connected(tag):
global ident
global next_time
current_ident = ''.join('{:02x}'.format(ord(c)) for c in tag.identifier)
if current_ident != ident:
next_time = time.time() + 7
print(current_ident) # Brand new ident
ident = current_ident
elif time.time() > next_time:
next_time = time.time() + 7
print(current_ident) # Repeated ident allowed
# else: # disallow repeated ident
return False
clf = ContactlessFrontend('usb')
while True:
clf.connect(rdwr={'on-connect': connected})
sleep(1)
I am creating a Telegram Bot using pyTelegramBotAPI that sends real-time updates of ongoing cricket matches. I want to break the loop whenever the user enters the "/stop" command. I've looked up various sources and also tried several methods to achieve the same but all in vain. The loop continues to iterate. The closest I've reached is by exiting the program by raising an error. Also, while inside the loop, the getUpdates method always returns an empty list. I've also written an issue for the same on GitHub.
def loop(match_url):
prev_info = ""
flag = 1
#continuously fetch data
while flag:
response = requests.get(match_url)
info = response.json()['score']
#display only when the score updates
if str(info) != prev_info:
prev_info = str(info)
send_msg(info)
else:
pass
send_msg(info)
#this handler needs to be fixed
#bot.message_handler(commands=['stop', 'end'])
def stop(message):
#code to break the loop
flag = 0
return
Since this was not working, I willingly used this wrong method:
while flag:
response = requests.get(match_url)
info = response.json()['score']
if str(info) != prev_info:
prev_info = str(info)
send_msg(info)
else:
pass
send_msg(info)
#bot.message_handler(commands=['stop', 'end'])
def stop(message):
bot.polling.abort = True #an arbitrary function that raises error and exits the program
Here's the whole code. I've also added my GitHub link of this code:
import requests, json, telebot
token = <TOKEN>
bot = telebot.TeleBot(token)
#parsing data from cricapi.com
def live_matches():
#here I'm using the KEY obtained from cricapi.com
curr_matches_url = "https://cricapi.com/api/cricket?apikey=<KEY>"
curr_matches = requests.get(curr_matches_url)
match_data = curr_matches.json()['data']
global unique_id_arr, score_arr
unique_id_arr, score_arr = [], []
match_details = ""
for i in match_data:
unique_id_arr.append(i["unique_id"])
for i in range(len(match_data)):
score_arr.append(match_data[i]["title"])
score_arr[i] += "\n"
match_details += str(i+1) + ". "
match_details += score_arr[i]
send_msg(match_details)
def send_msg(msg):
url2 = 'https://api.telegram.org/bot'+token+'/sendMessage'
data = {'chat_id': chat_id, 'text': msg}
requests.post(url2, data).json()
#bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
bot.reply_to(message, "Howdy, how are you doing?")
global chat_id
chat_id = message.chat.id
msg = bot.reply_to(message, "Welcome to test project\nEnter the match number whose updates you want to receive")
live_matches()
bot.register_next_step_handler(msg, fetch_score)
def fetch_score(message):
chat_id = message.chat.id
match_no = message.text
#checking if the number entered is present in the displayed list
if not match_no.isdigit():
msg = bot.reply_to(message, 'Error1!\nSelect a no. from the above list only')
return bot.register_next_step_handler(msg, fetch_score)
elif 1 <= int(match_no) <= len(score_arr):
unique_id = unique_id_arr[int(match_no)-1]
global match_url
#get the data of the desired match
match_url = "https://cricapi.com/api/cricketScore?unique_id="+unique_id+"&apikey=<KEY>"
loop(match_url)
else:
msg = bot.reply_to(message, "Error2!\nSelect a no. from the above list only")
return bot.register_next_step_handler(msg, fetch_score)
def loop(match_url):
prev_info = ""
flag = 1
#continuously fetch data
while flag:
response = requests.get(match_url)
info = response.json()['score']
#display only when the score updates
if str(info) != prev_info:
prev_info = str(info)
send_msg(info)
else:
pass
send_msg(info)
#this handler needs to be fixed
#bot.message_handler(commands=['stop', 'end'])
def stop(message):
#an arbitrary function that raises error and then exits
bot.polling.abort = True
bot.polling()
"""
#currently not using
def receive_msg():
url1 = 'https://api.telegram.org/bot'+token+'/getUpdates'
response = requests.get(url1)
text = response.json()['result']
if len(text) > 0:
user_msg = text[-1]['message']['text']
return user_msg
return text
"""
You are using telebot(pyTelegramBotAPI) package in the wrong way:
Why did you create your own function send_msg where there is already send_message method in telebot exists?
You are redeclaring your "stop" handler in the loop, which is wrong!
My suggestion to you is to learn how to use the pyTelegramBotAPI properly!
Here is a demonstration code, that solves your problem:
import telebot
from time import sleep
bot = telebot.TeleBot(BOT_TOKEN)
flag = 1
#bot.message_handler(commands=['loop'])
def loop(msg):
while flag:
bot.send_message(msg.chat.id, "ping")
sleep(1)
#bot.message_handler(commands=['stop', 'end'])
def stop(msg):
global flag
flag = 0
bot.send_message(msg.chat.id, "stopped")
bot.polling(none_stop=True)
Explanation:
Declared flag as a global variable and set it to 1
"loop" handler for starting the loop that sends you "ping" message every second
"stop" handler that changes flag to 0, which terminates your running loop
i manipulate a sensor : HC SR04 to capture a distance.
I'm a newbie in Python and RPI. My code work, I capture distance during a time but one moment the script stop...
My code :
GPIO.setmode(GPIO.BCM)
GPIO_TRIGGER = 23
GPIO_ECHO = 24
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
def main():
global state
print("ultrasonic")
while True:
print "1s second refresh.."
time.sleep(1)
i = 0
datas = []
average = 0
while i< 1:
GPIO.output(GPIO_TRIGGER, False)
time.sleep(C.time['count'])
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
while GPIO.input(GPIO_ECHO) == 0:
start = time.time()
while GPIO.input(GPIO_ECHO) == 1:
stop = time.time()
distance = (stop-start) * 17000
print "Distance : %.1f" % distance
average = F.getAverage(datas)
print "Average: %.1f" % average
GPIO.cleanup()
The code stop here
while GPIO.input(GPIO_ECHO) == 0:
start = time.time()
THE SOLUTION : with a sample timeout :
now = time()
while GPIO.input(self.gpio_echo) == 0 and time()-now<waitTime:
pass
I am also mucking about with this sensor. My code executes similar to yours and I need no timeout for it to work.
The one difference I can find is this:
while i< 1:
GPIO.output(GPIO_TRIGGER, False)
time.sleep(C.time['count'])
I don't know how long the sleep time is here, but it might be that that's causing the problem. If it would be similar to mine setting the Trigger to false would be directly after the setup of the in/out pins instead, and then there's a two second wait to eliminate noise. Your wait time might be lower, I can't tell. There should be no need to set the trigger to false again just before you send the pulse and, I don't know, but it might be causing a false start. I would change it to this to work similarly to mine and then remove the setting to false in the while loop.
GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
GPIO.setup(GPIO_ECHO, GPIO.IN)
GPIO.output(GPIO_TRIGGER, False)
print("Waiting for sensor to settle\n")
time.sleep(2)
I'm not sure if this will solve the issue without the need for a timeout, but I don't seem to need one.
I've written a module for making an object of the sensor which then allows for some more readable scripting. I'm also quite new to python and not at all an experienced programmer so fun errors might be there somewhere, but it's here below if you want to use it or just compare code:
#! /usr/bin/python3
# dist.py this is a module for objectifying an ultrasonic distance sensor.
import RPi.GPIO as GPIO
import time
class Distancer(object):
#init takes an input of one GPIO for trigger and one for echo and creates the object,
#it searches for a calibration file in the working directory (name)Const.txt, if none
#is found it will initiate a calibration
def __init__(self, trig, cho, name):
self.trigger = trig
self.echo = cho
self.name = name
self.filename = self.name + 'Const.txt'
GPIO.setup(self.trigger, GPIO.OUT)
GPIO.setup(self.echo, GPIO.IN)
GPIO.output(self.trigger, False)
print("Waiting for sensor to calm down")
time.sleep(2)
try:
with open(self.filename, "r") as inConst:
self.theConst = int(inConst.read())
except (OSError, IOError) as e:
print("Not calibrated, initializing calibration")
self.calibrate()
with open(self.filename, "r") as inConst:
self.theConst = int(inConst.read())
#Returns the echo time
def measureTime(self):
GPIO.output(self.trigger, True)
time.sleep(0.00001)
GPIO.output(self.trigger, False)
while GPIO.input(self.echo) == 0:
pulse_start = time.time()
while GPIO.input(self.echo) == 1:
pulse_end = time.time()
pulse_duration = pulse_end - pulse_start
return pulse_duration
#Returns a distance in cm
def measure(self):
return self.measureTime() * self.theConst
#Makes you set up the sensor at 3 different distances in order to find the
#relation between pulse time and distance, it creates the file (name)Const.txt
#in the working directory and stores the constant there.
def calibrate(self):
ten = []
thirty = []
seventy = []
print("Make distance 10 cm, enter when ready")
input()
for i in range(30):
ten.append(10/self.measureTime())
time.sleep(0.2)
print("Make distance 30 cm, enter when ready")
input()
for i in range(30):
thirty.append(30/self.measureTime())
time.sleep(0.2)
print("Make distance 70 cm, enter when ready")
input()
for i in range(30):
seventy.append(70/self.measureTime())
time.sleep(0.2)
allTime = ten + thirty + seventy
theOne = 0.0
for i in range(90):
theOne = theOne + allTime[i]
theOne = theOne / 90
with open(self.filename, "w") as inConst:
inConst.write(str(round(theOne)))
#Will continually check distance with a given interval until something reaches the
#treshold (cm), takes an argument to set wether it should check for something being
#nearer(near) or farther(far) than the treashold. Returns True when treshold is reached.
def distWarn(self, nearfar, treashold):
if nearfar.lower() == "near":
while True:
if self.measure() < treashold:
return True
break
time.sleep(0.2)
if nearfar.lower() == "far":
while True:
if self.measure() > treashold:
return True
break
time.sleep(0.2)
#Will measure with a second interval and print the distance
def keepGoing(self):
while True:
try:
print(str(round(self.measure())) + ' cm')
time.sleep(1)
except KeyboardInterrupt:
print("Won't keep going")
break
I've run it with the code below to test it and everything seems to work. First time it's run it will prompt you to calibrate the sensor by putting it at different distances from something.
#! /usr/bin/python3
import RPi.GPIO as GPIO
import time
import dist as distancer
GPIO.setmode(GPIO.BOARD)
TRIG = 16
ECHO = 18
dist = distancer.Distancer(TRIG, ECHO, 'dist')
def main():
global dist
print(str(round(dist.measureTime(),5)) + ' s')
print(str(round(dist.measure())) + ' cm')
dist.distWarn('near', 10)
print('Warning, something nearer than 10 cm at ' + time.asctime( time.localtime(time.time()) ))
dist.distWarn('far', 10)
print('Warning, something further than 10 cm at ' + time.asctime( time.localtime(time.time()) ))
dist.keepGoing()
GPIO.cleanup()
print('Fin')
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
GPIO.cleanup()
print("Exiting")
time.sleep(1)
I am pretty sure you want
while GPIO.input(GPIO_ECHO)==GPIO.LOW:
start = time.time()
while GPIO.input(GPIO_ECHO) == GPIO.HIGH:
stop = time.time()
I don't think GPIO.input naturally returns zeros or ones, you can test that though.
Not really, I think that i lost the signal, i'll try a timeout in
while GPIO.input(GPIO_ECHO)==GPIO.LOW:
start = time.time()
I think that my program wait indefinitely a signal but he stay to 0
I know this is an old question. The cause of the problem was described in this question https://raspberrypi.stackexchange.com/questions/41159/...
The solution is to add a timeout, like the OP did, to the while loops similar to this:
# If a reschedule occurs or the object is very close
# the echo may already have been received in which case
# the following will loop continuously.
count=time.time()
while GPIO.input(GPIO_ECHO)==0 and time.time()-count<0.1:
start = time.time()
...
# if an object is not detected some devices do not
# lower the echo line in which case the following will
# loop continuously.
stop = time.time()
count=time.time()
while GPIO.input(GPIO_ECHO)==1 and time.time()-count<0.1:
stop = time.time()