okay soweit. Demnach ist das kleine Ding etwas schwieriger anzusprechen als andere EEproms mit nur einer Device Adresse. Noch eine Frage. Woher weist du das die Deviceadresse 0x50 ist? Ich lese das aus dem Datenblatt nicht heraus. Lese immer nur von 1010 MSB. 0x50 sind aber 0101.0000
Lese immer nur von 1010 MSB. 0x50 sind aber 0101.0000
0b01010XXX
Wobei die XXX den A2,A1,A0 Eingängen vieler EEproms entsprechen.
Bei deinem 24C08 ist E der A2 Eingang
Also gilt für dein EEPROM
Startadresse: 0b01010000 mit E auf GND
Startadresse: 0b01010100 mit E auf Vcc
Gegenprobe:
Löte E auf Vcc, dann beginnen die Adressen mit 0x54
Ach ja: (was auch noch zur Verwirrung beiträgt)
Wire schiebt die GeräteAddresse um einen nach links, und klebt das r/w Bit an Position Null.
Das r/w Bit bleibt uns Arduino Usern verborgen.
PS:
Ich finde diesen s*heiß Fehler in meiner Lib nicht!
Ich glaube, ich muss stark umbauen und unmengen Debug Kommandos einbauen....
Mal schauen, wie ich das in den Griff bekomme...
das verschobene RW Bit hat mich letztens bei meinem Datalogger Projekt auch zur Verzweiflung gebracht. Als mir das egal war und ich es nicht mehr beachtet habe, funktionierte dennoch alles. Also habe ich mich nicht weiter darum gekümmert. Das EEprom vom 3231 RTC Modul kam zum Einsatz.
Deine Lib funktioniert bei all deinen EEproms nur nicht bei meinem süßen kleinen? Nur zum Verständnis für mich.
Wenn ich irgendwas testen soll, nur zu. Das Ding ist schnell verkabelt.
Deine Lib funktioniert bei all deinen EEproms nur nicht bei meinem süßen kleinen? Nur zum Verständnis für mich.
Ich habe hier nur einige EEProms mit 2 Byte Addressmodus.
Z.B. das AT24C32 auf der RTC
Die funktionieren. (kannst gerne mal testen)
Wichtig ist mir, den 1 Byte Addressmodus zu testen.
Und genau die Chance bietest du mir mit deinem kleinen EEProm
Du schreibst immer von 0 1 0 1 .... was scheinbar stimmt. Nur warum ist die Bitfolge anders?
Wire schiebt die von mir angegebene Adresse um 1 Bit nach links, um Platz für das r/w Bit zu bekommen.
Und damit stimmt das Resultat dann mit dem Datenblatt überein.
okay. Mit dem Bit verschieben ist wirklich verwirrend.
Das zeigt der I2C Scanner auch die verschobene Arduinische Adresse an?
Außerhalb der Arduino IDE fliegt man damit auf die Schnauze?
Das Bsp. CharArray mit meinem RTC3231 Modul
AT24C32<0x57> eep; // Das EEProm auf der china üblichen RTC, default Adresse 0x50 (80)
Vielleicht solltest du den Kommentar ändern. Oder hat das einfachere RTC 1307 Modul 0x50?
bringt:
EE Prom lenth: 4096
EE Prom ist bereit!
eep.get() 70160
fastBlockRead 27124
Dieses ist ein total langer Teststring. Eigentlich muesste hier ein ganzer Roman stehen.
wegen dem Fehler für den ST24C08. Vielleicht haste was übersehen? Die AT24C08 und ST24C08 unterscheiden sich vielleicht nochmehr als nur in der Device Adressierung. ???
Ja! (zumindest meine)
Vielleicht sollte ich den Kommentar konkretisieren.
Außerhalb der Arduino IDE fliegt man damit auf die Schnauze?
Alle mir bekannten Libs, auf allen mir bekannten Systemen, arbeiten mit der 0x50 o.ä.
Erst wenn man selber an den Registern fummelt, seine eigenen I2C Routinen schreibt, kommt man mit der "Wahrheit", mit der verschobenen Addresse incl. r/w, in Berührung.
Wire schützt uns davor, das Datenblatt zu verstehen! 8)
Die AT24C08 und ST24C08 unterscheiden sich vielleicht nochmehr als nur in der Device Adressierung.
Das habe ich schon mehrfach gemacht, werde ich aber nochmal tun.
Sie unterscheiden sich etwas in den Pins, und ihrer Nutzung, auch in den Wartezeiten nach dem Schreiben.
Aber Softwaretechnisch sollten sie sich identisch ansprechen lassen.
Es gibt jetzt ein Beispiel Debug, welches viele Ausgaben macht.
Dieses schreibt an die EEProm Adresse 250 usw um den Blockwechsel zu testen.
Habe einen fetten Bock in der Lib gefunden:
! Auch das Template-Switch-Case Konstrukt bedarf eines break; !
Grrr .... (tausend mal drüber geschaut, immer übersehen)
Die frische Zip liegt auf dem Server.
Jetzt hoffe ich mal, dass die Lib läuft!
habe keine Ahnung was du da machst, teste es aber gern.
Debug Sketch Ausgabe hängt als .c File dran, sieht schöner aus, nutze Notepad++
CharArray funktioniert demnach mit
ST24C08<0x50> eep;
EE Prom lenth: 1024
EE Prom ist bereit!
eep.get() 60200
fastBlockRead 13468
Dieses ist ein total langer Teststring. Eigentlich muesste hier ein ganzer Roman stehen.
Update:
Unterstützung für die ATTinys eingebaut.
Ist noch nicht vollständig getestet. Sieht allerdings auf dem LogikAnalyser schon voll toll aus.
Ein paar weitere EEProms hinzugefügt.
Beispiele überarbeitet
Tiny85 Beispiel hinzugefügt
Dabei habe ich mal wieder erfahren, warum globale Variablen gruseliger Mist sein können!
Auf dem UNO wird Wire.h genutzt, Folgerichtig wird eine globale Variable namens Wire angelegt. Auf dem Tiny ist TinyWireM.h das Mittel der Wahl. Und mit gnadenloser Konsequenz heißt das Objekt TinyWireM. Die Beiden sind noch nicht einmal von der selben Basisklasse abgeleitet. Und das obwohl beide die selbe Methoden Signatur haben.
Grr....
Und das Interface Konzept gibts in C++ auch nicht.
Na klar, Lösung gefunden.....
Aber die ist genau so elegant, wie das Problem...
#ifndef EEP_WIRE
// definiert in TinyWireM.h
#ifdef TinyWireM_h
#define EEP_WIRE TinyWireM
#endif
// definiert in Wire.h
#ifdef TwoWire_h
#define EEP_WIRE Wire
#endif
#endif
#ifndef EEP_WIRE.
#error Weder Wire, noch TinyWireM gefunden. EEP_WIRE ist nicht definiert.
#endif
combie:
Und das Interface Konzept gibts in C++ auch nicht.
Nicht als grundlegendes Pattern wie z.B. in C#, aber Interfaces gibt es klar. Ein Interface ist eine abstrakte Klasse. Und eine abstrakte Klasse in C++ ist eine Klasse die nur rein virtuelle Methoden (pure virtual function) enthält.
Bringt der in Ermangelung einer gemeinsamen Basisklasse aber auch nichts.
Serenifly:
Bringt der in Ermangelung einer gemeinsamen Basisklasse aber auch nichts.
So ist es!
Ja, mit meinen Defines komme ich auch so noch nicht weiter.
Scheinen mehr ein Dirty Häck zu sein, als eine Lösung.
Mein erster Test mit dem Arduino DUE war auch nicht schlecht. Tuts...
Aber da tut sich wieder eine Grube auf:
Der DUE hat 2 mal I2C, und damit gibt es Wire und Wire1.
Und ich möchte dann schon dem User eine Chance geben, Wire1 zu nutzen.
Wie auch immer....
Die Arduino typischen globalen Variablen in Libs spielen mir Streiche. Was die Arduino Jungs im Konzept verbockt haben, dürfen jetzt meine Define Kaskaden auslöffeln...
Vielleicht bekomme ich das auch ins Template gestopft.
Werde mal ausprobieren, was sich schöner anfühlt.....
Makros sind in der Tat wohl der gängige Weg in der Arduino Welt. Sieht man auch bei komplexen Bibliothen wie SdFat.
Du kannst einen config Header machen wo man bestimmte Optionen setzen kann. Einmal einen Default Wert. Und dann eine bestimmte Zeile auskommentieren für die Alternative. z.B. #define USE_WIRE1
Schön es nicht unbedingt (vor allem wenn man nicht immer nur eine der Optionen) nutzt, aber wenn man nicht ständig wechselt ist es auch nicht sooo schlimm
Mit Template Spezialisierung bekommt du es aber wahrscheinlich hin, je nach den Parametern ein bestimmtes Template zu instantiieren.
Bezüglich Interfaces:
Es gibt Arduino Klassen die das teilweise oder komplett nutzen. Die write(uint8_t) Methode ist rein virtuell. Jede Klasse die von Print ableitet muss sie implementieren. Stream hat mehrere rein virtuelle Methoden.
Printable (um Klassen per print() zu drucken) ist ein richtiges Interface mit einer einzigen Methode.
Ja...
Serial, Serial1, Serial2, Serial3 und auch die Software Serials sind Ableitungen von Stream und Print.
Das vereinfacht einige Dinge. Aber nichts desto Trotz, werden diese genauso wie Wire als globale Variablen angelegt. Ausnahme SoftSerial.
Aber das ist nicht meine Baustelle!
Ich glaube nicht, dass ich die Arduinos überredet bekomme, diese Variablen über Bord zu werfen.
Defines sind erst mal das Mittel der Wahl!
Update:
Die Möglichkeit geschaffen beliebige WireObjekte zu übergeben.
Einzige Bedingung: Sie müssen Aufrufkompatibel zum Arduino Wire sein.
Das Beispiel ArduinoDueWire1 zeigt die Verwendung.
Damit müssten auch einige, im Internet kursierende, SoftWire funktionieren.
Naja, schön ist auch das noch nicht.
Denn so bekommt man die EEProms nicht auf beide (oder wieviel auch immer) I2C Busse verteilt. Es ist immer nur die Nutzung eines Busses möglich.
Grr...
Doch besser per Template?
Du kannst einen config Header machen wo man bestimmte Optionen setzen kann.
Hach....
Ich möchte nicht den User zwingen, im Lib Ordner rum zu basteln.
Die Portabilität der Anwendungsprogramme leidet.
Eine bös versteckte Abhängigkeit.
combie:
Frage mir ein Loch in den Bauch!
Bitte!
Stehe gerne Rede und Antwort.
hab ich gern gemacht. Leider habe ich persönlich noch keine richtige Verwendung für den EEprom. Vielleicht kommt das ja noch. Mein Fragen Guthaben hebe ich mir auf.
Serenifly und Combie. Jetzt fehlt nur noch Uwe, Jurs und Udoklein, dann wären die Fachleute unter sich.
Möchte aber andere die sich noch im Hintergrund halten nicht ausnehmen.
Aus meiner Sicht habe ich bestenfalls "fundiertes Halbwissen" auf dem Gebiet.
Gerade das ++ im C++ hat noch große weiße Flächen.
Es gibt also noch reichlich zu lernen ...
Möchte aber andere die sich noch im Hintergrund halten nicht ausnehmen.
Ich auch nicht!
Wer die Lib nutzen möchte, men los!
Weitere Testberichte sind auch sehr sehr willkommen.
Da ist sicherlich, in den einzelnen Details, noch Verbesserungsbedarf.
Beim Testen meckert der Compiler von IDE 1.8.6 über den Punkt bei
#ifndef EEP_WIRE.
Darf ich den gefahrlos entfernen?
Bei der Verwendung eines 24C256 überprüfe ich die Grenzen der Variablentypen und bin dabei auf ein mir unverständliches int gestolpert, das doch eher vorzeichenlos sein sollte:
for(int i = 0; i < sizeof(T); i++)
Bei put() lasse ich mir die nächste freie Adresse zurückgeben, damit ich nahtlos speichern kann:
uint16_t put(uint16_t address,T &customvar)
{
uint8_t *ptr = (uint8_t*) &customvar;
int i = 0;
for(i = 0; i < sizeof(T); i++)
update(address + i,*ptr++);
return address + i;
}
Ich habe das so gemacht, funktioniert, soweit ich es überprüfen kann, übersehe ich Falltüren?