Optocoupler aan PCF8574

Nogmaals, probeer het ic te doorgronden. het ic heeft een in en output poort gecombineerd.
De software bepaalt dan wat ie moet doen.Waarschijnlijk gaat die 46 mA lopen omdat de poort als output staat ingesteld.!!!!

fatbeard

Honourable Member

Wat ik me nog kan herinneren uit de tijd dat ik veel met die dingen werkte (35 jaar terug) is dat er niet een specifieke input of output modus is.
In feite is het altijd een input, met een open collector output eraan parallel geschakeld. Er zit nog wat extra spul in om ervoor te zorgen dat de L-H overgang van de output wat 'steviger' overkomt, maar dat is niet essentieel voor het verhaal.

Als je de pin laag stuurt ("L" schrijft in het output register) wordt de pin laag, en mag dan de genoemde 25mA sinken. Lees je het input register zul je inderdaad een "L" zien.
Vanwege dat zul je in deze toestand (tenzij je de pin misbruikt door er veel te veel stroom in te stoppen) nooit een "H" zien.
Dáárvoor moet je de pin eerst zelf hoog sturen, zodat de ingebouwde (en mogelijk ook externe) pull-up zijn werk kan doen; het werkt dan als 'normale' input.

Een bijkomstigheid van deze setup is dat de poort geen stroom van betekenis kan leveren (dat houdt bij een paar honderd µA wel op), hij kan alleen stroom sinken.
Als je meer stroom nodig hebt dan die 200µA source of 25mA sink moeten er transistoren tussen.

De moraal: als je de ingang wilt sturen met een opto, moet die met zijn emitter aan GND liggen en de collector aan de pin van de PCF8574 liggen. Van die collector kun je nog een LED met serieweerstand naar 5V leggen, dat maakt nix uit.
Die LED kun je nu via de optocoupler aansturen (dan zal de PCF een "L" zien), of via de PCF (door de uitgang "L" te sturen). De input is nu wel geïnverteerd (opto aangestuurd = input "L" en vice versa), maar dat is in de firmware eenvoudig genoeg op te lossen. Misschien is er wel een invert functie in de PCF aanwezig, kan ik me niet meer herinneren.

Een goed begin is geen excuus voor half werk; goed gereedschap trouwens ook niet. Niets is ooit onmogelijk voor hen die het niet hoeven te doen.

Als je de pin laag stuurt ("L" schrijft in het output register) wordt de pin laag, en mag dan de genoemde 25mA sinken.

Dit is ook waar, als je de pin laag maakt kan je er dus een ledje ook aansluiten zonder problemen. Maar die 25mA ga ik dik overheen, zit nu op de 36mA, dat is wel al 10mA lager dan dat het was. Een weerstand toevoegen heeft alleen geen nut omdat er dan niks overblijft van de 5V die ik moet aan bieden op de "ingang" P0.

The I/Os should be HIGH before being used as inputs. After power-on as all the I/Os are set HIGH all of them can be used as input

Dit klopt helemaal, als je niks instelt worden alle pinnen hoog, er komt dus 5V op te staan, maar hoe kan ik die dan gebruiken als ingangen!? moet er toch juist 5V op aan bieden!?

Verder staat er nog dit:

Warning: If a HIGH is applied to an I/O which has been written earlier to LOW, a large current (IOL) will flow to VSS. (see Characteristics note 3).

Dat komt bij mij dus ook voor.

Als ik het volgende programma in de Arduino zet. zeg ik met
pcf8574.pinMode(P0, INPUT);

Dat P0 een ingang wordt. Als ik dan vervolgens ga meten, dan is de spanning 0V, dus eigenlijk is het geen ingang meer, want als het een ingang zou zijn, zou er 5V op staan?

Echter is het zo als ik nu een led aansluit van 5V naar de "ingang" P0.

Gaat 1. de les branden
2. de seriële monitor geeft aan dat er Low naar High is. dus van 0
naar 1.

code:

#include "PCF8574.h"
PCF8574 pcf8574(0x38);

void setup(){
  Serial.begin(9600);
  pcf8574.pinMode(P0, INPUT);
  pcf8574.begin();
}

