PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Raspberry Pi I2C



Kampi
04.10.2012, 00:54
Hallo Forum,

ich habe es erfolgreich geschafft einen PCF8574 mit meinem Raspberry Pi über I²C anzusprechen.
Allerdings ist mir eine Sache nicht ganz klar....
Ich verwende dieses Programm hier:



// Compile with: gcc /var/Programme/UART.c -o /var/Programme/UART


#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


char Device[] = "/dev/i2c-0";
int fd;
int res;
int address = 0x20;
char Buffer[1];




int main(int argc, char** argv) // Programmstart
{
fd = open(Device, O_RDWR);

if (ioctl(fd, I2C_SLAVE, address) < 0) // Set the port options and set the address of the device we wish to speak to
{
printf("Unable to get bus access to talk to slave\n");
exit(1);
}

res = write(fd, argv[1], 1);

close(fd);
return 0;
}


Die Adresse vom PCF ist die Adresse ohne R/W Bit. Und wenn ich mittels

sudo i2cdetect -y -a 0

den Bus nach Geräten absuche, taucht dort nur diese Adresse auf.
Wird das R/W Bit Hard oder Softwaremässig gesetzt oder wie funktioniert das?

Danke für die Antwort!

Klebwax
04.10.2012, 06:30
Die Adresse vom PCF ist die Adresse ohne R/W Bit. Und wenn ich mittels

sudo i2cdetect -y -a 0

den Bus nach Geräten absuche, taucht dort nur diese Adresse auf.
Natürlich. Ein I2C Slave hat nur eine Adresse. Diese ist 7 Bit lang.


Wird das R/W Bit Hard oder Softwaremässig gesetzt oder wie funktioniert das?

Diese Frage verstehe ich nicht. Der User entscheidet, von welchem Slave er lesen oder schreiben will. Der Device-Driver macht dann das passende daraus. Ob das dann Hardware oder Software ist, ist aus der User Ebene nicht zu erkennen.

BTW Programme gehören nicht nach /var , Sourcecode schon garnicht. Wie der Name /var(iable) schon sagt, ist das der Platz für variable Daten.

MfG Klebwax

hans99
04.10.2012, 07:08
Das R/W Bit ist Bestandteil der Adresse (Bit 0). Ist das Bit 0 auf 0, dann werden die vom Master gesendeten Daten auf das Port ausgegeben. Ist das Bit 0 auf 1, dann werden die Daten vom Port gelesen und an den Master gesendet.

Die I2C Adresse besteht eigentlich aus 2 Adressen: 0xX0 und 0xX1.

Siehe auch:

I2C Interface
PCF8574
SCPS068G–JULY 2001–REVISED MAY 2008.............................................. .................................................. .................................................. ............ www.ti.com
I2C communication with this device is initiated by a master sending a start condition, a high-to-low transition on
the SDA I/O while the SCL input is high. After the start condition, the device address byte is sent,
most-significant bit (MSB) first, including the data direction bit (R/W). This device does not respond to the general
call address. After receiving the valid address byte, this device responds with an acknowledge, a low on the SDA
I/O during the high of the acknowledge-related clock pulse. The address inputs (A0–A2) of the slave device must
not be changed between the start and the stop conditions.
The data byte follows the address acknowledge. If the R/W bit is high, the data from this device are the values
read from the P port. If the R/W bit is low, the data are from the master, to be output to the P port. The data byte
is followed by an acknowledge sent from this device. If other data bytes are sent from the master, following the
acknowledge, they are ignored by this device. Data are output only if complete bytes are received and
acknowledged. The output data will be valid at time, tpv, after the low-to-high transition of SCL and during the
clock cycle for the acknowledge.
A stop condition, which is a low-to-high transition on the SDA I/O while the SCL input is high, is sent by the
master.
Interface Definition
BIT
BYTE 7 (MSB) 6 5 4 3 2 1 0 (LSB)
I2C slave address L H L L A2 A1 A0 R/W
I/O data bus P7 P6 P5 P4 P3 P2 P1 P0

ePyx
04.10.2012, 07:25
Was Kampi meint ist, ob er das Bit auf Softwareseite setzen muss. Antwort ist auch hier ja. Einfach Adresse + 1 = R-Zugriff und Adresse + 0 ist W-Zugriff.

i2detect wird halt nur die W-Adresse also die 7-Bit-Adresse ausspucken.

