RPi3 mit Adafruit PWM9685

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
Istvan
User
Beiträge: 5
Registriert: Donnerstag 27. September 2018, 12:49

Guten Tag für die Runde,

Ich baue ein Aquariumsteuerung mit RPi. Technik ist schon fertig, einzelne teile funktionieren.
Programieren lerne ich jetzt.
der Plan ist:
Steuerung durch PHP und Python:
PHP Seite ist schon fertig, aber mit Python geht es irgendwie nicht. Es soll erst 3 Optionen bekommen.
  • ein
  • aus
  • Timer


Code lautet wie folgt:

Code: Alles auswählen

from __future__ import division
import time
from datetime import datetime, timedelta
import Adafruit_PCA9685

pwm = Adafruit_PCA9685.PCA9685(address=0x40)     
pwm.set_pwm_freq(100)

while True:
    dimmer=open("/var/www/html/dimmer.txt","r")
    start=open("/var/www/html/start.txt","r")
    ein=open("/var/www/html/ein.txt","r")
    aus=open("/var/www/html/aus.txt","r")
    a=0
    fmax=4096
    now=time.strftime("%H:%M")
    on=start.read()
    fdimm=int(fmax/100)*int(dimmer.read())
    dimm=(1/(fdimm/30))
    if on=="0" and a>0:
        a=a-1
    if on=="1" and a<fdimm:
        a=a+1
    if on=="2" and a<fdimm and now>=time.strftime(ein.read()) and now<time.strftime(aus.read()):
        a=a+1
    if on=="2" and a>0 and now>=time.strftime(aus.read()) and now<=time.strftime(23,59):
        a=a-1
    if on=="2" and a>0 and now<time.strftime(ein.read()) and now>=time.strftime(0,0):
        a=a-1
    pwm.set_pwm(0, 0, a)
    pwm.set_pwm(1, 0, a)
    pwm.set_pwm(2, 0, a)
    time.sleep(dimm)
    dimmer.close()
    start.close()
    ein.close()
    aus.close()

     
    
ich hoffe, dass jemand mir weiter helfen kann.

Vielen Dank voraus
mfG
Istvan
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

`geht es irgendwie nicht` ist keine gute Fehlerbeschreibung. Was willst Du tun? Was passiert statt dessen? Fehlermeldung?

Zum Code: die erste if-Bedingung ist nie erfüllt, weil a zu diesem Zeitpunkt immer 0 ist. Aus Dateien kann man nur einmal lesen, die doppelten ein.read() und aus.read() führen also zu falschem Verhalten. now ist immer in der Form "%H:%M" formatiert. Welche Formate stehen denn in den Datein aus und ein drinnen? Und welches außer "%H:%M" führt dann zu einem sinnvollen Vergleich? now kann daher maximal gleich der anderen Zeit sein, oder kleiner, wenn zwischen dem ersten und den weiteren strftime Aufrufen ein Minutensprung passiert ist. Und genau das muß bei der dritten if-Bedingung passieren, was sehr unwahrscheinlich und sehr nicht-deterministisch ist. Und nur dann kann die vierte oder fünfte if-Abftage erfüllt sein. Mit anderen Worten, a ist immer 0.

Ohne zu wissen, was Du aber eigentlich erreichen willst, kann man da wenig helfen.

Es ist keine gute Idee, in /var/www/html/ Schreibrechte auf Dateien zu haben. In Kombination mit andern Lücken könnte man so allen Besuchern Schadcode unterjubeln, oder wenn da auch noch die PHP-Dateien liegen, Deinen Server übernehmen.
Istvan
User
Beiträge: 5
Registriert: Donnerstag 27. September 2018, 12:49

so...
ich habe ein PHP geschrieben, welche aof "Knopfdruck" je nach links in dem Datei start.txt 1, 2, oder 0 schreibt. Ein endere PHP Script macht noch drei Dateien ein.txt aus.txt und dimmer.txt.
In Python mochte ich die einlesen, und je nachdem die befehle ausfuhren lassen.
Im Grundkonzept ware es ein AQ Steuerung fur Licht. Ich habe die Beleuchtung von Bausatze selber zusammengebastelt, aber ein wenig uberdimensioniert.
was ich eingentlich mochte, dass die Beleuchtung von 0 auf fdimm in 30sec hoch geht oder runter. 2te ware noch ein timerfunktion.

fehler was ich immer bekomme:

Traceback (most recent call last):
File "/home/pi/wiringPi/aqua1.py", line 7, in <module>
pwm = Adafruit_PCA9685.PCA9685(address=0x40)
File "build/bdist.linux-armv7l/egg/Adafruit_PCA9685/PCA9685.py", line 75, in __init__
self.set_all_pwm(0, 0)
File "build/bdist.linux-armv7l/egg/Adafruit_PCA9685/PCA9685.py", line 111, in set_all_pwm
self._device.write8(ALL_LED_ON_L, on & 0xFF)
File "/usr/local/lib/python2.7/dist-packages/Adafruit_GPIO/I2C.py", line 114, in write8
self._bus.write_byte_data(self._address, register, value)
File "/usr/local/lib/python2.7/dist-packages/Adafruit_PureIO/smbus.py", line 236, in write_byte_data
self._device.write(data)
IOError: [Errno 121] Remote I/O error
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da stirbt der I2C-Bus. Das kann durch schlechte oder zu lange Kabel kommen, schlechte Verbindungen, etc. mit Python hat das erstmal nichts zu tun.
Istvan
User
Beiträge: 5
Registriert: Donnerstag 27. September 2018, 12:49

