Craig Oates
4 years ago
1 changed files with 129 additions and 0 deletions
@ -0,0 +1,129 @@ |
|||||||
|
# 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() |
Reference in new issue