oberallgeier
04.10.2012, 08:21
Hi Kampi, hi Klebwax, ich muss mich ja mittlerweile (und notgedrungen) hier etwas mit I2C beschäftigen. (https://www.roboternetz.de/community/threads/59388-I²C-mit-Bitrate-100-kHz-nur-mit-Treiber/page2?p=560562#post560562) BTW: vielen Dank Klebwax für Deine Hilfe dort.


Natürlich. Ein I2C Slave hat nur eine Adresse. Diese ist 7 Bit lang ...Ich zitiere mal von NXP Semiconductors UM10204 (http://www.nxp.com/documents/user_manual/UM10204.pdf), Rev. 4 — 13 February 2012, Seite 3:

• Each device connected to the bus is software addressable by a unique address

Und auf Seite 8:
10-bit slave address (Anm.: optional für Single master, Multi-master oder master acting as a slave).

Klebwax
04.10.2012, 08:36
Die I2C Adresse ist 7 Bit. Aus dem Standard:


This address is seven bits long

Der I2C Bus transportiert Daten Byte (d.h. 8 Bit) weise. Das Erste Byte nach einem Start nennt man Adressbyte.


After the START condition (S), a slave address is sent. This address is seven bits long followed by an eighth bit which is a data direction bit (R/W) — a ‘zero’ indicates a transmission (WRITE), a ‘one’ indicates a request for data (READ)

Daß bei einer Datenkommunikation mehrere Felder in einem Byte vorhanden sind, ist gängige Praxis. Hier sind es zwei Felder, in den oberen 7 Bit die Adresse und im untersten das Direction Bit.


Was Kampi meint ist, ob er das Bit auf Softwareseite setzen muss. Antwort ist auch hier ja. Einfach Adresse + 1 = R-Zugriff und Adresse + 0 ist W-Zugriff.

Das geht garantiert in die Hose.

MfG Klebwax

Kampi
04.10.2012, 10:32
Huiuiuiui viele Antworten.
Erstmal danke Klebwax für den Hinweis mit dem /var Ordner.
Ich habe mir das nochmal durchgelesen und damit hat sich meine Frage geklärt.
Ich bin bisher davon ausgegangen, dass das R/W Bit ein fester Bestandteil der Adresse ist (sprich die Adresse 8 Bit lang ist).
Und dementsprechend war ich ein wenig verwirrt, weil mein Bascomprogramm nutzt die Adresse 0x40 um was in den PCF zu schreiben und mein C-Programm für das Raspberry nutzt 0x20.
Das hat mich gestern Abend ein bischen zum grübeln gebracht.
Aber jetzt habe ich im Datenblatt gesehen, dass das Writebit beim PCF standartmässig auf 0 steht.
Aber nochmals danke für die fixen Antworten (die Frage lag sehr wahrscheinlich an der Uhrzeit gestern.....hab bisl vergessen auf die Uhr zu gucken) :)

BastelWastel
04.10.2012, 10:49
Kurz mal so halb off-topic..
Ist I2C eigentlich schon fester Bestandteil von Raspian?
Wenn nein, wie implementiert man das am besten?

Gruss, Andreas

Kampi
04.10.2012, 10:55
Hey,

also ich habe da gestern etwas rumgedoktort und kann deshalb nicht sicher sagen wie und wodurch es jetzt funktioniert hat.
Hast du ein I²C Device zur Hand welches du eben anschließen kannst und mal gucken kannst ob du mittels

sudo i2cdetect -y -a 0

was angezeigt bekommst?
Das sollte dann etwa so aussehen:




0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --


Nur die Adresse von deinem Gerät ist dann sicher anders.

BastelWastel
04.10.2012, 11:05
Ja, I2C Device ist vorhanden.
Hab aber noch das erste release von Raspian drauf.
Aber separat installieren musstest du nichts?
Mh..muss ich mich heut Abend mal schlau machen.

Kampi
04.10.2012, 11:19
Ja, I2C Device ist vorhanden.
Hab aber noch das erste release von Raspian drauf.
Aber separat installieren musstest du nichts?
Mh..muss ich mich heut Abend mal schlau machen.

Ich habe da gestern eine neue Version von I²CTools installiert und dann noch ein paar Sachen die aber nicht funktioniert haben. Von daher weiß ich nicht ob es jetzt an den I²CTools liegt das es funktioniert oder ob es schon vorher ging.
Wenn du das ausprobieren könntest was man alles machen muss damit es funktioniert wäre es echt super :)
Ich mach mir auch mal eben ne zweite Karte fertig und probier es nochmal....

Kampi
04.10.2012, 12:17
Ok ich habe es nochmal verifiziert wie man vorgehen muss.
Dazu habe ich eine neue SD-Karte aufgesetzt und mal die Schritte durchgespielt.

Die Befehle lauten so:


$ sudo modprobe i2c-bcm2708
$ sudo modprobe i2c-dev
$ lsmod
$ sudo apt-get install i2c-tools
$ sudo i2cdetect -y 0


Diese beiden Befehle

$ sudo modprobe i2c-bcm2708
$ sudo modprobe i2c-dev

musst du aber offenbar nach jedem Neustart ausführen.

Danach klappt es bei mir problemlos.

Kampi
04.10.2012, 12:50
Passt vielleicht nicht ganz zum Topic aber ich habe ein Problem mit meiner SD-Karte.
Das Raspberry Pi bootet nicht mehr. Die neue SD-Karte funktioniert problemlos, sprich es kann nicht an der I²C Geschichte liegen sondern muss andere Gründe haben.
Die letzten Zeilen von der Ausgabe sind diese hier:



[ 2.199804] mmcblk0: p1 p2[ 2.298210] List of all partitions:
[ 2.303951] b300 7823360 mmcblk0 driver: mmcblk
[ 2.311569] b301 57344 mmcblk0p1 00000000-0000-0000-0000-000000000000
[ 2.323408] b302 7761920 mmcblk0p2 00000000-0000-0000-0000-000000000000
[ 2.335283] No filesystem could mount root, tried:
[ 2.340281] usb 1-1: new high-speed USB device number 2 using dwc_otg
[ 2.351379] ext4
[ 2.355597] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(179,2)
[ 2.368909] [<c0013e1c>] (unwind_backtrace+0x0/0xf0) from [<c037753c>] (panic+0x74/0x1a8)
[ 2.382144] [<c037753c>] (panic+0x74/0x1a8) from [<c04c2c08>] (mount_block_root+0x1e8/0x248)
[ 2.395659] [<c04c2c08>] (mount_block_root+0x1e8/0x248) from [<c04c2e7c>] (mount_root+0xf0/0x118)
[ 2.409784] [<c04c2e7c>] (mount_root+0xf0/0x118) from [<c04c2ffc>] (prepare_namespace+0x158/0x1b8)
[ 2.424185] [<c04c2ffc>] (prepare_namespace+0x158/0x1b8) from [<c04c285c>] (kernel_init+0xfc/0x12c)
[ 2.439002] [<c04c285c>] (kernel_init+0xfc/0x12c) from [<c000e930>] (kernel_thread_exit+0x0/0x8)
PANIC: VFS: Unable to mount root fs on unknown-block(179,2)


Entering kdb (current=0xcb828c80, pid 1) due to Keyboard Entry
kdb>



So wie ich das verstehe kann er kein Filesystem finden.
Aber wieso nicht? Und gibt es eine Möglichkeit dieses Problem zu beheben bzw. die Daten die auf der Karte sind runter zu bekommen?

peterfido
04.10.2012, 20:20
Mein (Linux) NAS liest die Raspi-SD-Karten per Kartenleser ein. Sollte auch mit einer Fritzbox funktionieren, wenn diese einen USB-Anschluß hat. (Im Prinzip auch per USB-Kartenleser am Raspi. Diesen dann natürlich mit einer anderen Karte booten) Dann die Freigabe einfach am PC öffnen und die wichtigen Dateien kopieren. Anschließend das zuletzt funktionierende Backup zurück auf die Karte spielen.

