You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.6 KiB
130 lines
4.6 KiB
3 years ago
|
# 07_light_meter.py
|
||
|
# From the code for the Electronics Starter Kit for the Raspberry Pi by MonkMakes.com
|
||
|
|
||
|
#from Tkinter import *
|
||
|
from tkinter import *
|
||
|
import json
|
||
|
import RPi.GPIO as GPIO
|
||
|
import time, math
|
||
|
import requests # for pushing the readings to roaming-light-api
|
||
|
from datetime import datetime
|
||
|
|
||
|
# Configure the Pi to use the BCM (Broadcom) pin names, rather than the pin positions
|
||
|
GPIO.setmode(GPIO.BCM)
|
||
|
|
||
|
# This project uses a photoresistor, a component whose resistance varies with the light falling on it.
|
||
|
# To measure its resistance, the code records the time it takes for a capacitor to fill
|
||
|
# when supplied by a current passing through the resistor. The lower the resistance the faster
|
||
|
# it fills up.
|
||
|
#
|
||
|
# You can think of a capacitor as a tank of electricity, and as it fills with charge, the voltage
|
||
|
# across it increases. We cannot measure that voltage directly, because the Raspberry Pi
|
||
|
# does not have an analog to digital convertor (ADC or analog input). However, we can time how long it
|
||
|
# takes for the capacitor to fill with charge to the extent that it gets above the 1.65V or so
|
||
|
# that counts as being a high digital input.
|
||
|
#
|
||
|
# For more information on this technique take a look at:
|
||
|
# learn.adafruit.com/basic-resistor-sensor-reading-on-raspberry-pi
|
||
|
# The code here is based on that in the Raspberry Pi Cookbook (Recipes 12.1 to 12.3)
|
||
|
|
||
|
|
||
|
# Pin a charges the capacitor through a fixed 1k resistor and the thermistor in series
|
||
|
# pin b discharges the capacitor through a fixed 1k resistor
|
||
|
a_pin = 18
|
||
|
b_pin = 23
|
||
|
|
||
|
# empty the capacitor ready to start filling it up
|
||
|
def discharge():
|
||
|
GPIO.setup(a_pin, GPIO.IN)
|
||
|
GPIO.setup(b_pin, GPIO.OUT)
|
||
|
GPIO.output(b_pin, False)
|
||
|
time.sleep(0.01) # 0.01 -- initial value
|
||
|
|
||
|
# return the time taken for the voltage on the capacitor to count as a digital input HIGH
|
||
|
# than means around 1.65V
|
||
|
def charge_time():
|
||
|
GPIO.setup(b_pin, GPIO.IN)
|
||
|
GPIO.setup(a_pin, GPIO.OUT)
|
||
|
GPIO.output(a_pin, True)
|
||
|
t1 = time.time()
|
||
|
while not GPIO.input(b_pin):
|
||
|
pass
|
||
|
t2 = time.time()
|
||
|
return (t2 - t1) * 1000000
|
||
|
|
||
|
# Take an analog readin as the time taken to charge after first discharging the capacitor
|
||
|
def analog_read():
|
||
|
discharge()
|
||
|
return charge_time()
|
||
|
|
||
|
# Convert the time taken to charge the cpacitor into a value of resistance
|
||
|
# To reduce errors, do it 100 times and take the average.
|
||
|
def read_resistance():
|
||
|
n = 20
|
||
|
total = 0;
|
||
|
for i in range(1, n):
|
||
|
total = total + analog_read()
|
||
|
reading = total / float(n)
|
||
|
resistance = reading * 6.05 - 939
|
||
|
return resistance
|
||
|
|
||
|
def light_from_r(R):
|
||
|
# Log the reading to compress the range
|
||
|
return math.log(1000000.0/R) * 10.0
|
||
|
|
||
|
# Gets the time and date (at the time of the reading)
|
||
|
def get_timestamp():
|
||
|
return datetime.now().strftime(("%Y-%m-%d %H:%M:%S"))
|
||
|
|
||
|
# Pushes the reading to roaming-light-api
|
||
|
def push_reading(lvalue):
|
||
|
act = False
|
||
|
if lvalue > 20:
|
||
|
act = True
|
||
|
time = get_timestamp()
|
||
|
headers = {"content-type": "application/json"}
|
||
|
# payload = { "active": act, "light-reading": int(lvalue), "timestamp": time }
|
||
|
payload = { "reading": int(lvalue), "time": time}
|
||
|
# res = requests.post("http://192.168.1.228:5000/api/readings/add/1", data=json.dumps(payload), headers=headers)
|
||
|
res = requests.post("http://ritherdon.abbether.net/api/readings/add/1", data=json.dumps(payload), headers=headers)
|
||
|
# print(int(lvalue))
|
||
|
# print(res.status_code)
|
||
|
print(payload)
|
||
|
|
||
|
# group together all of the GUI code into a class called App
|
||
|
class App:
|
||
|
|
||
|
# this function gets called when the app is created
|
||
|
def __init__(self, master):
|
||
|
self.master = master
|
||
|
frame = Frame(master, bg="black")
|
||
|
frame.pack(expand=1)
|
||
|
label = Label(frame, text='Light', fg="white", bg="black", font=("Helvetica", 32))
|
||
|
label.grid(row=0)
|
||
|
self.reading_label = Label(frame, text='12.34', bg="black", fg="white", font=("Helvetica", 110))
|
||
|
self.reading_label.grid(row=1)
|
||
|
self.update_reading()
|
||
|
|
||
|
# Update the reading
|
||
|
def update_reading(self):
|
||
|
light = light_from_r(read_resistance())
|
||
|
reading_str = "{:.0f}".format(light)
|
||
|
self.reading_label.configure(text=reading_str)
|
||
|
self.master.after(200, self.update_reading)
|
||
|
push_reading(light)
|
||
|
|
||
|
# Set the GUI running, give the window a title, size and position
|
||
|
root = Tk()
|
||
|
# Uncomment when app. is ready for deployment
|
||
|
#root.attributes("-fullscreen", True)
|
||
|
root.attributes("-zoomed", True)
|
||
|
root.configure(background="black")
|
||
|
root.wm_title('Light Meter')
|
||
|
app = App(root)
|
||
|
root.geometry("400x300+0+0")
|
||
|
try:
|
||
|
root.mainloop()
|
||
|
finally:
|
||
|
print("Cleaning up")
|
||
|
GPIO.cleanup()
|