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