Ist das Dateisystem auf der SD-Karte hinüber, lässt sich dieses evtl. reparieren.

Kampi
04.10.2012, 21:04
Das mit der Fritzbox ist ne geniale Idee. So mach ich es dann auch mal :D
Ne das Dateisystem konnte ich nicht reparieren. Ich habe mir jetzt einfach eine neue SD-Karte gemacht und mal die ganzen Programme usw. als Backup gesichert.

BastelWastel
05.10.2012, 00:29
Backup ist immer ne gute Idee..
Schau dir mal subversion an, falls du es nicht schon verwendest.

Kampi
05.10.2012, 00:53
Jap vor allem wenn man an sowas rumdoktort :)
Was ist Subversion?

ePyx
05.10.2012, 06:01
Ne Versionsverwaltung : http://de.wikipedia.org/wiki/Apache_Subversion

BastelWastel
05.10.2012, 08:31
Jup..Projekte lokal bearbeiten und mit SVN ein Backup auf externe HD oder nen Server, dann geht dir nichts mehr abhanden.
SVN ist hauptsaechlich auf Softwareprojekte ausgelegt..da kannst du z.B. direkt aktuellen Quellcode mit aelter Versionen vergleichen und so nette spielereien.
Als Interface kann ich http://tortoisesvn.net/ empfehlen :)

Gruss, Andreas

ePyx
05.10.2012, 08:45
Habe SVN auch einige Jahre benutzt. Leider hab ich mich immer darüber geärgert, dass die Daten zentral auf einem Rechner liegen und man zum auschecken bzw. um ältere Versionen zu ziehen eine aktive Verbindung benötigt. Daher bin ich irgendwann auf Git umgestiegen, da man dort dezentral arbeitet und jeder Rechner als Server agieren könnte wenn er wollte. Mittlerweile ist der Windows-Support auch recht brauchbar geworden.

BastelWastel
05.10.2012, 09:35
Genau das zentrale speichern der Daten ist was mir am Herzen liegt.
Hatte lange Zeit alle moeglichen Daten wild verstreut..diverse Sachen in verschiedenen Versionen doppelt. Und irgendwann findest du nichts mehr oder arbeitest mit aelteren Speicherstaenden.

Ich spiel gerade mit dem Gedanken noch einen PI zu kaufen und den als kleinen 24/7 online Backup Server in den Keller zu stellen.

ePyx
05.10.2012, 09:47
Nun daher hat man das Repo ja mit dabei. Die Crux an einer Versionsverwaltung ist aber immer noch, dass sie einem das commiten nicht abnimmt.

Wäre froh, wenn mein erstes endlich ankommt.

hans99
05.10.2012, 11:34
@ePyx,hast du, so wie ich, bei RS bestellt?Das war ein großer Fehler. Mein Sohnemann hatte vor 2 Wochen bei Farnell eine geordert und hat eine Woche später den PI bekommen. Er hat dann auch für mich einen geordert.Habe meinen PI seit Dienstag.

ePyx
05.10.2012, 11:47
@ePyx,hast du, so wie ich, bei RS bestellt?Das war ein großer Fehler. Mein Sohnemann hatte vor 2 Wochen bei Farnell eine geordert und hat eine Woche später den PI bekommen. Er hat dann auch für mich einen geordert.Habe meinen PI seit Dienstag.

Jap im Juni. Bin zwischenzeitlich umgezogen (lass zur Arbeit schicken) und hab meine letzten Scheine gemacht. Da hats nicht so wirklich unter den Nägeln gebrannt. Langsam wird es aber albern.

hans99
05.10.2012, 19:37
Da holt sich RS ein zinsenloses Darlehen. Du bezahlst bei der Bestellung sofort, und bekommst nach 3 Monaten die Lieferung.Ich habe bei RS zusätzlich zum PI noch einige Teile bestellt (ca. 70 €) mal 10000 = 700 000 € auf drei Monate. Nach der Meldung von RS, dass sich die Lieferzeit weiter verzögert, war ich ziemlich angefressen. Ich habe, nachdem ich den PI von Farnell bekommen habe, die Bestellung bei RS sofort storniert, Nach einer Schrecksekunde (von ca. einer Woche, seitens RS (auch eine Woche bringt Zinsen)) habe ich das Geld auf mein Kreditkartenkonto gut geschrieben bekommen. Ich, an deiner Stelle, würde auch bei Farnell bestellen.P.S. Warum funktionieren die Zeilenumbrüche bei mir nicht!

Kampi
05.10.2012, 20:09
Also ich kann mich eigtl nicht beschweren ;)
Ich hab mein Pi von RS eher bekommen als von Farnell....ich glaube das von Farnell kam sogar erst 2 Monate später.

ePyx
05.10.2012, 20:15
Naja das es so lange dauert ist mir fast noch egal. Schlimmer finde ich eigentlich, dass man erst die Stückzahl/Käufer wegfallen lassen hat und sich dann für die Lieferengpässe entschuldigt. Was die Geldanlage angeht stimmt das schon. Allerdings hab ich das Teil nicht gekauft weil ich es brauche und dass es dauert und mein Geld auf der Halde liegen könnte/würde hab ich mir schon vorher gedacht. Zu mal man solche Sachen nicht macht oder machen sollte wenn man auf die Kohle angewiesen ist.

Ich für meinen Teil werde wahrscheinlich demnächst einen Bogen um RS machen.

Kampi
06.10.2012, 21:26
Hey,

ich hab noch ne kurze Frage zum I²C von dem Raspberry Pi.
Ich meine irgendwo gelesen zu haben das das Raspberry Pi interne Pull-Up Widerstände für den I²C verwendet.
Ich wollte nämlich einen PSoC an mein Raspberry Pi anschließen aber dieser wird auf Grund des Playtinenlayouts nur mit 5V betrieben.
Wenn das Raspberry Pi jetzt eigene interne Pull-Up Widerstände besitzt sollte ich den I²C doch eigentlich auch zur Pegelwandlung missbrauchen können oder?
Btw....das PSoC Board besitzt keine Pull-Ups

