initial
This commit is contained in:
554
kwhmeter_20131014.py
Normal file
554
kwhmeter_20131014.py
Normal file
@@ -0,0 +1,554 @@
|
||||
# This Python script needs a SPI module.
|
||||
# For more info, please see:
|
||||
# http://www.100randomtasks.com/simple-spi-on-raspberry-pi
|
||||
#
|
||||
# This script also uses a "LoadAverage" module. This module can be downloaded from:
|
||||
# http://patrick.i234.me/kwhmeter/LoadAverage.py
|
||||
#
|
||||
# This script is written for use on a Raspberri Pi, in combination with some
|
||||
# custom-made hardware.
|
||||
# The schematic of the hardware can be found here:
|
||||
# https://www.circuitlab.com/circuit/eae95u/raspberry-pi-kwh-meter/
|
||||
#
|
||||
# or an PDF can be found on my own site:
|
||||
# http://patrick.i234.me/kwhmeter/raspberry-pi-kwh-meter.pdf
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
# Unused modules, that I might incorporate later
|
||||
#import rrdtool
|
||||
#import os
|
||||
|
||||
import MySQLdb
|
||||
|
||||
|
||||
import spidev
|
||||
import time
|
||||
import RPi.GPIO as GPIO
|
||||
import ConfigParser
|
||||
# for the module LoadAverage, see: http://patrick.i234.me/kwhmeter/LoadAverage.py
|
||||
import LoadAverage
|
||||
import datetime
|
||||
from datetime import date
|
||||
# For PVoutput
|
||||
import urllib, urllib2
|
||||
|
||||
|
||||
DEBUG = False
|
||||
|
||||
# GPIO Pins for the different components:
|
||||
switch = 23
|
||||
redLED = 17
|
||||
greenLED = 18
|
||||
boardLED = 22
|
||||
|
||||
|
||||
# Initialise SPI
|
||||
spi = spidev.SpiDev()
|
||||
spi.open(0, 0)
|
||||
|
||||
|
||||
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
|
||||
def readadc(adcnum):
|
||||
if ((adcnum > 7) or (adcnum < 0)):
|
||||
return -1
|
||||
r = spi.xfer2([1, (8 + adcnum) << 4, 0])
|
||||
adcout = ((r[1] & 3) << 8) + r[2]
|
||||
return adcout
|
||||
|
||||
|
||||
def turnonLED(LED):
|
||||
GPIO.output(LED, True)
|
||||
|
||||
|
||||
def turnoffLED(LED):
|
||||
GPIO.output(LED, False)
|
||||
|
||||
|
||||
def toggleLED(LED):
|
||||
GPIO.output(LED, GPIO.input(LED) ^ 1)
|
||||
|
||||
|
||||
def writeLog(watt, total, importCount, exportCount, rotTime, loadaverage):
|
||||
localtime = time.localtime(time.time())
|
||||
filename = '%s_kWh-meter.log' % time.strftime("%Y-%m-%d", localtime)
|
||||
line = "%s\t%s\t%s\t%s\t%.3f\t%.3f\t%.3f\t%.0f\t%.3f\t%.3f\t%.3f\n" % (
|
||||
time.strftime("%Y-%m-%d %H:%M:00", localtime), time.strftime("%Y-%m-%d", localtime),
|
||||
time.strftime("%H:%M:00", localtime), watt, total, importCount, exportCount, rotTime, loadaverage[0],
|
||||
loadaverage[1], loadaverage[2])
|
||||
|
||||
logfile = open(filename, 'a')
|
||||
try:
|
||||
logfile.write(line)
|
||||
finally:
|
||||
logfile.close()
|
||||
|
||||
logfile.close()
|
||||
|
||||
|
||||
def writesettings(config):
|
||||
with open('kwhmeter.conf', 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
return True
|
||||
|
||||
|
||||
def readsettings():
|
||||
config = ConfigParser.SafeConfigParser()
|
||||
config.read('kwhmeter.conf')
|
||||
|
||||
if not config.has_section('kWh Settings'):
|
||||
config.add_section('kWh Settings')
|
||||
if not config.has_option('kWh Settings', 'LeftChannelID'):
|
||||
config.set('kWh Settings', 'LeftChannelID', '2')
|
||||
if not config.has_option('kWh Settings', 'RightChannelID'):
|
||||
config.set('kWh Settings', 'RightChannelID', '0')
|
||||
|
||||
|
||||
# Section kWh data
|
||||
if not config.has_section('kWh'):
|
||||
config.add_section('kWh')
|
||||
if not config.has_option('kWh', 'importCounter'):
|
||||
config.set('kWh', 'importCounter', '0')
|
||||
if not config.has_option('kWh', 'exportCounter'):
|
||||
config.set('kWh', 'exportCounter', '0')
|
||||
if not config.has_option('kWh', 'rotationsPerKWh'):
|
||||
config.set('kWh', 'rotationsPerKWh', '600')
|
||||
if not config.has_option('kWh', 'cumuliday'):
|
||||
config.set('kWh', 'cumuliday', date.today().strftime("%Y%m%d"))
|
||||
|
||||
# Add Pvoutput stuff
|
||||
if not config.has_section('pvout'):
|
||||
config.add_section('pvout')
|
||||
if not config.has_option('pvout','pvout_enabled'):
|
||||
config.set('pvout','pvout_enabled','false')
|
||||
if not config.has_option('pvout','pvout_apikey'):
|
||||
config.set('pvout','pvout_apikey','0')
|
||||
if not config.has_option('pvout','pvout_sysid'):
|
||||
config.set('pvout','pvout_sysid','0')
|
||||
|
||||
# If you want to save in a MySQL DB, uncomment below:
|
||||
# Section MySQL
|
||||
#if not config.has_section('MySQL'):
|
||||
# config.add_section('MySQL')
|
||||
#if not config.has_option('MySQL', 'host'):
|
||||
# config.set('MySQL', 'host', 'localhost')
|
||||
#if not config.has_option('MySQL', 'user'):
|
||||
# config.set('MySQL', 'user', 'root')
|
||||
#if not config.has_option('MySQL', 'passwd'):
|
||||
# config.set('MySQL', 'passwd', 'root')
|
||||
#if not config.has_option('MySQL', 'db'):
|
||||
# config.set('MySQL', 'db', 'kwhRijnsraat214')
|
||||
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def savekwhdata(config, importCounter, exportCounter):
|
||||
config.set('kWh', 'importCounter', "%.0f" % importCounter)
|
||||
config.set('kWh', 'exportCounter', "%.0f" % exportCounter)
|
||||
writesettings(config)
|
||||
|
||||
|
||||
# If you want to save in a MySQL DB, uncomment below:
|
||||
#def savetodb(config, watt, total, imported, exported):
|
||||
# section = 'MySQL'
|
||||
# localtime = time.localtime(time.time())
|
||||
#
|
||||
# conn = MySQLdb.connect(host = config.get(section, 'host'),
|
||||
# user = config.get(section, 'user'),
|
||||
# passwd = config.get(section, 'passwd'),
|
||||
# db = config.get(section, 'db'))
|
||||
# cursor = conn.cursor()
|
||||
#
|
||||
# try:
|
||||
# cursor.execute(
|
||||
# "INSERT INTO `DayDatakWh` (`DateTime`, `CurrentPower`, `ETotalToday`, `EImportToday`, `EExportToday`, `CurrentUsage`, `EUsageToday`, `PVOutput`, `CHANGETIME`) VALUES ('%s', %s, %.3f, %.3f, %.3f, NULL, NULL, NULL, '0000-00-00 00:00:00');" % (
|
||||
# time.strftime("%Y-%m-%d %H:%M:00", localtime), watt, total, imported, exported))
|
||||
# conn.commit()
|
||||
# except:
|
||||
# conn.rollback()
|
||||
# conn.close()
|
||||
#
|
||||
# return True
|
||||
|
||||
def printinfo(line):
|
||||
timeStr = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))
|
||||
print "%s\t%s" % (timeStr, line)
|
||||
#serialDev.writeLine("%s\t%s" % (timeStr, line))
|
||||
|
||||
def exportPvoutput(config, gentotal, genpower, contotal, conpower):
|
||||
|
||||
pvout_enabled = config.getboolean('pvout','pvout_enabled')
|
||||
pvout_apikey = config.get('pvout','pvout_apikey')
|
||||
pvout_sysid = config.get('pvout','pvout_sysid')
|
||||
|
||||
url = "http://pvoutput.org/service/r2/addstatus.jsp"
|
||||
now = datetime.datetime.now()
|
||||
|
||||
get_data = {
|
||||
'key': pvout_apikey,
|
||||
'sid': pvout_sysid,
|
||||
'd': now.strftime('%Y%m%d'),
|
||||
't': now.strftime('%H:%M'),
|
||||
'v1': gentotal * 1000,
|
||||
'v2': genpower,
|
||||
'v3': contotal * 1000,
|
||||
'v4': conpower,
|
||||
'c1': "1"
|
||||
}
|
||||
|
||||
|
||||
get_data_encoded = urllib.urlencode(get_data) # UrlEncode the parameters
|
||||
printinfo(get_data_encoded)
|
||||
request_object = urllib2.Request(url + '?' + get_data_encoded) # Create request object
|
||||
try:
|
||||
response = urllib2.urlopen(request_object) #make the request and store the response
|
||||
printinfo("Pvoutput Exported")
|
||||
return True
|
||||
except urllib.error.HTTPError, e:
|
||||
printinfo('HTTPError = ' + str(e.code))
|
||||
return False
|
||||
except Exception:
|
||||
import traceback
|
||||
checksLogger.error('generic exception: ' + traceback.format_exc())
|
||||
|
||||
#http://pvoutput.org/service/r2/addstatus.jsp?
|
||||
|
||||
def calibratesensors(config):
|
||||
printinfo("Do calibration of sensors . . .")
|
||||
sensorleftLValue = 9999
|
||||
sensorleftHValue = -1
|
||||
sensorrightLValue = 9999
|
||||
sensorrightHValue = -1
|
||||
|
||||
turnoffLED(boardLED)
|
||||
turnoffLED(greenLED)
|
||||
turnonLED(redLED)
|
||||
|
||||
startTime = millis()
|
||||
elapsedTime = millis() - startTime
|
||||
startBlink = millis()
|
||||
startInfo = millis()
|
||||
|
||||
sensorleftDiff = 0
|
||||
sensorrightDiff = 0
|
||||
|
||||
while (elapsedTime < 30000) or (sensorleftDiff < 40) or (sensorrightDiff < 40): #or not GPIO.input(switch):
|
||||
# run calibration for min. 10 seconds,
|
||||
# and distance between low and high value must be at least 40 ticks
|
||||
# or while the switch on the board is hold down (pressing the switch = 0, not pressing the switch = 1)
|
||||
|
||||
sensordata = samplesensors(config)
|
||||
sensorleftCurrent = sensordata['left']
|
||||
sensorrightCurrent = sensordata['right']
|
||||
|
||||
if sensorleftLValue > sensorleftCurrent:
|
||||
sensorleftLValue = sensorleftCurrent
|
||||
if sensorleftHValue < sensorleftCurrent:
|
||||
sensorleftHValue = sensorleftCurrent
|
||||
|
||||
if sensorrightLValue > sensorrightCurrent:
|
||||
sensorrightLValue = sensorrightCurrent
|
||||
if sensorrightHValue < sensorrightCurrent:
|
||||
sensorrightHValue = sensorrightCurrent
|
||||
|
||||
if DEBUG:
|
||||
printinfo("Sensor left: %s\tSensor right: %s" % (sensorleftCurrent, sensorrightCurrent))
|
||||
|
||||
if millis() - startBlink > 100:
|
||||
toggleLED(boardLED)
|
||||
toggleLED(greenLED)
|
||||
toggleLED(redLED)
|
||||
startBlink = millis()
|
||||
|
||||
|
||||
sensorleftDiff = sensorleftHValue - sensorleftLValue
|
||||
sensorrightDiff = sensorrightHValue - sensorrightLValue
|
||||
|
||||
if millis() - startInfo > 1000:
|
||||
printinfo("Time %s: \tSL: %s (diff: %s) \t\tSR: %s (diff: %s)" % (elapsedTime, sensorleftCurrent, sensorleftDiff, sensorrightCurrent, sensorrightDiff))
|
||||
startInfo = millis()
|
||||
|
||||
|
||||
time.sleep(0.1)
|
||||
elapsedTime = millis() - startTime
|
||||
|
||||
|
||||
sensorleftLTh = sensorleftLValue + ((sensorleftDiff / 10) * 5) # 50% above min
|
||||
sensorleftHTh = sensorleftHValue - ((sensorleftDiff / 10) * 2) # 20% below max
|
||||
sensorrightLTh = sensorrightLValue + ((sensorrightDiff / 10) * 5) # 50% above min
|
||||
sensorrightHTh = sensorrightHValue - ((sensorrightDiff / 10) * 2) # 20% below max
|
||||
|
||||
turnoffLED(boardLED)
|
||||
turnoffLED(greenLED)
|
||||
turnoffLED(redLED)
|
||||
|
||||
printinfo("Calibration done!")
|
||||
printinfo("Left low: %s" % sensorleftLValue)
|
||||
printinfo(" high: %s" % sensorleftHValue)
|
||||
printinfo(" diff: %s" % sensorleftDiff)
|
||||
printinfo(" lthld.%s" % sensorleftLTh)
|
||||
printinfo(" hthld.%s" % sensorleftHTh)
|
||||
printinfo("Right low: %s" % sensorrightLValue)
|
||||
printinfo(" high: %s" % sensorrightHValue)
|
||||
printinfo(" diff: %s" % sensorrightDiff)
|
||||
printinfo(" lthld.%s" % sensorrightLTh)
|
||||
printinfo(" hthld.%s" % sensorrightHTh)
|
||||
printinfo("")
|
||||
|
||||
config.set('kWh', 'minleft', "%.0f" % sensorleftLValue)
|
||||
config.set('kWh', 'maxleft', "%.0f" % sensorleftHValue)
|
||||
config.set('kWh', 'minmarginleft', "%.0f" % sensorleftLTh)
|
||||
config.set('kWh', 'maxmarginleft', "%.0f" % sensorleftHTh)
|
||||
|
||||
config.set('kWh', 'minright', "%.0f" % sensorrightLValue)
|
||||
config.set('kWh', 'maxright', "%.0f" % sensorrightHValue)
|
||||
config.set('kWh', 'minmarginright', "%.0f" % sensorrightLTh)
|
||||
config.set('kWh', 'maxmarginright', "%.0f" % sensorrightHTh)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def millis():
|
||||
return int(round(time.time() * 1000))
|
||||
|
||||
|
||||
def samplesensors(config):
|
||||
# Sample the left and right sensor for maxsamples times (in order to get an average value)
|
||||
leftid = config.getint('kWh Settings', 'LeftChannelID')
|
||||
rightid = config.getint('kWh Settings', 'RightChannelID')
|
||||
maxsamples = 20
|
||||
sensorleft = 0
|
||||
sensorright = 0
|
||||
|
||||
for loopCount in range(0, maxsamples):
|
||||
sensorleft += readadc(leftid)
|
||||
sensorright += readadc(rightid)
|
||||
#print "%s | %s" % (sensorleft, sensorright)
|
||||
sensorleft /= maxsamples
|
||||
sensorright /= maxsamples
|
||||
|
||||
return {'left': sensorleft, 'right': sensorright}
|
||||
|
||||
|
||||
def dotFollower(config):
|
||||
# This is the main part of the code, which will start to minitor the black dot on the disc
|
||||
|
||||
# Do some initialisations
|
||||
rotationsperkwh = config.getfloat("kWh", "rotationsPerKWh") * 1.00
|
||||
counterimport = config.getint("kWh", "importCounter")
|
||||
counterexport = config.getint("kWh", "exportCounter")
|
||||
countertotal = counterimport + counterexport
|
||||
currentpower = 0
|
||||
timeperrotation = 0
|
||||
|
||||
left = False
|
||||
right = False
|
||||
leftdetected = False
|
||||
rightdetected = False
|
||||
lefttimestamp = time.time()
|
||||
leftprevtimestamp = time.time()
|
||||
righttimestamp = time.time()
|
||||
rightprevtimestamp = time.time()
|
||||
sensorinnertimestamp = time.time()
|
||||
sensorinnerlength = 0
|
||||
sensoroutertimestamp = time.time()
|
||||
sensoroutherlength = 0
|
||||
exportpower = 0
|
||||
importpower = 0
|
||||
|
||||
thisday = config.get("kWh", "cumuliday")
|
||||
printinfo("Date: %s" % thisday)
|
||||
|
||||
|
||||
leftmin = config.getint("kWh", "minmarginleft")
|
||||
leftmax = config.getint("kWh", "maxmarginleft")
|
||||
rightmin = config.getint("kWh", "minmarginright")
|
||||
rightmax = config.getint("kWh", "maxmarginright")
|
||||
|
||||
logexported = False
|
||||
loadaverage = LoadAverage.Loadaverage()
|
||||
loadaverageadded = False
|
||||
|
||||
# Keep on running while the switch is NOT pressed
|
||||
while 1: #GPIO.input(switch):
|
||||
sensordata = samplesensors(config)
|
||||
|
||||
# left sensor
|
||||
if sensordata['left'] >= leftmax and not left:
|
||||
# turn left to False
|
||||
left = True
|
||||
turnonLED(greenLED)
|
||||
leftdetected = True
|
||||
leftprevtimestamp = lefttimestamp
|
||||
lefttimestamp = time.time()
|
||||
#printinfo("Left sensor: . %.5f secs" % (lefttimestamp - leftprevtimestamp))
|
||||
if not rightdetected:
|
||||
sensorinnertimestamp = time.time()
|
||||
sensoroutherlength = time.time() - sensoroutertimestamp
|
||||
else:
|
||||
sensoroutertimestamp = time.time()
|
||||
sensorinnerlength = time.time() - sensorinnertimestamp
|
||||
|
||||
if sensordata['left'] <= leftmin and left:
|
||||
# turn left to False
|
||||
left = False
|
||||
turnoffLED(greenLED)
|
||||
#printinfo("Left off")
|
||||
|
||||
|
||||
|
||||
# right sensor
|
||||
if sensordata['right'] >= rightmax and not right:
|
||||
# turn right to False
|
||||
right = True
|
||||
turnonLED(redLED)
|
||||
rightdetected = True
|
||||
rightprevtimestamp = righttimestamp
|
||||
righttimestamp = time.time()
|
||||
#printinfo("Right sensor:. %.5f secs" % (righttimestamp - rightprevtimestamp))
|
||||
if not leftdetected:
|
||||
sensorinnertimestamp = time.time()
|
||||
sensoroutherlength = time.time() - sensoroutertimestamp
|
||||
else:
|
||||
sensoroutertimestamp = time.time()
|
||||
sensorinnerlength = time.time() - sensorinnertimestamp
|
||||
|
||||
if sensordata['right'] <= rightmin and right:
|
||||
# turn right to False
|
||||
right = False
|
||||
turnoffLED(redLED)
|
||||
#printinfo("Right off")
|
||||
|
||||
if not left and not right and leftdetected and rightdetected:
|
||||
#rotation detected!
|
||||
leftdetected = False
|
||||
rightdetected = False
|
||||
if sensorinnerlength < sensoroutherlength: # detection of left and right was correct
|
||||
turnonLED(boardLED)
|
||||
# Determine direction
|
||||
if lefttimestamp < righttimestamp:
|
||||
# The left sensor was seen before the right
|
||||
# S1 --> S2
|
||||
# Rotation is "importing from the net"
|
||||
rotation = 1
|
||||
counterimport += 1
|
||||
else:
|
||||
# The right sensor was seen before the left
|
||||
# S1 <-- S2
|
||||
# Rotation is "exporting to the net"
|
||||
rotation = -1
|
||||
counterexport += 1
|
||||
countertotal = counterimport - counterexport
|
||||
|
||||
# I'll average the left and right rotation time to get a "smoother" value (in principle I calculate the point between the 2 sensors)
|
||||
timeperrotation = (((lefttimestamp - leftprevtimestamp) + (righttimestamp - rightprevtimestamp)) / 2)
|
||||
currentpower = int(rotation * rotationsperkwh * 10 / (timeperrotation))
|
||||
|
||||
if rotation == 1:
|
||||
printinfo("-> importing from net")
|
||||
importpower = currentpower
|
||||
exportpower = 0
|
||||
else:
|
||||
printinfo("<- exporting to net")
|
||||
exportpower = currentpower * -1
|
||||
importpower = 0
|
||||
#printinfo("Rotation time: . %.5f secs" % timeperrotation)
|
||||
#printinfo("-- -- -- -- -- -- -- -- -- -- --")
|
||||
#printinfo("Inner gab: . . . %.5f secs" % sensorinnerlength)
|
||||
#printinfo("Outer: . . . . . %.5f secs" % sensoroutherlength)
|
||||
#printinfo("Total: . . . . . %.5f secs" % (sensoroutherlength + sensorinnerlength))
|
||||
printinfo("Rotation time: . %.5f secs" % timeperrotation)
|
||||
printinfo("Current power: . %.0f Watt" % currentpower)
|
||||
#printinfo("ImportCount: . . %.0f" % counterimport)
|
||||
#printinfo("ExportCount: . . %.0f" % counterexport)
|
||||
printinfo("Import:. . . . . %.2f kWh" % (counterimport / rotationsperkwh))
|
||||
printinfo("Export:. . . . . %.2f kWh" % (counterexport / rotationsperkwh))
|
||||
printinfo("Total: . . . . . %.2f kWh" % (countertotal / rotationsperkwh))
|
||||
printinfo("Load average:. . %.0f W, %.0f W, %.0f W" % loadaverage.loadaverage())
|
||||
printinfo("--------------------------------------------------------------------------------")
|
||||
|
||||
# do a tiny nap
|
||||
time.sleep(0.1)
|
||||
turnoffLED(boardLED)
|
||||
else:
|
||||
# Ooops... inner gab is bigger then the outer route??? We are detecting the wrong way!
|
||||
# sleep a bit and try again
|
||||
printinfo("Skipping rotation . . .")
|
||||
if (sensoroutherlength / 4) < 10:
|
||||
time.sleep(sensoroutherlength / 4)
|
||||
else:
|
||||
time.sleep(10)
|
||||
else:
|
||||
time.sleep(0.001)
|
||||
|
||||
if time.gmtime()[5] % 10 == 0:
|
||||
# Every 10 seconds print the current values
|
||||
if not loadaverageadded:
|
||||
loadaverage.addvalue(currentpower)
|
||||
loadaverageadded = True
|
||||
|
||||
if time.gmtime()[4] % 5 == 0:
|
||||
# Every 5 minutes, write a log entry & DB record
|
||||
if not logexported:
|
||||
writeLog(currentpower, (countertotal / rotationsperkwh), (counterimport / rotationsperkwh),
|
||||
(counterexport / rotationsperkwh), (timeperrotation * 1000), loadaverage.loadaverage())
|
||||
savekwhdata(config, counterimport, counterexport)
|
||||
# If you want to save to pvoutput, uncomment the line below:
|
||||
exportPvoutput(config, (counterexport / rotationsperkwh), exportpower, (counterimport / rotationsperkwh), importpower)
|
||||
logexported = True
|
||||
else:
|
||||
logexported = False
|
||||
else:
|
||||
loadaverageadded = False
|
||||
|
||||
if thisday != date.today().strftime("%Y%m%d"):
|
||||
if logexported == True:
|
||||
exportpower = 0
|
||||
importpower = 0
|
||||
thisday = date.today().strftime("%Y%m%d")
|
||||
config.set('kWh', 'cumuliday',thisday)
|
||||
|
||||
writesettings(config)
|
||||
|
||||
|
||||
# Main program routine begins here:
|
||||
#----------------------------------
|
||||
|
||||
config = readsettings()
|
||||
writesettings(config)
|
||||
|
||||
#init raspberry pi gpio pins
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
|
||||
GPIO.setup(switch, GPIO.IN)
|
||||
GPIO.setup(boardLED, GPIO.OUT, initial = GPIO.LOW)
|
||||
GPIO.setup(greenLED, GPIO.OUT, initial = GPIO.LOW)
|
||||
GPIO.setup(redLED, GPIO.OUT, initial = GPIO.LOW)
|
||||
|
||||
#set LEDs default off
|
||||
turnoffLED(boardLED)
|
||||
turnoffLED(greenLED)
|
||||
turnoffLED(redLED)
|
||||
|
||||
writesettings(config)
|
||||
|
||||
# Infinite loop
|
||||
while True:
|
||||
config = calibratesensors(config)
|
||||
dotFollower(config)
|
||||
|
||||
# we will never get here...
|
||||
GPIO.remove_event_detect(switch)
|
||||
GPIO.cleanup()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user