# 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()