Klebwax
06.10.2012, 23:03
Ich meine irgendwo gelesen zu haben das das Raspberry Pi interne Pull-Up Widerstände für den I²C verwendet.

Was hälst du denn davon, mal im Schaltplan nachzusehen?
23389

MfG Klebwax

peterfido
06.10.2012, 23:16
Einen Schaltplan für einen Pegelwandler habe ich im RN-Wiki gepostet. Dieser ist allerdings nicht für I²C geeignet. Wenn Dein SoC die 3,3V des Raspi als High erkennt, würde ich PullUps 4k7 zu den 3,3V nehmen und zur Sicherheit noch 2 Zenerdioden 3V6 einbauen.

Edit: Den Schaltplan kannte ich noch gar nicht. Demnach sind 1k8 Pullups verbaut. So "niedrige" Werte habe ich bisher noch nicht benutzt. Die Zenerdioden würde ich zur Sicherheit aber noch mit einbauen.

Kampi
06.10.2012, 23:27
Edit: Den Schaltplan kannte ich noch gar nicht. Demnach sind 1k8 Pullups verbaut. So "niedrige" Werte habe ich bisher noch nicht benutzt. Die Zenerdioden würde ich zur Sicherheit aber noch mit einbauen.

Da schließe ich mich an.....den sehe ich jetzt auch zum ersten mal.
Ich habe es gerade mal getestet. Der PSoC wird mit i2cdetect erkannt aber aus irgendeinem Grund schlägt das Schreiben und Lesen immer fehl....

Bzw....ich arbeite im Moment noch mit den Befehlen i2cget und i2cset. Nur wie kann ich ein NACK senden? Weil ich habe nun am Bus einen PCF8574 und der arbeitet problemlos mit dem I2C über Konsole. Aber ein EEPROM was auch am Bus hängt will ein NACK haben und ebenso mein PSoC. Nur bisher habe ich nichts gefunden wie man ein NACK senden kann.
Dasselbe Problem habe ich anscheinend dann auch mit meinem C-Programm. Da funktioniert die Kommunikation mit meinem PCF8574 auch super aber sobald der PSoC dran hängt gibt es Probleme.
Hier ist mal das Datenblatt des I²C Moduls vom PSoC:

http://www.cypress.com/?docID=34801

Etwas unter der "ROM" Sektion am Anfang ist ein Timingdiagramm wo dann drin steht das der Chip ein NACK beim lesen erwartet.
Ich habe das auslesen mit einem Mega32 unter Bascom getestet. Da klappt es problemlos :/

peterfido
06.10.2012, 23:41
Das kann mehrere Gründe haben. Wenn Du ein Oszi hast, würde ich die Signalqualität checken. Evtl. lässt sich die Geschwindigkeit "runterdrehen". Ich habe mit dem Raspi noch keinerlei I²C Erfahrungen gesammelt. Beim AVR läuft es bei längeren Kabeln langsamer besser. Zusätzlich nehme ich da immer geschirmte Leitungen (die, welche damals immer bei den CD-ROMs zur Soundkarte bei waren).

Kampi
06.10.2012, 23:51
Ich denke nicht das es die Signalqualität ist, da das Schreiben und Lesen mit dem PCF funktioniert und auch beim EEPROM. Nur leider lese ich beim EEPROM was anderes aus als ich einlese. Wo ich vorhin den Test mit dem Mega32 und dem PSoC gemacht habe hatte ich dasselbe Problem und da ließ sich das Problem beheben als ich in Bascom gesagt habe das kein ACK nach der Übertragung kommt. Deswegen vermute ich da den Fehler.

Klebwax
07.10.2012, 00:18
Da schließe ich mich an.....den sehe ich jetzt auch zum ersten mal.

Mit so einem Board rumspielen und keinen Schaltplan haben ??


Nur wie kann ich ein NACK senden?

Man kann kein NACK senden. Ein Byte wird bei I2C in 9 Bits übertragen. Das 9. Bit ist die Quittung. Wenn ein Master von einem Slave liest, taktet er 8 Bits die er liest und liefert selbst beim 9. Bit ACK oder NACK. Das NACK (resp. ACK) ist Teil des Reads. Das bedeutet, man kann entweder einen Read mit ACK oder einen Read mit NACK machen.

Für I2C gibt es bei Linux einen ganzen Zoo von Funktionen, da sollte was dabei sein. Ein wenig in den Header-Files suchen oder in den Sourcen von i2cdetect oder lmsensors. Wenn man erstmal einen Funktionsnamen hat, findet sich der Rest.

BTW die 3,6V Zehner sind witzlos. Bis die richtig leiten, werden es schon mal 4V und mehr. Wenn es denn sein muß (warum eigentlich, bei Open Collector kann es nicht höher werden, als die Spannung am Pullup) Klemmdioden nach 3,3V.

MfG Klebwax

peterfido
07.10.2012, 00:21
Nur leider lese ich beim EEPROM was anderes aus als ich einlese.

Ich bin etwas verwirrt.

Was meinst Du mit Ack NACH der Übertragung? Beim lesen sendet doch der Master als letztes ein Nack, wenn ich mich richtig erinnere.

Kampi
07.10.2012, 00:26
Ah ok danke für die Korrektur, hab gedacht das NACK kommt vom Slave.
Es war aber das Fehlen vom NACK welches den Fehler verursacht hat. Es lässt sich reproduzieren und verschwindet auch direkt wenn man ein NACK nach dem Lesen im Bascom angibt und daher vermute ich das es beim Pi genau so sein wird.
Dann werde ich mich morgen wohl mal auf die Suche machen müssen.....mal schauen ob sich was findet.

peterfido
07.10.2012, 00:28
Mit so einem Board rumspielen und keinen Schaltplan haben ??

Ja sicher doch. Wozu einen Schaltplan? Pinout des für mich interessanten Header reicht doch. Habe beim PC ja auch nur die Belegung der Schnittstellen und keinen kompletten Schaltplan zur Hand.


BTW die 3,6V Zehner sind witzlos. Bis die richtig leiten, werden es schon mal 4V und mehr. Wenn es denn sein muß (warum eigentlich, bei Open Collector kann es nicht höher werden, als die Spannung am Pullup) Klemmdioden nach 3,3V.

