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.
129 lines
4.6 KiB
129 lines
4.6 KiB
# 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://35.176.14.135/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()
|
|
|