I2C Bus Adresse ermitteln / scannen

achim S.

Mitglied
16. Jan. 2010
704
13
18
Berlin Biesdorf
Sprachen
  1. ANSI C
Hallo Gemeinde
Es gibt verschiedene Programme (einfache Arduino) um die I"C adressen zu ermitteln. So einen Scanner in C suche ich. Kennt jemand da was. Ausgabe auf ein Display (nicht PC) vielleicht über den Bus?
achim
 
Etwas fertiges kenne ich jetzt nicht. Aber wäre auch etwas zu abhängig von dem was du hast (welches Display, welche Anbindung also 4 oder 8 Bit, SPI, I2C).

So etwas ist aber ja auch schnell gemacht. Du brauchst eigentlich nur ein I2C Start senden mit der Read Adresse und dann den Rückgabewert prüfen.
[CCODE]ret = i2c_start(i2c_slave_address);
if (ret) {
//SLAVE_NICHT_ANWESEND;
} else {
//SLAVE_ANWESEND;
}
i2c_stop();
[/CCODE]Das nur noch in eine Schleife packen die die Adresse hoch zählt, LCD Routinen hinzufügen, vielleicht noch einen Taster zum starten, fertig :)


Edit:
Ich selbst nutze meinen Raspberry Pi für sowas.
Siehe: http://avr-praxis.de/forum/showthread.php?2969-Infos-und-Anleitungen&p=29818&viewfull=1#post29818
 
Hallo Tommy
ist ganz einfach. Ist ein Display 1604 von Pol.., eine Anbindung von 4Bit, I2C,
Der Grundaufbau soll bzw. ist ein AT1284p, ein Display mit einem PCF8574 und 1604. Auf einem Port liegen ein paar taster zur Bedienung. Zur Kontrolle wird mir immer die Adresse des IC angezeigt, weitere kann ich suchen lassen.
achim
 
Hi Achim,

das ist sehr einfach umzusetzen ....
- Du schickst nen I2C-Start
- danach sendest du eine Adresse. 0-255 mit ner Schleife durcharbeiten lassen. Damit hast du alle Read und Writeadressen
- Nachsehen ob ein Acknowledge zurückkommt. Wenn ja, dann reagiert ein Baustein am Bus auf die Adresse.
- Danach nen I2C-Stop senden um die Kommunikation abzubrechen und die nächste Adresse zu prüfen.
Ist also sehr einfach.

Gruß
Dino
 
Hallo Dino
die Sache ist mir bewusst. den Bus mit der Anzeige, verschiedene Anbindungen, Abfragen, Temp usw habe ich im Griff. Leider klappt diese Abfrage nicht bzw. der Zwischenspeicher und übergabe an die Anzeige.- Deshalb suche ein Stück Code, der mir das zeigen könnte. Werde es mit meinem Teil zusammenbauen und gern hier reinstellen. Habe schon einiges an Programmen reingestellt (hier und wo anders). Mit einigen Sachen stehe ich im Klintsch, deshalb muss ich was dazu suchen.
Eigentlich ist das ganze so gedacht. Verwende einen AT1284p mit einem Display 1604 und einem PCF8574. Das ist als Bus aufgebaut mit ein paar tasten an einem Port. Wenn ich ein anderes bzw. zusätzliche I2C Modul aufstecke möchte ich zur Kontrolle die Adressen angezeigt bekommen. Vom PCF bekomme ich die Adresse angezeigt zur Kontrolle. Da ich schon Problem mit doppelten Adressen hatte, möchte ich notfalls die Module einzeln testen können.
achim
 
Also Du willst immer nur einen Slave(!) an Deine "Blackbox" anklemmen, welche Dir dann die Adresse des neuen Slaves ermittelt und anzeigt, oder wie?

(wenn Du einen Master an die Box (die selbst ja ein Master sein muß) hängst (also insbesondere auch ein ganzes Netz inklusive Master), muß dieser Master für Multi-Master-Arbitrierung implementiert sein (die Box entsprechend auch). Außerdem sollten die Bitraten zumindest ähnlich sein, da bei gleichzeitigem Zugriff mehrerer Master deren Clocks verANDet sind.)
 
Bisher bin ich nicht von einem Master ausgegangen. Es soll nur der Bus sein. Ich kann ja auch von einem z.B. LT75 (Temp) Werte auslesen und auf meinem Display (PCF8574) anzeigen lassen ohne das ich einen Master/Slave brauche
 
???