Hauptsache, am anderen Ende sind nicht auch aus Versehen Pullups zu den 5V drin.
Der Raspi kann mit Sicherheit kurze Spannungssprünge besser ab, als ständig anliegende 5V. Man könnte auch Widerstände in Serie statt der Zenerdioden als Schutz verwenden. Mir haben die Zenerdioden schon geholfen. Zumindest lebt der Raspi noch, obwohl ich mal aus Versehen den FTDI auf 5V IO statt 3,3 stehen hatte.

BastelWastel
07.10.2012, 23:16
Servus Kampi..

Hatte eben Zeit i2c-tools zu testen.
Klappt so weit..kann die Adressen der Devices am Bus sehen.

Aber was ich noch nicht gefunden habe ist eine brauchbare Doku zu den i2c-tools.
Hast du da zufällig was auf Lager?

Gruß, Andreas

Klebwax
08.10.2012, 00:47
Ja sicher doch. Wozu einen Schaltplan? Pinout des für mich interessanten Header reicht doch. Habe beim PC ja auch nur die Belegung der Schnittstellen und keinen kompletten Schaltplan zur Hand.
Das sind ja auch definierte Schnittstellen, für die es geschriebene Standards gibt. Aber wie die Frage nach den i2C Pullups zeigt, ist ein Schaltplan bei einem "Bastelboard" wie dem Pi nützlich und manchmal notwendig. Ebenso ist die Schaltung bei GPIOs wichtig, dagegen kann man USB oder HDMI in den Standards nachlesen. Wenn ich eine Elektronik einsetze, für die es einen Schaltplan gibt, habe ich mir den auch angesehen.


Aber was ich noch nicht gefunden habe ist eine brauchbare Doku zu den i2c-tools.
Ob Google da helfen kann? Das ist ein Linux System, dafür gibt es bis zum Source Code alles öffentlich.

MfG Klebwax

Kampi
08.10.2012, 05:29
Servus Kampi..

Hatte eben Zeit i2c-tools zu testen.
Klappt so weit..kann die Adressen der Devices am Bus sehen.

Aber was ich noch nicht gefunden habe ist eine brauchbare Doku zu den i2c-tools.
Hast du da zufällig was auf Lager?

Gruß, Andreas

Ne hab noch keine gefunden.
Hatte gestern aber auch nicht die Zeit/Lust nach einer zu suchen ;)

ePyx
08.10.2012, 05:51
i2ctools gehört zu lmsensors-Projekt.

Doku : http://www.lm-sensors.org/wiki/i2cToolsDocumentation

Btw. man i2c-tools hilft eventuell.

Auch nett : http://www.e-reflexes.de/oxy_blog/?tag=i2c-scanner

Kampi
08.10.2012, 06:00
Aber die Doku erklärt immer noch nicht so richtig warum ich keinen Zugriff auf meinen PSoC habe (also via I²C).
Bei meinem RN-Control geht das problemlos nur das Raspberry zickt bisschen. Da kommt sowohl beim lesen als auch beim schreiben der selbe Fehler obwohl das Device bei i2cdetect auftaucht.

ePyx
08.10.2012, 07:46
Aber die Doku erklärt immer noch nicht so richtig warum ich keinen Zugriff auf meinen PSoC habe (also via I²C).

Das mag daran liegen, dass die ursprüngliche Frage auf den PCF8574 bzw. die Verwendung der R/W-Adressen zielte und nicht auf deinen PSoC. Des Weiteren habe ich gerade den Thread von vorn bis hintern noch einmal gelesen und keine Frage dies bezüglich finden können. (Ist noch früh daher kann es auch sein, dass ich etwas übersehen habe).
Von daher kann man ein Problem nicht lösen, wenn man es nicht kennt.

Kampi
08.10.2012, 08:21
Auf Seite 4 ganz oben wird es erwähnt :)
Also das Problem ist dieses (nochmal zusammengefasst):
Ich habe einen I²C Bus aus einem Raspberry Pi als Master, einem 24C128 EEPROM, einem PCF8574 und einem PSoC als I²C Slave (benutze das EzI²C Modul http://www.cypress.com/?docID=34801).
Per i2cdetect werden ALLE Geräte am Bus erkannt, aber das Schreiben und Lesen klappt nur beim PCF8574 richtig. Beim EEPROM lese ich was anderes aus als ich rein geschrieben habe und beim PSoC schlägt das Lesen und das Schreiben fehl.
Den PSoC als I²C Slave habe ich aber bereits mit einem Mega32 als Master ausprobiert und da klappte sowohl das Lesen als auch das Schreiben des Mega32 von dem PSoC problemlos.
Hier ist mal der Testcode vom Mega32:



'Mikrocontroller
$regfile = "m32def.dat"
$crystal = 16000000
$baud = 19200


'Stacks
$hwstack = 200
$swstack = 200
$framesize = 400


'TWI konfigurieren
Config Sda = Portc.1
Config Scl = Portc.0
Config Twi = 100000 'TWI Frequenz


'Adresse des PCF
Const Psocw = &H80
Const Psocr = &H81 'Adresse vom PSoC. Der PSoC hat softwareseitig die
'0x40 als 7-Bit Adresse bekommen. Mit R/W Bit ergibt
'Variablen 'dies 0x80
Dim Bitmuster As Byte
Dim Buffer As Byte


Bitmuster = 0
Buffer = 0


'I²C initialisieren
I2cinit


Do


'PSoC beschreiben
I2cstart 'TWI Startkondition
I2cwbyte Psocw
I2cwbyte 0 'Startadresse des I²C Buffers vom PSoC
I2cwbyte Bitmuster 'Daten übertragen
I2cstop


'PSoC auslesen
I2cstart
I2cwbyte Psocr
I2crbyte Buffer , Nack


Print "Wert: " ; Buffer 'Ausgabe der Daten


Incr Bitmuster 'Bitmuster um eins erhöhen


Wait 1


Loop
End


Und vom PSoC:


//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------


#include <m8c.h> // Part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules


// Variablen
char Wert = 100;


// Funktionen
void I2C_Init(void);


void main(void)
{
M8C_EnableGInt;
LCD_Start(); // LCD Modul aktivieren

LCD_Position(0,0);
LCD_PrCString("PSoC I2C Slave");

EzI2Cs_SetRamBuffer(1, 1, (char *)&Wert); // I²C Buffer setzen, 1 Byte Größe, 1 Byte Schreib/Lesbar

I2C_Init();

while(1)
{
LCD_Position(1,0);
LCD_PrCString("Wert:");
LCD_Position(2,0);
LCD_PrHexInt(Wert);
}
}


void I2C_Init(void)
{
EzI2Cs_Start(); // I²C Modul starten
EzI2Cs_EnableInt(); // I²C Interrupts aktivieren
}


Hoffe das Problem ist dadurch etwas klarer geworden :)

