Jag har kollat igenom det flera gånger, men vi kan ta en titt i offentlighetens ljus.

Databladet till MCP23017:
http://ww1.microchip.com/downloads/en/D ... 21952b.pdf
Och så min kod:
Kod: Markera allt
# Definiera adresser
DEVICE = 0x22 # Adressen till min krets på I2C-bussen.
# A
IODIRA = 0x00 # Register for pin direction. In or Out
OLATA = 0x0A # Register for outputs (When IOCON.BANK=1)
GPIOA = 0x09 # Register for inputs (When IOCON.BANK=1)
GPPUA = 0x06
# B
IODIRB = 0x10
OLATB = 0x1A
GPIOB = 0x19
GPPUB = 0x16
#
IOCON = 0x04
# - - - - - -
bus = smbus.SMBus(1) # I2C-bussen och vilken kanal.
#Bank 1. No mirror in INT. Sequential operation enabled. (IOCON: Sid 18 i databladet.)
bus.write_byte_data(DEVICE, IOCON, 0b10000000)
# Pull-up disabled for inputs
bus.write_byte_data(DEVICE, GPPUA, 0x00)
bus.write_byte_data(DEVICE, GPPUB, 0x00)
# Set all GPA and GPB pins as outputs by setting
# all bits of IODIRA and IODIRB register to 0
bus.write_byte_data(DEVICE,IODIRA, 0x00)
bus.write_byte_data(DEVICE,IODIRB, 0x00)
# Set output all 7 output bits to 0 on GPA and GPB
bus.write_byte_data(DEVICE,OLATA, 0x00)
bus.write_byte_data(DEVICE,OLATB, 0x00)
Jag är lite osäker på om jag valt rätt under "1.3.1 BYTE MODE AND SEQUENTIAL MODE" (Sida 5 i databladet.)
Jag använder ju en Raspberry Pi's I2C-port till portexpandern,
så jag antar att det är Raspberryn som någonstans ska vara inställd för att matcha portexpandern.
Men jag vet inte var man hittar infon om hur Raspberryn är inställd
och därför vet jag inte riktigt hur jag ska sätta de register som punkt 1.3.1 behandlar.
Nu begär jag inte att någon ska kolla igenom det och förklara, men jag skulle förstås bli glad.
edit:
Som ni ser så har jag inte ställt in interrupts och sådant,
men som jag förstått det så påverkar detta input, inte output.
Ok, jag vet vad som anses om icke satta register, så jag fixar dem också för säkerhet skull.
edit 2:
Nu har jag gjort läxan, så här är alla register i portexpanderns datablad med:
Kod: Markera allt
# Definiera adresser
DEVICE = 0x22 # Adressen till min krets på I2C-bussen
# A
IODIRA = 0x00 # Register for pin direction. In or Out
OLATA = 0x0A # Register for outputs (When IOCON.BANK=1)
GPIOA = 0x09 # Register for inputs (When IOCON.BANK=1)
IPOLA = 0x01 # Register for input polarity
GPINTENA = 0x02 # Interrupt on change. Enable/Disable.
DEFVALA = 0x03 # Default value for interrupt-on-change.
INTCONA = 0x04 # Intterupt on change. Control.
# B
IODIRB = 0x10
OLATB = 0x1A
GPIOB = 0x19
IPOLB = 0x11
GPINTENB = 0x12
DEFVALB = 0x13
INTCONB = 0x14
#
IOCON = 0x04
GPPUA = 0x06
GPPUB = 0x16
# - - - - - -
bus = smbus.SMBus(1) # I2C-bussen och vilken kanal.
#Bank 1. No mirror in INT. Sequential operation enabled.
bus.write_byte_data(DEVICE, IOCON, 0b10000000)
#Interrupt on change. Disable GPIO input for interrupt-on-change
bus.write_byte_data(DEVICE, GPINTENA, 0b00000000)
bus.write_byte_data(DEVICE, GPINTENB, 0b00000000)
#Default value for interrupt-on-change-pins.
bus.write_byte_data(DEVICE, DEFVALA, 0b00000000)
bus.write_byte_data(DEVICE, DEFVALB, 0b00000000)
#Pin value is compared against the previous pin value.
bus.write_byte_data(DEVICE, INTCONA, 0b00000000)
bus.write_byte_data(DEVICE, INTCONB, 0b00000000)
#Input polarity. Input will reflect the same logic state.
bus.write_byte_data(DEVICE, IPOLA, 0b00000000)
bus.write_byte_data(DEVICE, IPOLB, 0b00000000)
# Pull-up disabled for inputs
bus.write_byte_data(DEVICE, GPPUA, 0b00000000)
bus.write_byte_data(DEVICE, GPPUB, 0b00000000)
# Set all GPA and GPB pins as outputs by setting
# all bits of IODIRA and IODIRB register to 0
bus.write_byte_data(DEVICE,IODIRA, 0x00)
bus.write_byte_data(DEVICE,IODIRB, 0x00)
#GPIO port. All to 0.
bus.write_byte_data(DEVICE, GPIOA, 0x00)
bus.write_byte_data(DEVICE, GPIOB, 0x00)
# Set output all 7 output bits to 0 on GPA and GPB
bus.write_byte_data(DEVICE,OLATA, 0x00)
bus.write_byte_data(DEVICE,OLATB, 0x00)
# - - - - - -
Det jag lade till nu var alltså:
Kod: Markera allt
IPOLA = 01h
IPOLB = 11h
GPINTENA = 02h
GPINTENB = 12h
DEFVALA = 03h
DEFVALB = 13h
INTCONA = 04h
INTCONB = 14h
#Input polarity. Input will reflect the same logic state.
IPOL = 0b00000000
#Interrupt on change. Disable GPIO input for interrupt-on-change
GPINTEN = 0b00000000
#Default value for interrupt-on-change-pins.
DEFVAL = 0b00000000
#Pin value is compared against the previous pin value.
INTCON = 0b00000000
#GPIO pull-upp resistor. Disabled
GPPU = 0b00000000
#GPIO port. Alla 0.
GPIO = 0b00000000
Som ni ser så lade jag till GPIO.
Jag använder register OLATA för att skicka ut data från portexpandern.
OLATA har alltid funnits med i min setup av portexpandern.
edit:
Senaste testet var att köra med GPIOA istället för OLATA,
men då fick jag inte ut något alls från portexpandern.
Undrar om det är jag som är ovanligt dum aftonen till ära eller om det är kretsen som är trasig.
Synd att jag bara köpte en sådan krets. Annars hade det gått fort att verifiera det sistnämnda
också.
edit 2:
Jag hittade en intressant sak: En bugg kring clock-stretching av I2C-bussen i Raspberry Pi.
http://www.advamation.com/knowhow/raspb ... c-bug.html
Men frågan är isåfall varför min DS2482 (I2C-1wire-bridge) fungerar felfritt
när inte portexpandern (MCP23017) gör det...
Lite samlade trådar som jag hittat när jag letat efter info om problemet:
http://www.raspberrypi.org/phpBB3/viewt ... 0&p=302378
http://www.microchip.com/forums/m628744.aspx
http://www.raspberrypi.org/phpBB3/viewt ... 44&t=13771
Quick2Wire ska tydligen vara en kompatibel variant av I2C som kan fungera bättre,
men det finns inte längre på deras sajt vad jag kan se:
http://quick2wire.com/
Här är förresten de SMbus/I2C-kommandon som Python stödjer:
http://wiki.erazor-zone.de/wiki:linux:python:smbus:doc
Jag kör med
write_byte_data(addr,cmd,val)
SMbus-protokollet:
http://git.kernel.org/cgit/linux/kernel ... s-protocol
Nu är det ju inte helt säkert att mitt problem bero på detta,
eftersom kommunikationen kommer igång efter ett tag.
Men det var intressant läsning.
Jag tänkte testa write_i2c_block_data(addr,cmd,vals)
istället för write_byte_data(addr,cmd,val).
Men icke...
Den här raden:
bus.write_i2c_block_data(DEVICE, OLATA, 0) # RS
ger:
"Traceback (most recent call last):
File "LCD-test2c.py", line 110, in <module>
bus.write_i2c_block_data(DEVICE, OLATA, 0) # RS
TypeError: Third argument must be a list of at least one, but not more than 32 integers"
Jag har provat 0x00 istället, men nej.
Det finns inget tal någonstans som är större än 255 (0xFF). Inte ens i närheten.
DEVICE = 0x22
OLATA = 0x0A
Jag börjar bli lite småputt på det här projektet...
Lärde mig Python på en eftermiddag, byggde upp allt på en annan.
Gjorde trevliga Python-klasser och bibliotek och kunde initiera efter en kväll.
Men det har man förstås inget för. För naturligtvis blir det tvärstopp på något så oväntat
som att data bara bestämmer sig för att sluta dyka upp på andra sidan kretsen.
Portexpandern har ju en A och B port.
Jag ska kolla om B är lika B som A.
edit igen:
Port B ignorerar mig totalt.
Gjorde precis likadant som innan, men bytte OLATA mot OLATB.
Båda de registren är konfigurerade likadant, men då förstås mot olika portar.
Nä men om man skulle beställa lite nya kretsar kanske.......

Electrokit brukar ta någon vecka på sig. Elfa verkar inte leverera till dagen efter längre.
Får se vad jag hittar för leverantör.