TWI (I²C) ist ein Master-Slave-Bus. Der Master generiert den Takt, und adressiert den gewünschten Slave (wobei die ersten 7 Bit die eigentliche Adresse darstellen, und das letzte Bit festlegt ob der Slave empfangen oder senden soll. Eine Adresse adressiert alle Slaves als Empfänger (general call), die anderen stehen für die einzelnen Slaves zur Verfügung.
Befinden sich mehrere Master am Bus, könnten diese gleichzeitig senden (sogar denselben Slave adressieren usw) - deswegen muß jeder Master überwachen, ob wirklich auf dem Bus landet, was er sendet. Weicht das ab (also legt er ein Hi, und liest ein Lo), verliert er die Arbitrierung und stellt seinen Transfer ein (und muß selbst zu Slave werden - der andere Master könnte ja ihn adressieren wollen).

Slaves allein würden nur passiv am Bus hängen, da sie nur auf ihre eigene, vom Master gesendete Adresse reagieren. (Und auf einen general call, auf den sie aber nicht antworten (alle gleichzeitig;))
 
Hallo,

wo liegt denn nun eigentlich das Problem?

... den Bus mit der Anzeige, verschiedene Anbindungen, Abfragen, Temp usw habe ich im Griff. Leider klappt diese Abfrage nicht bzw. der Zwischenspeicher und übergabe an die Anzeige.

Ich habe den Eindruck, dass das Problem garnicht im Bereich I2C liegt, sondern eher bei der Ausgabe der I2C Adresse des Slaves (eines Bytes) auf dem Display?! :hmmmm:

Dirk :ciao:
 
Wenn du einen PCF8574 als Slave bezeichnest, dann arbeite ich mit Slaves. Wenn ich aber einen zusätzlöichen AT2313 verwende und ihm Daten bzw Befehle erteile bzw übermittel, was ist es dann?
Ich nutze den AT1284p als Master, ok, die anderen ICs sind I2C Schaltkreise die durch den Master angesprochen werden und nur das ausführen könne was sie vom Master bekommen. Diese ICs sind vom Hersteller auf bestimmte Adressen gesetzt (Hardware) und diese Adressen möchte ich lesen können. Bei 7 Bit stehen mir rund 112 Adressen zur Verfügung. Ich kann (wie bereits gesagt) von 0 bis 128 eine Schleife durchlaufen lassen. Ist die Adresse bzw IC im Bus vorhanden antwortet er mit ACK. Damit habe ich eine Adresse gefunden. Die möchte ich auf einem Display darstellen bzw mir anzeigen lassen- Nach durchlauf erscheint Fertig anzeige und ich kann vergleichen ob meine Daten der Einstellung und des Herstellers mit meinen gelesenen Daten übereinstimmt. Die Anzeige im Bus z.B Ausgabe eines Textes oder Temp kann ich machen. Das Anzeieg Problem besteht in der Adresse und im suchen.
achim
 
Der Tiny2313 hat kein TWI. Man könne mit dem USI einen TWI-Slave implementieren, vielleicht mit hängen und würgen auch sowas wie ein TWI-Master (obwohl ich mir da mit Clock-Stretching und eventueller Multi-Master-Arbitrierung nicht sicher bin) - aber darum ging es Dir sicher nicht.

Du scheinst einen single-Master zu haben (den Mega1284?), und diverse Slaves. In #6 wollte ich eigentlich fragen ob Dein Scanner (ich war da von 'ner separaten Hardware ausgegangen) den gesamten laufenden Bus (inklusive Master und Slaves) scannen soll, oder eben nur einzelne Slaves.

Den Vorschlag für die Suche hast Du ja bereits erhalten, das Byte jetzt noch auf ein Display auszugeben sollte Doch kein Problem sein, oder hast Du mit der binär->hex Konvertierung Probleme?
 
Es ist so. Nutze vorrangig den AT1284p als Singel. Den AT2313 will ich erst später einbinden. Eine separate Hardware habe ich dazu nicht. Möchte den AT1284 als Scanner nutzen können. Dazu nutze ich auch die die Anzeige über den PCF8574 mit dem 1604. Der hat 4 Zeilen mit 16 Stellen. Dazu habe ich ein Menue geschrieben und nutze die Ports des 1284 als Eingang Taster. Damit kann ich verschiedene Option wählen. Das aufrufen der Routine und die übergabe der Werte an das Display mit Ausgabe hex - stelle ich mich sau blöd an.
achim
 
Das aufrufen der Routine und die übergabe der Werte an das Display mit Ausgabe hex - stelle ich mich sau blöd an.
achim

Also die Schleife mit I2C_Start + I2C_Stop wurde hier ja schon erwähnt, so würde ich es mal probieren.

Die 8Bit Adresse mit RW-Bit oder eben die 7Bit-Adresse ohne RW-bit konvertierst du in zwei Character, welche du auf dem Display ausgibst.

Prinzipiell kannst du folgendes Beispiel als Basis verwenden:
[CCODE]#include <avr/pgmspace.h>

const unsigned char HEX[] PROGMEM = {"0123456789ABCDEF"};

void DisplayHex8(uint8_t data)
{

uint8_t a, b;

a = pgm_read_byte(&HEX[(data & 0x0F)]);
b = pgm_read_byte(&HEX[((data>>4) & 0x0F)]);

// Display
// "0x"
// b: high nibble
// a: low nibble

} [/CCODE]

(Es gibt noch die Möglichkeit die beiden Nibble einzeln zu betrachten und hier immer in Abhängigkeit, ob es sich um den Bereich 0..9 oder 10..15 handelt, den Offset für Ascii '0' bzw. 'A' addierst)
 
Hallo Dirk,

mal wieder eine sehr Einfache Routine zum Umwandeln. Braucht man kein speicherfressendes "sprintf"
 
Also die Schleife mit I2C_Start + I2C_Stop wurde hier ja schon erwähnt, so würde ich es mal probieren.

Die 8Bit Adresse mit RW-Bit oder eben die 7Bit-Adresse ohne RW-bit konvertierst du in zwei Character, welche du auf dem Display ausgibst.

Prinzipiell kannst du folgendes Beispiel als Basis verwenden:
[CCODE]#include <avr/pgmspace.h>

const unsigned char HEX[] PROGMEM = {"0123456789ABCDEF"};

void DisplayHex8(uint8_t data)
{

uint8_t a, b;

a = pgm_read_byte(&HEX[(data & 0x0F)]);
b = pgm_read_byte(&HEX[((data>>4) & 0x0F)]);

// Display
// "0x"
// b: high nibble
// a: low nibble

} [/CCODE]

(Es gibt noch die Möglichkeit die beiden Nibble einzeln zu betrachten und hier immer in Abhängigkeit, ob es sich um den Bereich 0..9 oder 10..15 handelt, den Offset für Ascii '0' bzw. 'A' addierst)

Sollten doch auch besser als "char" deklariert werden.
 
"Besser" ist relativ. Es zeigt nur auf das in dieser Variable "wohlmöglich" ein "Buchstabe/Chrackter" gespeichert wird. :p *Klugscheißerei*
 
Hallo

Ich habe den I2C Bus meiner ATMega8 "Entwicklungsumgebung" bestehend aus:
- ATMega8, 3.686.400 Hz
- Portexpander MCP23017 als I2C-Teilnehmer, Adresse 0x42
- Portexpander PCA9555 als I2C-Teilnehmer, Adresse 0x40
mal gescannt (mit der I2C-Lib von P. Fleury - wie im Beitrag vorgeschlagen #2), dabei wurde die Adresse 0x40 korrekt erkannt, ebenso die Adresse 0x42,
aber es wurde auch 0x43 zurückgemeldet - das ist falsch (wäre die READ Adresse des MCP23017) - wie kann das sein?


I2C Scanner
Scanning mit 100k
0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
5 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
6 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
7 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Scan Ergebnis 100k
Anzahl I2C - Teilnehmer: 1
Fehlerhaft: 0

I2C Scanner
Scanning mit 100k
0 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
3 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
4 40 -- 42 43 -- -- -- -- -- -- -- -- -- -- -- --
5 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
6 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
7 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Scan Ergebnis 100k
Anzahl I2C - Teilnehmer: 3
Fehlerhaft: 0

Der Portexpander MCP23017 fkt allerdings korrekt (IO wird korrekt bedient) ...

mfg

Hero_123
 
Hatte ein ähnliches Ergebnis auch mal am RasPi. PullUp's vergessen / Bus unsauber?
Da die Adressen nur bis 7x gehen gehe ich von der Schreibweise >>2 aus, also wird das R/W Bit weg geschubst, macht effektiv die Slaveadresse (sowohl read alsauch write). Sonst wäre es 00-FF, aber in 2er Schritten. Ziemlich verwirrend weil manche es so schreiben, andere anders.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)