Edit:
Den PSoC betreibe ich mit 5V. Da das Raspberry Pi nur 3,3V Pegel verwendet, nutze ich die Pull-Ups vom Raspberry Pi und habe damit einen 3,3V I²C Pegel.
Laut dem Datenblatt von dem Chip

http://www.datasheetcatalog.org/datasheet2/3/06o2c5d1lqskgz7998j2lq6ps83y.pdf

reichen 2,1V für einen High Pegel aus. Es kann also auch nicht sein das er die Pegel nicht erkennt.

m.a.r.v.i.n
08.10.2012, 09:11
Hallo Daniel,
Laut I2C Spezifikation müssten es für HIGH Pegel VCC*0.7 sein. Bei 5V VCC wären das 3.5V, bei 3.3V VCC 2.31V. Die 2.1V beziehen sich demnach auf 3V VCC. Wenn du den Chip mit 5V betreibst, gilt 3.5V.
Dass manche Bauteile trotzdem noch gehen, mag Zufall sein. Du brauchst wohl einen Level Shifter für I2C oder du betriebst den PSOC auch mit 3.3V.

Kampi
08.10.2012, 09:52
Erstmal danke für den Hinweis.
Wieso muss ich den für die Pegel die Betriebsspannung des Chips nehmen?
Der Bus läuft doch auf 3,3V und I²C ist doch Open Collector von daher sollte da doch die Betriebsspannung des Chips egal sein (oder habe ich da einen Denkfehler?)
Weil ich bin bisher immer von der Busspannung ausgegangen.
Ansonsten kennt jemand einen Levelshifter im DIP Gehäuse ;)? Weil das Board mit 3,3V betreiben geht (glaube ich) nicht.

Klebwax
08.10.2012, 10:16
Den PSoC betreibe ich mit 5V. Da das Raspberry Pi nur 3,3V Pegel verwendet, nutze ich die Pull-Ups vom Raspberry Pi und habe damit einen 3,3V I²C Pegel.
Laut dem Datenblatt von dem Chip

http://www.datasheetcatalog.org/datasheet2/3/06o2c5d1lqskgz7998j2lq6ps83y.pdf

reichen 2,1V für einen High Pegel aus. Es kann also auch nicht sein das er die Pegel nicht erkennt.

So ist es.


Laut I2C Spezifikation müssten es für HIGH Pegel VCC*0.7 sein.

Mindestens bedeutet, daß es auch weniger sein kann. Und wenn das Datenblatt des Chips sagt, 2,1V ist das voll in den Specs. Da die Chips erkannt werden, liegt das Problem woanders. Jetzt noch eine zweite Baustelle mit Pegelwandlern aufzumachen ist nicht zielführend.

MfG Klebwax

m.a.r.v.i.n
08.10.2012, 11:41
Im PSOC Datenblatt steht nur was von 2.1V für GPIO. Ob damit auch I2C gemeint ist, würde ich nicht von ausgehen. Mindestens 0.7*VCC für HIGH Pegel heisst gleich oder größer, aber nicht weniger. Wenn es mit dem Mega32 (ich nehme an unter 5V) geklappt hat und mit dem Raspberry Pi unter 3.3V nicht, dann spricht das für Pegelprobleme. Es kann natürlich auch ein Software Fehler im RasPi Code sein.

