Code: Alles auswählen
ich habe folgendes Problem.
Ich möchte einen Portexpander IC PCA 9555 als zusätzliche Ausgänge benutzen.
Dazu habe ich eine Klasse geladen, die aus dem i2c-test.py Program von Frank Buss stammt.
Ich möchte nur Outputs benutzen.
Wenn ich das Programm starte werden alle Ports so gesetzt wie ich es möchte und es funktioniert.
In der Unterfunktion def execute meines Programms benutze ich genau die gleichen Variable ioExpander.setOutput(v)
um das Ergebnis an den I2C Klasse zu senden.
Und dann kommt es zum TimeOut mit dem I2C. (Fehlermeldung unten im Text)
irgendwie kann ich die Variable nicht an die Klasse übergeben, obwohl diese laut class PCA9555 () def set.output global sein müsste.
Was mache ich da falsch?
Danke für Eure Antworten !
Lutz
Code: Alles auswählen
#####################################################################
# Programm zur Bedienung der Outputs des PCA9555 Expander
#####################################################################
import os
import sys
import subprocess
import io
import smbus
import time
import socket
#I2C INITIALISIERUNG PCA9555
class PCA9555():
# open Linux device /dev/ic2-0
i2c = smbus.SMBus(1)
# construct a new object with the I2C address of the PCA9555
def __init__(self, address):
self.address = address
# write a 16 bit value to a register pair
# write low byte of value to register reg,
# and high byte of value to register reg+1
def writeRegisterPair(self, reg, value):
low = value & 0xff
high = (value >> 8) & 0xff
self.i2c.write_byte_data(self.address, reg, low)
self.i2c.write_byte_data(self.address, reg + 1, high)
# read a 16 bit value from a register pair
def readRegisterPair(self, reg):
low = self.i2c.read_byte_data(self.address, reg)
high = self.i2c.read_byte_data(self.address, reg + 1)
return low | (high << 8)
# set IO ports to input, if the corresponding direction bit is 1,
# otherwise set it to output
def setInputDirection(self, direction):
self.writeRegisterPair(6, direction)
# set the IO port outputs
def setOutput(self, value):
self.writeRegisterPair(2, value)
# read the IO port inputs
def getInput(self):
return self.readRegisterPair(0)
# create a new PCA9555 object
global ioExpander
ioExpander = PCA9555(0x20) #Adresse des PCA9555-Chip A0/A1/A2 = Ground
# test output value
v = 3
# direction of the LED animation
directionLeft = False
# set input for IO pin 15, rest output
ioExpander.setInputDirection(1 << 16);
#Initalzustand nach Start Raspberry
#Alle Ports Output und 0 Zustand
p0_str = "port0"
globals()[p0_str]= ('00000000')
#print(port0)
p1_str = "port1"
globals()[p1_str]= ('00000000')
#print(port0)
[color=#0000FF]#ini I2C Ausgang RaspiStart
port0v=('00000000') #Grundzustand nach Einschalten PORT0
port1v=('00000000') #Grundzustand nach Einschalten PORT0
port_bin=port1v+port0v #Beide 8Bit Vorgaben zum 16 Bit Wort zusammensetzen
PCA_data=int(port_bin, 2) #16 Bit-Wort in Dezimal-Wert wandeln
v=PCA_data #Übergabe an Variable v der class PCA9555
ioExpander.setOutput(v); #Ausgänge PCA9555 setzen[/color][/color]
#---------------------------------------------------------------------------------------------
def execute(datagram):
global restart
port0x=(globals()[p0_str])
port1x=(globals()[p1_str])
if m2==1: #Merkervariable = 1 Befehl mit nur Punkt im Befehlswort
instring1= (instring +(adr)) #Abfragestring generieren
ad=int(adr) #adr in intWert wandeln
if m1==1: #Merkervariable = 1 Befehl mit Gleichheitszeichen im Befehlswort
instring1 = (instring +(z_nach_gleich)) #Variable z_nach_gleich entspricht Inhalt Befehl nach Gleichheitszeichen
#**************EIN Schalten von I2C Outputs PORT-0-PCA9555***************************
if instring1 == ("SET:PORT0="+(z_nach_gleich)):
port0A=(z_nach_gleich)
if port1x != ('00000000'): #Abfrage wenn Werte in Port1 ungleich der global InitPort1 Variable
port_bin=(port1x)+(port0A) #Beide 8Bit Vorgaben zum 16 Bit Wort zusammensetzen
(globals()[p0_str])=(port0A) #Ändern der globalen Variable die nach dem Einschalten als Grundzustand gesetzt wurde
else:
port_bin=('00000000')+(port0A ) #Beide 8Bit Vorgaben zum 16 Bit Wort zusammensetzen
(globals()[p0_str])=(port0A)
PCA_data=int(port_bin, 2) #16 Bit-Wort in Dezimal-Wert wandeln
v=PCA_data #Übergabe an Variable v der class PCA9555
[color=#4000BF] ioExpander.setOutput(v); [/color] #Ausgänge PCA9555 setzen
datagram = ("VAL_PORT.0="+(port_bin)+chr(13))
return datagram
#**************EIN Schalten von I2C Outputs PORT-1-PCA9555***************************
if instring1 == ("SET:PORT1="+(z_nach_gleich)):
port1A=(z_nach_gleich)
if port0x != ('00000000'):
port_bin=(port1A)+(port0x)
(globals()[p1_str])=(port1A)
else:
port_bin=(port1A)+('00000000')
(globals()[p1_str])=(port1A)
PCA_data=int(port_bin, 2)
v=PCA_data #Übergabe an Variable v der class PCA9555
[color=#0000BF] ioExpander.setOutput(v));[/color] #Ausgänge PCA9555 setzen
datagram = ("VAL_PORT.1="+(port_bin)+chr(13))
return datagram
'-----------------------------------------------------------------------------------------------------------
def get_datagram(get_nachricht):
global adr
global z_nach_gleich
global m1
global m2
#print(get_nachricht)
zeichen=str(get_nachricht)
zl= len(zeichen) #Zeichenlänge ermitteln
z_arr=[] #Zeichen Array
for i in range(2,(zl-1)): #Die ersten beide(b')aus socket StringtoByte und letztes Zeichen(')abtrennen
z_arr.append(zeichen[i]) #Zeichen auf Zeichen Array schreiben
z_arr="".join(z_arr) #Zeichen zusammenführen
zl= len(z_arr) #Stringlänge ermitteln
#print(zl)
#print(z_arr)
pkt= z_arr.find(".") #Position Punkt im Befehl ermitteln
#print(pkt)
gleich_zeich = z_arr.find("=") #Position Gleich Zeichnen im Befehl ermitteln
#print(gleich_zeich)
#++++++++IN Datenprüfung++++++++++++++
if (gleich_zeich > 0): # Prüfung ob Gleich Zeichen im String
m1=1
m2=0
zl_nach_gleich = zl - (gleich_zeich+1) # Anzahl Zeichen nach Gleich Zeichen ermitteln
z_nach_gleich = z_arr[-(zl_nach_gleich):] # Zeichen nach Gleich Zeichen auf Variable schreiben
befehl = z_arr[0:(gleich_zeich+1)] # Zeichen vor Gleich Zeichen auf Variable schreiben
if (zl_nach_gleich > 0):
#print("Gleich="+(befehl))
return befehl
else:
error="Fehler"
return error
if (pkt > 0 ): #Prüfung ob Punkt im String
m1=0
m2=1
adr_zl = zl - (pkt+1) # Anzahl Zeichen nach Punkt ermitteln
adr = z_arr[-(adr_zl):] # Zeichen nach Punkt auf Variable schreiben
befehl = z_arr[0:(pkt+1)] # Zeichen vor Punkt auf Variable schreiben
#print('ADR=',adr_zl)
#print('Befehl=',befehl)
if (adr_zl > 0): # Prüfung auf Zeichen nach Punkt
#print("Punkt="+(befehl))####!!!!!!!!!!!!!!!
return befehl
else:
error="Fehler"
return error
else:
error="Fehler"
return error
########################### FUNKTIONEN ENDE
############################Hauptschleife###############################
while True:
try: # Versuch
daten, addr = s.recvfrom(1024) # Versuch Puffer lesen
except: # falls keine Daten
t = 0 # keine Daten, Zustand merken
get_nachricht = "" # Daten-Puffer leeren
if (t == 1): # wenn Daten verfuegbar
get_nachricht = daten # Daten kopieren
quell_ip = str(addr[0]) # Quell-IP selektieren
quell_port = str(addr[1]) # Quell-Port selektieren
#print ("[%s]:[%i] %s" % (addr[0], addr[1], daten)) #IP, Port und Daten ausgeben
#print (get_nachricht)
instring= get_datagram(get_nachricht)#Rückgabewert auf Variable schreiben
if (instring == "Fehler"): #Wenn Fehler im Eingangstelegramm
nachricht="Fehler" #Wort "error" an Absender senden
s.sendto(nachricht.encode('ascii'),(addr[0],addr[1])) # Nachricht an Absender zuruecksenden
else: #sonst
nachricht=(execute("datagram")) #Rückgabewert auf Variable schreiben
print (nachricht)
s.sendto(nachricht.encode('ascii'),(addr[0],addr[1])) # Nachricht an Absender zuruecksenden
t = 1
s.close()
Traceback (most recent call last):
File "PCA9555_Test.py", line 41, in writeRegisterPair
self.i2c.write_byte_data(self.address, reg, low)
TimeoutError: [Errno 110] Connection timed out
pi@raspberrypi:~ $