void loop(){
  byte val = pcf8574.digitalRead(P0);     
  Serial.println(val);
  delay(500);
}

[Bericht gewijzigd door stefan787 op woensdag 27 maart 2019 10:01:35 (15%)

Stefan,
Dat is idd vreemd. Default worden de pinnen van 8574 hoog en lees je een 1 uit. In de paar projectjes die ik er mee gemaakt heb hang ik drukknopjes naar de 0. Bij indrukken lees ik dan een 0 uit.
Geen extra pull-up weerstanden nodig.

Het lijkt alsof de arduino initiatiecode niet doet wat je zou verwachten. Je zou dit kunnen controleren:

Laat de ingangen van de 74 zweven.
Maak een stukje code dat na power-up een aantal seconden wacht.
Vervolgens de input definieren zoals je nu al gedaan heb.

Voltmeter op de ingangspin. Meet wat er gebeurt als je de spanning inschakelt. Direct na power-up moeten de betreffende pin hoog worden en dat ook blijven als de initiatie code wordt uitgevoerd.

Ik ben heel benieuwd.

Op 27 maart 2019 10:14:32 schreef Leo-Bolier:
Stefan,
Dat is idd vreemd. Default worden de pinnen van 8574 hoog en lees je een 1 uit.

Default zijn de pinnen inderdaad hoog.

Ook al heb ik nu in de setup de regel:
pcf8574.pinMode(P0, INPUT);
uit staan, blijf ik gewoon een 0 uitlezen. dit zou dan toch sws een 1 moeten zijn? Dit omdat de ingang al hoog is.

code:

#include "PCF8574.h"
PCF8574 pcf8574(0x38);

void setup(){
  Serial.begin(9600);
  //pcf8574.pinMode(P0, INPUT);
  pcf8574.begin();
}

void loop(){
  byte val = pcf8574.digitalRead(P0);          
  Serial.println(val);
  delay(500);
}
Arco

Special Member

Weet je zeker dat die library 0x38 verwacht i.p.v. 0x70 als adres? (vaak wordt het R/W bit erbij opgeteld...)
Anders de 8574 even zonder microcontroller opstarten (wel de i2c pull-ups). 'Kaal' moet 'ie als input opstarten.
(kan natuurlijk zijn dat de pindrivers al zijn overleden door de mishandelingen...)

De eerder getekende schakeling die met een BC547 de pin direct naar de +5V trekt mag dus nooit. Je moet altijd naar Gnd trekken...
Dat er dan meer als 25mA gaat lopen is logisch; je sluit de boel kort en dan gaat er zoveel stroom lopen (te veel) als de pin leveren kan...

[Bericht gewijzigd door Arco op woensdag 27 maart 2019 10:46:49 (31%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Voor de zekerheid, laat een Arduino i2cscanner de i2c bus testen en kijken welke ic gevonden wordt, met welk adres.

Op 27 maart 2019 10:49:54 schreef BenI2C:
Voor de zekerheid, laat een Arduino i2cscanner de i2c bus testen en kijken welke ic gevonden wordt, met welk adres.

Dat werkt nog wel:

Op 27 maart 2019 10:30:06 schreef Arco:
Weet je zeker dat die library 0x38 verwacht i.p.v. 0x70 als adres? (vaak wordt het R/W bit erbij opgeteld...)
Anders de 8574 even zonder microcontroller opstarten (wel de i2c pull-ups). 'Kaal' moet 'ie als input opstarten.
(kan natuurlijk zijn dat de pindrivers al zijn overleden door de mishandelingen...)

De eerder getekende schakeling die met een BC547 de pin direct naar de +5V trekt mag dus nooit. Je moet altijd naar Gnd trekken...
Dat er dan meer als 25mA gaat lopen is logisch; je sluit de boel kort en dan gaat er zoveel stroom lopen (te veel) als de pin leveren kan...

Dan moet het eigenlijk zo:

Laat eens zien:
Primair loopt er bij gesloten schakelaar circa 10 mA.
Volgens de datasheet van de -3 versie heb je een minimum ratio van 100% dus secundair kan er ook 10mA lopen. Maar met 1K8 vanaf de 5 volt wordt dat niet meer dan 2 mA. De Vce-sat is dan iets van 0,4 volt. De beide BC547's zouden dan dicht moeten zijn. De PCF8574 ingang dus hoog en de secundaire led uit.

Bij geopende schakelaar loopt er secundair een verwaarloosbaar lekstroompje. Er gaat dan ongeveer 2 mA richting beide BC547's. Hoe die zich verdeelt is de vraag. Het zou wellicht kunnen dat de ene een lager Vbe heeft dan de andere. Die gaat dan denk ik alles krijgen en de andere niets ? .....Ik denk dat je in elke basisleiding een serieweerstand moet opnemen.

Maar voorlopig denk ik dat die chip kapot is.

We hebben succes met de PCF8574.

Is eigenlijk best wel een beetje simpel de oplossing.

Dit is de code:

code:

#include <Wire.h>

int reading = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.write(B11111111); // zet alle pinnen hoog, dus als ingang

}

void loop() {
  Wire.requestFrom(B0111000, 1);  // maak verbinding met het ic. en vraag 1 byte op aan info. B0111000 staat ook wel voor 0x38 of 112 dec.
    reading = Wire.read(); 
    Serial.println(reading, BIN); // en stuur dit door naar de seriële monitor in binair. 

  delay(250);
}

En als we alle ingangen los hebben dan krijgen we een 11111111 binnen. alles aan de GND is 00000000.

Vervolgens is dit te gemakkelijk te koppelen aan de optocoupler...

gewoon een pin van de PCF8574 aan de collector aansluiten en de emitter aan de GND.. En stroom... dat loopt er mooi niet. naja dat kan me fluke niet meten zo weinig

Ik ben onbekend met de C-code implementatie voor de Arduino.
En al helemaal met de library. Maar dan toch vreemd dat een blijkbaar specifiek voor de 8574 bedoelde lib niet lijkt te werken en een WIRE lib het wel doet.

Wat ik ook vreemd vind dat een Wire.write(...) blijkbaar geen adres van de chip nodig heeft maar een WIRE.Request.From wel....
Dat adres is blijkbaar wel degelijk 70H...dus misschien moet je bij die pcf8574 library ook wel 70H opgeven.

Die initiele Wire.write is ook helemaal niet nodig. De pinnen zijn bij default al inputs dus 1-en schrijven hoeft niet. Het zou dan ook zonder moeten werken.

Ik zou het zelf nog wel even gaan proberen met de oude lib en 70 als base adres.. Uitgaande van de kennis van nu. Voortschrijdend inzicht etc...:-)

Arco

Special Member

...de regel: pcf8574.pinMode(P0, INPUT);

Dat is ook nogal misleidend: het heeft niets met de 8574 te maken, maar met de betreffende pin van de Arduino... (volgens mij)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

Op 27 maart 2019 14:02:11 schreef Arco:
[...]
Dat is ook nogal misleidend: het heeft niets met de 8574 te maken, maar met de betreffende pin van de Arduino... (volgens mij)

Ik vindt het voor nu wel even mooi. Het werkt uitstekend nu.

De Lib zou zo gemaakt dat de PCF8574 als normaal I/O kan bedienen.

Hier hebben ze dat goed uitgelegd:

https://github.com/xreef/PCF8574_library

Op 27 maart 2019 13:27:14 schreef Leo-Bolier:

Wat ik ook vreemd vind dat een Wire.write(...) blijkbaar geen adres van de chip nodig heeft maar een WIRE.Request.From wel....
Dat adres is blijkbaar wel degelijk 70H...dus misschien moet je bij die pcf8574 library ook wel 70H opgeven.

Op de Arduino website wordt dat beschreven.

https://www.arduino.cc/en/Reference/WireRequestFrom

heeft er volgens mij mee te maken dat je dan direct verbinding hebt, dus er kunnen geen zaken tussen komen.

If false, requestFrom() sends a restart message after the request. The bus will not be released, which prevents another master device from requesting between messages. This allows one master device to send multiple requests while in control.