5V zu 3V Pegelwandler gibt es von AdaFruit (http://www.watterott.com/de/4-channel-I2C-safe-Bi-directional-Logic-Level-Converter-BSS138) oder Sparkfun (http://www.watterott.com/de/Pegelwandler).

Kampi
08.10.2012, 12:08
Ja der Mega32 wurde mit 5V betrieben.
Im Grunde hat der PSoC nur GPIOs. Die Pins werden erst in der Software konfiguriert. Da kann man sich aussuchen wo man den I²C hinlegen will (gibt glaube ich P1.0 und 1.1 sowie 1.5 und 1.7 zur Auswahl). Von daher vermute ich das diese Spezifikationen egal für welches Protokoll/Anwendung sind.
Sicher bin ich mir da aber nicht.
Der Pegelwandler von Sparkfun eignet sich aber nicht für I²C soweit ich sehe. I²C ist bidirektional und der ist nur für eine Richtung. Oder sehe ich das falsch?

Klebwax
08.10.2012, 12:20
Um aber mit der SW weiterzukommen, habe aus einem Beispiel-Code aus dem Netz ein Stück zusammengeschnitten, mit dem ich auf meinem Desktop-PC vermutlich das EEPROM meines Monitors auslesen kann. Wegen der Übersichtlichkeit sind die Adressen hardcoded und ein wirkliches Schreiben habe ich nicht probiert, um den Rechner nicht zu gefärden.


#include <linux/i2c-dev.h>
#include <stdio.h>
#include <fcntl.h>

#define NUMBYTES 20

int main() {

int file;
char filename[] = "/dev/i2c-0";
char buffer[20];
int i;

file = open(filename, O_RDWR);
if (file < 0) {
perror("i2c-test open: ");
return -1;
}
/* You can do plain i2c transactions by using read(2) and write(2) calls.
* You do not need to pass the address byte; instead, set it through
* ioctl I2C_SLAVE before you try to access the device.
*/
if (ioctl(file, I2C_SLAVE, 0x50) < 0) {
perror("i2c-test set slave address: ");
return -1;
}
buffer[0] = 0; // set read pointer in I2C slave
if(write(file, buffer, 1) != 1) {
perror("i2c-test write: ");
return -1;
}
if (read(file, buffer, NUMBYTES) != NUMBYTES) {
perror("i2c-test read: ");
return -1;
} else {
for(i = 0; i < NUMBYTES; i++) {
printf("%02x ", (unsigned char)buffer[i]);
}
printf("\nok\n");
}
return 0;
}

Vielleicht hilfts

MfG Klebwax

ePyx
08.10.2012, 12:47
Der Pegelwandler von Sparkfun eignet sich aber nicht für I²C soweit ich sehe. I²C ist bidirektional und der ist nur für eine Richtung. Oder sehe ich das falsch?


Pegelwandler ist bidirektional wegen der MOSFETs. Habe mir den auch schon selber (http://www.epyx-online.de/bidirektionaler-levelshifter-fur-i²ctwi/)aufgebaut. Nicht schön, aber schneller aufzubauen und günstiger als ein PCA9603 oder ähnliche Wandler.
23398 (http://www.epyx-online.de/wp-content/gallery/elektronik/2012-02-09_20-21-09_994.jpg)

Kampi
08.10.2012, 12:55
Gut.
Das Programm teste ich heute/morgen mal. Wenn das klappt ist das Problem mit dem EEPROM schon mal beiseite. Dann bleibt nur noch der PSoC.... :/

BastelWastel
08.10.2012, 13:11
Ob Google da helfen kann? Das ist ein Linux System, dafür gibt es bis zum Source Code alles öffentlich.

Haette ich was gefunden wuerde ich nicht gross dumm fragen...



i2ctools gehört zu lmsensors-Projekt.

Doku : http://www.lm-sensors.org/wiki/i2cToolsDocumentation

Btw. man i2c-tools hilft eventuell.

Auch nett : http://www.e-reflexes.de/oxy_blog/?tag=i2c-scanner

Genau nach sowas hatte ich gesucht.
War zwar schon auf lm-sensors, hatte aber nur ne Doku ueber i2c generell gefunden.
Besten Dank :)

ePyx
08.10.2012, 13:15
Wenn Google bei allem helfen würde, bräuchten wir kein Forum mehr. Oftmals ist es einfach nur zu spät und die zündende Idee für den passenden Suchbegriff fehlt.

Ist auch keine Frage : "Wie steuer ich bei meinem Arduino die LED an..."

Kampi
08.10.2012, 14:56
Um aber mit der SW weiterzukommen, habe aus einem Beispiel-Code aus dem Netz ein Stück zusammengeschnitten, mit dem ich auf meinem Desktop-PC vermutlich das EEPROM meines Monitors auslesen kann. Wegen der Übersichtlichkeit sind die Adressen hardcoded und ein wirkliches Schreiben habe ich nicht probiert, um den Rechner nicht zu gefärden.


#include <linux/i2c-dev.h>
#include <stdio.h>
#include <fcntl.h>

#define NUMBYTES 20

int main() {

int file;
char filename[] = "/dev/i2c-0";
char buffer[20];
int i;

file = open(filename, O_RDWR);
if (file < 0) {
perror("i2c-test open: ");
return -1;
}
/* You can do plain i2c transactions by using read(2) and write(2) calls.
* You do not need to pass the address byte; instead, set it through
* ioctl I2C_SLAVE before you try to access the device.
*/
if (ioctl(file, I2C_SLAVE, 0x50) < 0) {
perror("i2c-test set slave address: ");
return -1;
}
buffer[0] = 0; // set read pointer in I2C slave
if(write(file, buffer, 1) != 1) {
perror("i2c-test write: ");
return -1;
}
if (read(file, buffer, NUMBYTES) != NUMBYTES) {
perror("i2c-test read: ");
return -1;
} else {
for(i = 0; i < NUMBYTES; i++) {
printf("x ", (unsigned char)buffer[i]);
}
printf("\nok\n");
}
return 0;
}

Vielleicht hilfts

MfG Klebwax

Also das Programm funktioniert. Er ließt die Zellen aus.
Jetzt muss ich das nur mal mit einem Write kombinieren um zu sehen ob das auch klappt :)
Danke dafür!

Edit: Beim zweiten mal ausführen spuckt er aber nur 0xff aus. Wieso?

Klebwax
08.10.2012, 15:10
Haette ich was gefunden wuerde ich nicht gross dumm fragen...

23399

MfG Klebwax

Klebwax
08.10.2012, 15:22
Also das Programm funktioniert. Er ließt die Zellen aus.
Jetzt muss ich das nur mal mit einem Write kombinieren um zu sehen ob das auch klappt :)
Danke dafür!

Edit: Beim zweiten mal ausführen spuckt er aber nur 0xff aus. Wieso?

$ sudo ./i2c-test
00 ff ff ff ff ff ff 00 04 72 be 00 e7 7d 11 01 0b 14 01 03

Das geht bei mir beliebig oft.

Write bei einem EEPROM sollte so gehen:

buffer[0] = Adresspointer im EEPROM
buffer[1] = Datenbyte
..
buffer[x] = Datenbyte

write(fd, buffer, x+1)

Wieviel man auf einmal schreiben kann, hängt vom EEPROM ab. Wenn man nicht auf eine Ready wartet, sollte man vor dem nächsten read oder write etwas Pause machen.

MfG Klebwax

BastelWastel
08.10.2012, 15:56
War zwar schon auf lm-sensors, hatte aber nur ne Doku ueber i2c generell gefunden.

Wenn du da mal auf Dokumentation klickst findest du ne Doku ueber i2c, nicht ueber i2c-tools..darum meine Frage.
Wie dem auch sei, danke fuer deinen redundanten Hinweis auf die existenz Goggles..

Gruss

Kampi
08.10.2012, 16:17
$ sudo ./i2c-test
00 ff ff ff ff ff ff 00 04 72 be 00 e7 7d 11 01 0b 14 01 03

Das geht bei mir beliebig oft.

Write bei einem EEPROM sollte so gehen:

buffer[0] = Adresspointer im EEPROM
buffer[1] = Datenbyte
..
buffer[x] = Datenbyte

write(fd, buffer, x+1)

Wieviel man auf einmal schreiben kann, hängt vom EEPROM ab. Wenn man nicht auf eine Ready wartet, sollte man vor dem nächsten read oder write etwas Pause machen.

