Da nun der Raspberry PI aufgesetzt und betriebsbereit ist, soll es in diesem Abschnitt darum gehen, das Programm für den Raspberry zu schreiben, welches dazu führt, dass die LED Impulse aufgenommen und weiter verarbeitet werden. Das Programm wird Schritt für Schritt erklärt und kann im Anschluss heruntergeladen werden. Dabei wird so vorgegangen, dass zuerst ein Teil des Programm-Codes gezeigt wird, danach wird eine kurze Erklärung geliefert. 

import smbus 
import time
import requests
import RPi.GPIO as GPIO 
import telepot
from telepot.loop import MessageLoop

Als erstes wird dafür gesorgt, dass alle erforderlichen Abhängigkeiten in das Programm eingefügt werden. Dies beinhaltet die Bibliotheken für Zeit (der Sensor soll in einem bestimmten Zeit Intervall ausgelesen werden) und das entsprechende Kommunikationssystem, welches für die richtige Übermittlung der Sensordaten auf den Raspberry sorgt, den GPIO (General Purpose Input/Output) - Pin des MOS-Moduls und die Telepot-Bibliothek, die später noch für die Steuerung via Telegram wichtig ist. Später wird dies genauer erläutert. Denke daran, dass der Compiler wahrscheinlich Fehler anzeigen wird, wenn die Importanweisungen einfach so eingegeben werden. Entsprechend muss über die Konsole die Importbibliothek jeweils heruntergeladen werden. Hier kannst Du selbstständig recherchieren, welche Befehle dafür in der Konsole erforderlich sind.

READ_INTERVAL = 60
SLEEP_INTERVAL = 0.2
LIGHT_TRESHOLD = 5
EFF_VOLTAGE = 230

Nun werden alle erforderlichen Konstanten eingefügt. Dies beinhaltet die Auslesezeit des Sensors in Sekunden (60), die Pause zwischen den einzelnen Auslesevorgängen in Sekunden (0,2), somit ergeben sich insgesamt pro Minute 300 Auslesevorgänge des Sensors, die Lichtschwelle in Lux, die überschritten werden muss, damit ein Blinkimpuls wahrgenommen wird (5) und für die weiteren Berechnungen die Annahme, dass der Effektivwert der Netzspannung 230 V sei. 

LIGHT_SENSOR_PIN = 0x23 

Als nächstes wird der Pin definiert, der angeschlossen wurde und die Informationen vom Lichtsensor an den Raspberry übermittelt. Unter Seite 5 des Sensor-Datenblatts ist zu entnehmen, dass die Sensor-Adresse 0x23 ist.

bus = smbus.SMBus(1)

Nun wird das Kommunikationssystem des Raspberry, welches wir nutzen wollen, initialisiert. Wir nennen das Bussystem einfach "bus".

def convertToNumber(data):
    result=(data[1] + (256 * data[0])) / 1.2
    return (result)

def readLight(addr=LIGHT_SENSOR_PIN):
    data = bus.read_i2c_block_data(addr,0x20)
    return convertToNumber(data)

In diesem Abschnitt des Programms wird das übergebene Signal von Sensor zum Raspberry, welches eine Spannung repräsentiert, in eine Zahl umgewandlet und der Sensor einmal ausgelesen. Beim Aufruf der Methode "readLight()" wird die gemessene Lichtintensität in Lux ermittelt. Diese könnte zunächst in der Konsole ausgegeben werden, um sicherzustellen, ob der Sensor korrekt ausliest.

def readLightOverTime():
    ticks = 0
    times = int(READ_INTERVAL/SLEEP_INTERVAL)
    for i in range(0, times):
        light_intensity = readLight()
        if(light_intensity > LIGHT_TRESHOLD):
            ticks += 1
        time.sleep(SLEEP_INTERVAL)
    return ticks

Nun geht es darum, den Sensor über ein bestimmtes Zeit Intervall auszulesen, und das so oft wie möglich, um sicherzustellen, dass kein emittierter LED-Impuls versäumt wird, weil der Sensor gerade in diesem Moment keine Messwertaufnahme macht. Wie schon anfangs bei der Deklaration der Konstanten genannt, wird über eine Minute mit einer Pause von 0,2 Sekunden zwischen den Auslesevorgängen gemessen. Dies ergibt 300 Messvorgänge in einer Minute. In einer For-Schleife wird dann die Variable "ticks", welche die gezählten Lichtimpulse repräsentiert, immer dann um eins hochgezählt, wenn die ermittelte Lichtintensität des Sensors größer als der Schwellenwert, also 5 Lux ist. Am Ende der Minute wird die Anzahl der gezählten Impulse zurückgegeben. 

def calculatePowerFromTicks(ticks):
    return ticks * 3600 / READ_INTERVAL

def calculateCurrentFromPower(power):
    return power / EFF_VOLTAGE

def calculatePowerConsumptionOverHour(power):
    return power / 1000;

In den drei oben zu sehenden Methoden wird in dieser Reihenfolge ein mal in der Minute die umgesetzte elektrische Leistung, der elektrische Strom, der geflossen ist und die umgesetzte elektrische Arbeit (Stromverbrauch, der auf dem Stromzähler angezeigt wird) errechnet. Vollziehe selber nach, ob Du die drei Berechnungsvorschriften in den Methoden verstanden hast (elektrotechnisches Grundverständnis).

def main():
    GPIO.setup(LIGHT_SENSOR_PIN, GPIO.IN) 
    
    while(True):
        ticks = readLightOverTime() 
        power = round(calculatePowerFromTicks(ticks), 2) 
        current = round(calculateCurrentFromPower(power), 2) 
        powerConsumption = round(calculatePowerConsumptionOverHour(power),2) 

if __name__=="__main__":
    main()

Nun widmen wir uns der Main-Methode. Zu aller erst wird der Pin des Lichtsensors als Input definiert, da er dem Raspberry Informationen gibt und nicht anders herum. In eine while-Bedingung werden folgende Dinge ununterbrochen durchgeführt: der Sensor wird dauerhaft ausgelesen, also immer eine Minute lang und nach einer Minute werden die drei Informationen (Leistung, Strom, Arbeit) errechnet. Dabei wird Leistung, Strom und Arbeit immer auf zwei Nachkommastellen gerundet. Die dick gekennzeichnete if-Bedingung ist eine Eigenart von Python, die unbedingt nach dem Quellcode am Ende des Programms hingeschrieben werden muss, damit das Programm ausführbar bleibt!

Das Programm ist nun in der Lage, den Sensor auszulesen und aus den gezählten Impulsen und der Annahme der konstanten Spannung einige Energiedaten zu errechnen. Diese werden in den drei dick gedruckten, kursiven Variablen im letzten Code-Block hineingeschrieben. Als nächstes ist es von Interesse diese Energiedaten online dazustellen und einzusehen.

Zuletzt geändert: Donnerstag, 5. August 2021, 10:33