I am trying to count people who break a laser beam (hardware works) and then post to google form.
code:
###################################################
######### People Counter v1-1 ############
###################################################
################################
###Setting up Python Modules####
################################
import RPi.GPIO as GPIO
import os, time
################################
##### Setting up GPIO pins #####
################################
RECEIVER_PIN = 23
################################
######Setting up Counters ######
################################
peoplecount = 0
uploadcount = 0
door = 1 # <- Use this to designate multiple doors for tracking
location = 'Entry' # <- Use this to designate multiple locations for tracking in one form
rpitemp = 'vcgencmd measure_temp | cut -c6-7' # Temperatur vom RPi
def callback_func(channel):
if GPIO.input(channel):
print("Lichtschranke wurde unterbrochen")
## This waits for a specified minute of the hour, checks if anyone has been detected since the last upload, then uploads the data to a Google Form.
# if time.strftime("%M") in ("13", "28", "43", "58") and peoplecount > 0 and uploadcount == 0:
global peoplecount
global uploadcount
if peoplecount > 0 and uploadcount == 0:
try:
url = 'https://docs.google.com/forms/d/e/1FAIpQLSduNOOwMUtpQc5QNFbcwPXQhD0MRppum3kkYHThkFvo0JluQw/formResponse?entry.664100658=%s&entry.1901373746=%s&entry.1382055524=%s&entry.718436324=%s&submit=Senden' % (location, door, peoplecount, rpitemp)
response = br.open(url)
print "People count uploaded with value %s on door %s at %s and RPi Temp %s" % (peoplecount, door, location, rpitemp)
uploadcount = 0
peoplecount = 0
print "values reset"
except:
print "Cannot Access Page"
elif time.strftime("%M") in ("38", "39", "40", "41") and uploadcount == 1:
uploadcount = 0
elif GPIO.input(RECEIVER_PIN) == True:
peoplecount = peoplecount + 1
print "Motion Detected: Door %s at %s on %s. Count is %s" % (door, time.strftime("%H:%M:%S"), time.strftime("%A"), peoplecount)
time.sleep(3)
if __name__ == '__main__':
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(RECEIVER_PIN, GPIO.IN)
GPIO.add_event_detect(RECEIVER_PIN, GPIO.RISING, callback=callback_func, bouncetime=200)
try:
while True:
time.sleep(0.5)
except:
# Event wieder entfernen mittels:
GPIO.remove_event_detect(RECEIVER_PIN)
error:
Lichtschranke wurde unterbrochen
Motion Detected: Door 1 at 19:47:22 on Friday. Count is 1
Cannot Access Page
It seems that the variables don't send any data. If I don't send the form with %s it works. Can anybody help me or is there a better method?
I think you are using the Browser module to open the URL. If so you haven't imported the browser module. So that's why it's throwing an exception and printing cannot Access page
from mechanize import Browser
br = Browser()
Install the module using PIP and add this at the start of the code. This should help
Related
I started learning Python two months ago and I have written a code for a Raspberry pi project. My problem is that the program stucks after some hours of operation. I think that in all cases, it stopped after some wifi connection drops. But I don't understand why the whole program stops if there something wrong with the wifi connection. It stops uploading values and renew the lcd screen messages it prints (I removed this and other stuff from the code in order to be more easy to read.)
The code starts at the startup (sudo python /home/pi/test.py &) and contains two Threads:
The "Control" thread reads temperature and humidity by using an i2c bus and a sensor am2315 and according to a temperature threshold, controls a relay through GPIO.
The "Thingspeak" thread reads the temperature threshold from a 'Thingspeak' channel and then uploads the measurements from the previous thread to 'Thingspeak'.
I really don't know what to do and how to search for any solutions.
Any help will be much appreciated.
#! /usr/bin/env python
from time import sleep
import datetime
import urllib2
import RPi.GPIO as GPIO
import threading
import smbus
from tentacle_pi.AM2315 import AM2315
import smtplib
import contextlib
sleep(120)
# Lock
tLock = threading.Lock()
# Global variables
tem_global = 0; hum_global = 0
tem_hi = 35; relay = 21
# GPIO setup
GPIO.setmode(GPIO.BCM)
GPIO.setup(relay, GPIO.OUT)
GPIO.output(relay, False)
sleep(1)
def Control():
global temg, humg, tem_hi, relay
# AM2315 setup
am = AM2315(0x5c,"/dev/i2c-1")
I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1
bus = smbus.SMBus(I2C_bus_number)
bus.write_byte(I2C_address, i2c_channel_setup)
sleep(1)
while True:
try:
tem_local, hum_local = am2315meas()
except:
tem_local = -1; hum_local = -1
tLock.acquire()
tem_global = tem_local; hum_global = hum_local
if tem_local < tem_hi:
GPIO.output(relay, True)
else:
GPIO.output(relay, False)
tLock.release()
sleep(150)
def Thingspeak():
global tem_global, hum_global, tem_hi
myAPI = "..."
channelID = "..."
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
sleep(30)
try:
# Reading value from thingspeak
tLock.acquire()
with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read:
tem_hi = float(fread.read())
t.Lock.release()
sleep(30)
# Uploading values to thingspeak
tLock.acquire()
with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload:
pass
tLock.release()
except:
with open('/home/pi/errors.txt', mode='a') as file:
file.write('Network error recorded at %s.\n' % datetime.datetime.now())
file.close()
sleep(60)
continue
def Main():
t1 = threading.Thread(target=Thingspeak)
t2 = threading.Thread(target=Control)
t1.start()
t2.start()
t1.join()
t2.join()
GPIO.cleanup()
if __name__ == '__main__':
Main()
Problem solved. As James K Polk indicated, there was an error after the tLock.acquire(), every time the internet connection went off, causing deadlock of the program. Below is a corrected part of the code for anyone would be interested.
def Control():
global tem_global, hum_global, tem_hi, relay
# AM2315 setup
am = AM2315(0x5c,"/dev/i2c-1")
I2C_address = 0x70; I2C_bus_number = 1; i2c_channel_setup = 1
bus = smbus.SMBus(I2C_bus_number)
bus.write_byte(I2C_address, i2c_channel_setup)
sleep(1)
while True:
try:
tem_local, hum_local = am2315meas()
except:
tem_local = -1; hum_local = -1
with tLock:
tem_global = tem_local; hum_global = hum_local
if tem_local < tem_hi:
GPIO.output(relay, True)
else:
GPIO.output(relay, False)
sleep(150)
def Thingspeak():
global tem_global, hum_global, tem_hi
myAPI = "..."
channelID = "..."
baseURL = 'https://api.thingspeak.com/update?api_key=%s' % myAPI
while True:
sleep(30)
try:
# Reading value from thingspeak
with tLock:
with contextlib.closing(urllib2.urlopen("https://api.thingspeak.com/channels/%s/fields/1/last?" % channelID)) as f_read:
tem_hi = float(fread.read())
sleep(30)
# Uploading values to thingspeak
with tLock:
with contextlib.closing(urllib2.urlopen(baseURL + "&field1=%s" % tem_global + "&field2=%s" % hum_global)) as f_upload:
pass
except:
with open('/home/pi/errors.txt', mode='a') as file:
file.write('Network error recorded at %s.\n' % datetime.datetime.now())
sleep(60)
continue
I wrote a Python script for the Raspberry Pi in order to monitor changes of 4 GPIO inputs, write them into a databse and send a message to my phone via a telegram bot.
Everything works fine, except that after a couple of hours, some processes of the script shut down. The script is still running (knwoing from a log file), but especially the GPIO event detect and the telegram bot API stop working. This mostly occurs over night.
Because it works perfectly fine for the first few hours after startup, I guess it shouldn't be a bug in the program, but you never know.
I started up the script via rc.local, but switched to System.d for running on startup instead. Works fine for that.
So in a nutshell: Script runs fine, but after a couple of hours some functions in the script become inactive (GPIO event detect, log messages, telegram API - kinda feels like the Pi is falling asleep).
#!/usr/bin/env python
#Import libraries
import time
import RPi.GPIO as GPIO
import telepot
import MySQLdb
import os.path
import logging
import datetime
#start logging
logfile = '/home/pi/Betrieb/logs/log_'+datetime.datetime.now().strftime("%Y-%m-%d_%H-%M")
logging.basicConfig(filename=logfile,level=logging.DEBUG,format='%(asctime)s %(message)s')
logging.debug('=========================================================')
logging.debug('Logging started!')
#initialize connection to Telegram bot
bot = telepot.Bot('##########################################')
#Connect to MySQL-database
con = MySQLdb.connect('localhost',"root","###########","################")
c = con.cursor()
###########################################################################################################
class User:
def __init__(self, id, name, user_id, enable):
self.id = id
self.name = name
self.chat_id = user_id
self.enable = enable
class Machine:
def __init__(self, id, number, name, pin, enable):
self.id = id
self.number = number
self.name = name
self.pin = pin
self.enable = enable
###########################################################################################################
def my_callback(pin):
c.execute("SELECT name FROM machines WHERE pin=%s" % pin)
con.commit()
data = c.fetchall()
for set in data:
machine_name=set[0]
### Attention: multiple sets with same ID can exist
if GPIO.input(pin):
print "Rising edge detected "+str(pin)
string = "INSERT INTO malfunction(machine_name,machine_pin,status) VALUES('%s',%s,1)" % (machine_name,pin)
c.execute(string)
con.commit()
for i in range(0,len(user)):
if user[i].enable:
bot.sendMessage(user[i].chat_id,"Stoerung "+ machine_name)
print "Sent message to", user[i].name
logging.debug('Detected malfunction on Pin %s and sent message to %s', str(pin), user[i].name)
else:
print "Falling edge detected on "+str(pin)
string = "INSERT INTO malfunction(machine_name,machine_pin,status) VALUES('%s',%s,0)" % (machine_name,pin)
c.execute(string)
con.commit()
for i in range(0,len(user)):
if user[i].enable:
bot.sendMessage(user[i].chat_id,"Stoerung behoben "+ machine_name)
print "Sent message to", user[i].name
logging.debug('Solved malfunction on Pin %s and sent message to %s', str(pin), user[i].name)
def updateData():
global machine
global user
logging.debug('Update data.')
#Update user data
c.execute("SELECT * FROM telegram_users")
con.commit()
data = c.fetchall()
user = []
del user[:]
for set in data:
newUser = User(set[0],set[1],set[2],set[3])
user.append(newUser)
#Update machine data
try:
machine
except NameError:
machine = []
else:
for i in range(0,len(machine)):
if machine[i].enable:
GPIO.remove_event_detect(machine[i].pin)
del machine[:]
c.execute("SELECT * FROM machines")
con.commit()
data = c.fetchall()
GPIO.setmode(GPIO.BCM)
for set in data:
# 0 = id / 1 = number / 2 = name / 3 = pin / 4 = enable #
newMachine = Machine(set[0],set[1],set[2],set[3],set[4])
machine.append(newMachine)
if set[4]:
GPIO.setup(set[3], GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
GPIO.add_event_detect(set[3], GPIO.BOTH, callback=my_callback, bouncetime=300)
logging.debug('Added Event Detect on Pin %s', set[3])
###########################################################################################################
updateData()
logging.debug('Initial Update finished. Start looping.')
Counter = 0
while True:
Counter +=1
if Counter == 600:
logging.debug('Still running!')
Counter = 0
time.sleep(1);
lockfile = "/home/pi/Betrieb/lockfiles/request_update"
if os.path.isfile(lockfile):
os.remove(lockfile)
updateData()
print "Data updated."
logging.debug('Deleted lockfile and updated data.')
I got a small python program that communicates with an EV3 robot (lego's robot) via BT. The program sends the EV3 a number 1/2 or 3, the robot makes a predefined movement and send back 'A' to indicate that the movement is done and that it is ready for next command.
The system works great but once in a while the python app crushes with this error message:
'An established connection was aborted by the software in your host machine.' this comes from socket.recv that is called inside btListener() thread.
The relevant python parts:
import bluetooth
from gmail import *
import re
from gtts import gTTS
from time import sleep
import pygame
import serial
import thread
import os
import ftplib
from StringIO import StringIO
from blynkapi import Blynk
def a(): #Send 'a' to 'Status' mailbox
print "Send a to robot"
for i in commandA:
client_sock.send(chr(i))
sleep(1)
def b(): # Send 'b' to 'Status' mailbox
def c(): # Send 'c' to 'Status' mailbox
def clear(): # Send clear array to 'Status' mailbox
for i in clearArray:
client_sock.send(chr(i))
def btListener():
# Listen for end of run reply from the EV3
global ev3Flag, listenFlag
while True:
if listenFlag and (not ev3Flag):
try:
data = client_sock.recv(1024) #Check if EV3 is ready for new command
if data[-2] == 'A':
ev3Flag = True
print "Received 'Ready' from EV3 "
sleep(1)
except Exception as e:
print(e)
print "Failed to read data from socket"
def queueHandler():
# Read next command from QueueArray, call sendFunc and clear the queue
global ev3Flag, listenFlag, queueArray
while True:
if len(queueArray) > 0 and ev3Flag:
sendFunc(queueArray[0])
queueArray.pop(0)
def sendFunc(cmd):
#Send the next command on QueueArray to the EV3
global ev3Flag, listenFlag
if cmd == 1:
try:
ev3Flag = False
listenFlag = False
a()
listenFlag = True
sleep(3)
clear() # clear the EV3 btsocket with a default message
except Exception as e:
print "Error on sendFunc cmd = 1"
print(e)
elif cmd == 2:
try:
except Exception as e:
elif cmd == 3:
try:
except Exception as e:
if __name__ == "__main__":
# Blynk setup
blynk = Blynk(auth_token)
switch1 = Blynk(auth_token, pin = "V0")
switch2 = Blynk(auth_token, pin = "V1")
switch3 = Blynk(auth_token, pin = "V2")
print "Blynk connected"
queueArray = [] # Queue array to hold incoming commands
listenFlag = True # Listen to message from EV3
ev3Flag = True # EV3 ready for new command flag
# BT CONNECTION WITH EV3 #
print "Searching for BT connections: "
nearby_devices = bluetooth.discover_devices()
for bdaddr in nearby_devices:
print bdaddr + " - " + bluetooth.lookup_name(bdaddr)
if target_name == bluetooth.lookup_name(bdaddr):
target_address = bdaddr
break
server_sock = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
port = 1
server_sock.bind(("", port))
server_sock.listen(1)
client_sock, address = server_sock.accept()
print "Accepted connection from ", address
if target_address is not None:
print "found target bluetooth device with address ", target_address
else:
print "could not find target bluetooth device nearby"
# END BT CONNECTION WITH EV3 #
try:
thread.start_new_thread(queueHandler, ())
except Exception as e: print(e)
try:
thread.start_new_thread(btListener, ())
except Exception as e: print(e)
while True:
res1 = switch1.get_val()
res2 = switch2.get_val()
res3 = switch3.get_val()
if (int)(res1[0]) == 1:
print "Add 1 to queue"
queueArray.append(1)
if (int)(res2[0]) == 1:
print "Add 2 to queue"
queueArray.append(2)
if (int)(res3[0]) == 1:
print "Add 3 to queue"
queueArray.append(3)
Edit 1:
I tested it a bit more and it seems that the crush happens when the program tries to recv data and send data the same time. (via the clear() or a()/b()/c() functions), could that be the situation?
I'm new to sockets so the first solution that comes in mind is create a flag to limit the action of the socket, is there a better/smarter way to keep that from happening?
Edit 2:
I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.
I moved the 'listenFlag = True' line inside sendFunc() to after my call to clear() and it seems to solve the problem which was probably due to the python program trying to receive and sand at the same time.
I'm trying to get my Arduino to ring a bell every time the #annoyingbellbot receives the #ringit message. I adapted a lot of this code this instructable but I changed some of it to work with the bell. By the way, I took the twitter API info out so I don't think that is the problem and assume all the spacing is correct. So my problem is that when I tweet at the #annoyingbellbot, nothing happens. It just stays in the loop forever. Any help would be greatly appreciated. Thanks!
##Import Libraries
import twitter
import serial
import time
##authenticate yourself with twitter
api = twitter.Api(consumer_key='', consumer_secret='', access_token_key='', access_token_secret='')
##set to your serial port
#ser = serial.Serial(port='COM3')
ser = serial.Serial()
ser.baudrate = 9600
ser.port = 3
## check serial port
def checkokay():
ser.flushInput()
time.sleep(3)
line=ser.readline()
time.sleep(3)
if line == ' ':
line=ser.readline()
print 'here'
## Welcome message
print 'Welcome To Bell Bot!'
def driptwit():
status = []
x = 0
drip = []
status = api.GetUserTimeline('annoyingbellbot') ##grab latest statuses
checkIt = [s.text for s in status] ##put status in an array
if len(status) != 0:
drip = checkIt[0].split() ##split first tweet into words
## check for match and write to serial if match
if drip[0] == '#ringit':
print 'Tweet Recieved, Ringing Bell'
ser.write('1')
else:
ser.write('0')
print 'Awaiting Tweet'
print "Loop"
while 1:
driptwit() ## call driptwit function
time.sleep(15) ## sleep for 15 seconds to avoid rate limiting
I need to Write "pir sensor" motion detection COUNT to text file.
I tried with this code and this is work without writing to text file. when I put write to file it gives an error file = open("textFile.txt", "w")
IndentationError: unindent does not matchanyouter indentation level.
Expected Output is last motion count number in text file.
code is
# Import required Python libraries
import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# Define GPIO to use on Pi
GPIO_PIR = 7
# Set pin as input
GPIO.setup(GPIO_PIR,GPIO.IN)
Current_State = 0
Previous_State = 0
# I put Variable= 0 for the motion Count
Variable= 0
try:
print "Waiting for PIR to settle ..."
# Loop until PIR output is 0
while GPIO.input(GPIO_PIR)==1:
Current_State = 0
print " Ready"
# Loop until users quits with CTRL-C
while True :
# Read PIR state
Current_State = GPIO.input(GPIO_PIR)
if Current_State==1 and Previous_State==0:
# PIR is triggered
start_time=time.time()
print " Motion detected!"
# here I need to write numbers for the text file.
file = open("textFile.txt", "w")
file.write(Variable)
file.close()
Variable+=1
# Record previous state
Previous_State=1
elif Current_State==0 and Previous_State==1:
# PIR has returned to ready state
stop_time=time.time()
print " Ready ",
elapsed_time=int(stop_time-start_time)
print " (Elapsed time : " + str(elapsed_time) + " secs)"
Previous_State=0
except KeyboardInterrupt:
print " Quit"
# Reset GPIO settings
GPIO.cleanup()
import RPi.GPIO as GPIO
import time
# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)
# Define GPIO to use on Pi
GPIO_PIR = 7
print "PIR Module Test (CTRL-C to exit)"
# Set pin as input
GPIO.setup(GPIO_PIR,GPIO.IN) # Echo
Current_State = 0
Previous_State = 0
Variable=0
try:
print "Waiting for PIR to settle ..."
# Loop until PIR output is 0
while GPIO.input(GPIO_PIR)==1:
Current_State = 0
print " Ready"
# Loop until users quits with CTRL-C
while True :
# Read PIR state
Current_State = GPIO.input(GPIO_PIR)
if Current_State==1 and Previous_State==0:
# PIR is triggered
print " Motion detected!"
# Record previous state
Previous_State=1
file = open("textFile.txt", "w")
file.write(Variable)
file.close()
Variable+=1
elif Current_State==0 and Previous_State==1:
# PIR has returned to ready state
print " Ready"
Previous_State=0
# Wait for 10 milliseconds
time.sleep(0.01)
except KeyboardInterrupt:
print " Quit"
# Reset GPIO settings
This is my friend's code.
(I believe nothing is wrong with your code but a few Indentation Error(e.g. spacing Error) For that you can use some sort of text editor (I use sublime text)
You need to use a string with file.write, here is an example:
file = open("textfile.txt", "rw+")
file.write(str(Variable))
file.close()