MfG Klebwax

mmh ich weiß natürlich nicht ob das EEPROM in Ordnung ist. Vielleicht hat das Ding ja schon nen Schuss......

Kampi
08.10.2012, 17:08
Also ich habs nochmal probiert und es kommt immer nur 0xff raus. Selbst nach einem Reboot ändert sich nichts.
Ich vermute stark, dass das EEPROM einen Schuss hat da du ja sagst das es bei dir funktioniert.
Ich probier das nachher auch mal mit meinem PSoC der soll sich laut Datenblatt ja wie ein EEPROM verhalten....mal schauen ob das stimmt.....

Kampi
09.10.2012, 19:53
Also das I²C Problem hat sich wohl gelöst.
Ich Depp habe vergessen, dass das EEPROM eine 16-Bit Adresse hatte und beim PSoC habe ich ein Byte zuviel gesendet, da ich dachte man müsse einen Pointer setzen ab wann man das EEPROM auslesen will.
Wenn ich aber nur

i2cget -y 0 0x40

sende, statt wie vorher

i2cget -y 0 0x40 0x00

klappt es 1a.

ePyx
10.10.2012, 05:46
Also das I²C Problem hat sich wohl gelöst.
Ich Depp habe vergessen, ....
klappt es 1a.

Wieder die Sache mit dem zwischen Monitor und Bürostuhl. ;) Aber schön das es nun funktioniert und nichts Schlimmeres der Grund war.

Kampi
10.10.2012, 07:48
Ja aber erstmal nur mit dem EEPROM. Den PSoC kann ich bisher nur auslesen aber mit dem Schreiben weiß ich noch nichts neues.
Da kommt immer ein Error :/

Kampi
10.10.2012, 21:00
Heyho,

hab mal wieder bisschen rumgespielt und dabei ist ein Programm rausgekommen um eine DS1307 auszulesen (gar nicht gewusst das man das Ding nicht mit 3,3V betreiben kann. Habs erst gemacht und dann gewundert warum ich das Ding nicht im Bus gesehen habe..... -.-)


// Compile with: gcc /Programme/DS1307.c -o /Programme/DS1307


#include <stdio.h>
#include <stdlib.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


#define Buffer 7


char BCD2D(char Wert)
{
return (Wert%16 + 10 * (Wert/16));
}


int main()
{
int File;
char Device[] = "/dev/i2c-0";
char RTC = 0x68;
char Date[7];
int i;

if ((File = open("/dev/i2c-0", O_RDWR)) < 0) // I²C aktivieren
{
printf("I²C Modul kann nicht geladen werden!\n");
return -1;
}

if (ioctl(File, I2C_SLAVE, RTC) < 0) // Port und Adresse setzen
{
printf("Deviceadresse wurde nicht gefunden!\n");
exit(1);
}

Date[0] = 0; // Pointer auf Adresse 0 (Startadresse) setzen

if(write(File, Date, 1) != 1)
{
printf("Fehler beim Schreiben der Daten!\n");
return -1;
}

if (read(File, Date, Buffer) != Buffer)
{
printf("Fehler beim Lesen der Daten!\n");
return -1;
}
else
{
// Werte von BCD in Dezimal umwandeln
for(i = 0; i < Buffer; i++)
{
Date[i] = BCD2D(Date[i]);
}

printf("DS1307 Ausgabe");
printf("\n");
printf("\n");

// Uhrzeit ausgeben
printf("Stunden: %d", Date[2]);
printf("\n");
printf("Minuten: %d", Date[1]);
printf("\n");
printf("Sekunden: %d", Date[0]);
printf("\n");


// Tage ausgeben
printf("Jahr: 20%d", Date[6]);
printf("\n");
printf("Monat: %d", Date[5]);
printf("\n");
printf("Tag: %d", Date[4]);
printf("\n");



printf("Wochentag: %d", Date[3]);
printf("\n");
}

close(File);
return 0;
}

BastelWastel
16.10.2012, 16:47
Laesst du deine i2c Funktionen im main()?
Ich hab mich gestern noch ein wenig mit C befasst (kompletter C-Anfaenger) und angefangen dass nach bestem Wissen und Gewissen in Funktionen und in separate files zu packen.
Vllt. kann ich dich ja als debug user begeistern wenn ich fertig bin :D
(bevor ich wieder erschlagen werd, ja ich bin mir sicher da gibts schon *.h und *.c files fuer, aber der Lerneffekt... ;) )

Kampi
16.10.2012, 20:09
Das Programm nutze ich jetzt eh nimmer. Hab mein Raspberry Pi so eingestellt, dass es die Uhrzeit aus der DS1307 holt. Dadurch wird die RTC quasi blockiert und die Systemzeit des Pis immer aktuell.....netter kleiner Stolperstein war noch die Zeitzone....hab mich gewundert warum die Zeit dauernd zwei Stunden hinterher ging ^.^
Aber ansonsten wüsste ich bei dem Programm keinen Grund die Sachen nochmal in Funktionen zu packen.

Kampi
27.10.2012, 16:18
Also ich habe eben nochmal bisl rumprobiert (diesmal mit einem anderen PSoC Board).
Das Lesen klappt auf einmal problemlos.......sogar mit dem ersten Board.....
Schreiben schlägt noch immer fehl......aber zumindest habe ich jetzt meine CapSense Tasten am Pi hängen und kann die auswerten. Bei denen brauche ich eigtl nicht schreiben ^.^

Kampi
20.01.2013, 11:11
Hey,

ich wollte nur mal einen aktuellen Stand posten......
Ich habe es nun mittlerweile geschafft den PSoC als Slave zu nutzen.
Der Fehler war anscheinend die Geschwindigkeit. Mit 100k kann ich nur lesen und nicht schreiben. Aber bei 400k klappt beides (hätte ich mal früher drauf kommen können dies zu testen >.<)

porter91
23.01.2013, 17:42
Hey wo bekomm ich die includes für das I"c auf dem Pi her ??

Kampi
23.01.2013, 19:00
Die sind schon auf dem Pi. Ich habe zumindest nichts installieren müssen.