jetzt habe ich die Gehause auseinander genommen... ein kabel war nicht richtig eingesteckt...
es geht jetzt.
Istvan
User
Beiträge: 5
Registriert: Donnerstag 27. September 2018, 12:49

jetzt habe ich einiges ausgeloscht.

Code: Alles auswählen

from __future__ import division
import time
from datetime import datetime, timedelta
import Adafruit_PCA9685

pwm = Adafruit_PCA9685.PCA9685(address=0x40)     
pwm.set_pwm_freq(100)
a=0
while True:
    dimmer=open("/var/www/html/dimmer.txt","r")
    start=open("/var/www/html/start.txt","r")
    ein=open("/var/www/html/ein.txt","r")
    aus=open("/var/www/html/aus.txt","r")
    fmax=4096
    on=start.read()
    fdimm=int(fmax/100)*int(dimmer.read())
    dimm=(1/(fdimm/30))
    if on=="0" and a>0:
        a=a-1
    if on=="1" and a<fdimm:
        a=a+1
    pwm.set_pwm(0, 0, a)
    pwm.set_pwm(1, 0, a)
    pwm.set_pwm(2, 0, a)
    time.sleep(dimm)
    dimmer.close()
    start.close()
    ein.close()
    aus.close()
Ein/Aus geht.
wie konnte ich ein Zeitschalter einprogramieren?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Istvan: Anmerkungen zum Quelltext:

`a` ist kein guter Name. Der verrät nicht was der Wert bedeutet.

Um das ``=`` bei Zuweisungen (ausserhalb von Argumentlisten) und binäre Operatoren setzt man üblicherweise Leerzeichen damit das lesbarer ist und nicht alles so aneinander klebt.

Konstanten werden normalerweise am Anfang, nach den Importen, definiert und komplett in Grossbuchstaben geschrieben.

Namen sollte man nicht zu weit von der Stelle entfernt definieren wo sie letztlich verwendet werden und Dateien sollten geschlossen werden, wenn sie nicht mehr benötigt werden. Also nicht alle Dateien am Anfang des Schleifenkörpers öffnen und am ende erst wieder schliessen. Um letzteres sicherzustellen bietet sich die ``with``-Anweisung zusammen mit `open()` an.

Wenn man `on` nicht als Zeichenkette sondern als Zahl betrachten würde, dann hat man zweimal das lesen einer Zahl aus einer Datei und könnte das in eine Funktion auslagern.

Mit `min()` und `max()` kann man die ``if``-Abfragen bezüglich `on` zusammenkürzen.

Ungetestet:

Code: Alles auswählen

#!/usr/bin/env python2
from __future__ import absolute_import, division, print_function
import os
import time

import Adafruit_PCA9685

BASE_PATH = '/var/www/html'
FMAX = 4096


def load_int(filename):
    with open(os.path.join(BASE_PATH, filename), 'r') as file:
        return int(file.read())


def main():
    pwm = Adafruit_PCA9685.PCA9685()
    pwm.set_pwm_freq(100)
    
    pwm_off = 0
    while True:
        fdimm = FMAX // 100 * load_int('dimmer.txt')
        pwm_off = max(0, min(fdimm, pwm_off + [-1, 1][load_int('start.txt')]))
        
        for channel in range(3):
            pwm.set_pwm(channel, 0, pwm_off)
        
        time.sleep(1 / (fdimm / 30))


if __name__ == '__main__':
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Istvan
User
Beiträge: 5
Registriert: Donnerstag 27. September 2018, 12:49

wow...
Danke!
Es funktioniert. ich muss noch einiges verstehen, wenn ich es spater wieder benutzen mochte.
mit "def" habe ich ausser ein Paar Tutorials noch nicht richtig gearbeitet. so Schaut aber schon ordendtlicher aus.

wenn ich etwas fragen darf, was bedeutet es:

Code: Alles auswählen

pwm_off = max(0, min(fdimm, pwm_off + [-1, 1][load_int('start.txt')]))
ich weiss, dass es doof klingt, aber sowas habe ich noch nicht gesehen.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Istvan: Was hast Du noch nicht gesehen? In der Zeile ist nichts wirklich ungewöhnliches. Funktionsaufrufe, Operatoren, Listen, … Grundlagen halt.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
DeaD_EyE
User
Beiträge: 1012
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Wenn es um Lebewesen geht, sollte man lieber sehr vorsichtig sein. Wäre doch schade, wenn die Tiere verrecken, weil der Programmierer Mist gebaut hat.

Code: Alles auswählen

pwm_off = max(0, min(wert1, wert2))
So ist es lesbarer.

Dann fängst du am besten von innen an. Also min(wert1, wert2) sollte klar sein.
max(0, kleinster_wert1_2) sollte dann auch klar sein.

Ist sehr praktisch das in eine Funktion zu packen. Manchmal braucht man das öfters.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten