Go Down

Topic: [Projekt] I2C EEPROM (Read 4864 times) previous topic - next topic

Doc_Arduino

#30
Jan 05, 2016, 07:20 pm Last Edit: Jan 05, 2016, 07:22 pm by Doc_Arduino
Hallo,

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;


Quote
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.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

combie

Quote
Debug Sketch Ausgabe hängt als .c File dran
Das sieht perfekt aus!
Die Device Adresse wechselt schön.



Quote
habe keine Ahnung was du da machst,
Frage mir ein Loch in den Bauch!
Bitte!
Stehe gerne Rede und Antwort.


Quote
teste es aber gern.
Und da bin ich wirklich dankbar für.
Sonst hätte ich den Fehler vermutlich nicht so schnell gefunden.

Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

combie

#32
Jan 06, 2016, 02:00 pm Last Edit: Jan 06, 2016, 04:38 pm by combie
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...

Code: [Select]



#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




Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Serenifly

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.

combie

#34
Jan 06, 2016, 03:09 pm Last Edit: Jan 06, 2016, 03:35 pm by combie
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.....
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Serenifly

#35
Jan 06, 2016, 03:16 pm Last Edit: Jan 06, 2016, 03:23 pm by Serenifly
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.

combie

#36
Jan 06, 2016, 04:01 pm Last Edit: Jan 06, 2016, 04:16 pm by combie
Quote
Bezüglich Interfaces:
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?



Quote
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.


Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

Doc_Arduino

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.  ;)




Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

combie

#38
Jan 06, 2016, 04:28 pm Last Edit: Jan 06, 2016, 04:33 pm by combie
Quote
Fachleute
Ach, das solltest du nicht so sehen....

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 ... ;-)

Quote
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.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

agmue

Beim Testen meckert der Compiler von IDE 1.8.6 über den Punkt bei

Code: [Select]
#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:

Code: [Select]
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:

Code: [Select]
   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?
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

combie

#40
Oct 20, 2018, 12:06 pm Last Edit: Oct 20, 2018, 12:08 pm by combie
Quote
Darf ich den gefahrlos entfernen?
Ja!
Der Punkt da, ist ein Versehen
Und damit flüssiger als Wasser, überflüssig.


Quote
und bin dabei auf ein mir unverständliches int gestolpert, das doch eher vorzeichenlos sein sollte:
Auch hier stimme ich dir zu.

Insgesamt betrifft das 3 Schleifen.
Dort kannst du int gefahrlos und Sinn behaftet, durch uint16_t ersetzen.

Quote
Bei put() lasse ich mir die nächste freie Adresse zurückgeben, damit ich nahtlos speichern kann:
Ich habe das so gemacht, funktioniert, soweit ich es überprüfen kann, übersehe ich Falltüren?
Das kannst du natürlich so tun.

Wobei ich allerdings genau den anderen Weg gehen würde. Und zwar dem Compiler die Berechnung der Adressen überlassen.

Unter zur Hilfenahme von: offsetof()

Das hätte den Vorteil, dass man nicht händisch die Adressen bespielen muss, sondern mit C++ Strukturen arbeitet. So wie man es im Ram auch tun würde.

Wenn du mehr über deine Anwendung, über die Daten, erzählen würdest, könnte ich dir evtl. einen konkreten Vorschlag machen.


---
Danke für die Rückmeldung, die Korrekturen werden eingearbeitet.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

combie

Nachtrag:
Eigentlich wäre die korrekte Implementierung für put() und get() so:

Code: [Select]

  // lesen beliebiger Datentypen
  template< typename T >
  T &get(uint16_t address, T &customvar)
  {
    uint8_t *ptr = (uint8_t*) &customvar;
    for(uint16_t i = 0; i < sizeof(T); i++)
      *ptr++ = read(address + i);
    return customvar;
  }

 

  // schreiben beliebiger Datentypen
 template< typename T >
 const T &put(uint16_t address,const T &customvar)
  {
    uint8_t *ptr = (uint8_t*) &customvar;
    for(uint16_t i = 0; i < sizeof(T); i++)
       update(address + i,*ptr++);
     return customvar;
  }


Denn dann ist es, in dem Punkt, Aufruf kompatible mit der Arduino EEPROM klasse.
Was ja eins meiner Designziele ist/war.
Auch das werde ich dahingehend korrigieren.
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

agmue

Danke für die Rückmeldung, die Korrekturen werden eingearbeitet.
Bitte gerne :)

Wenn du mehr über deine Anwendung, über die Daten, erzählen würdest, könnte ich dir evtl. einen konkreten Vorschlag machen.
Das Angebot nehme ich gerne an!

Es handelt sich um ein mehrere Jahre zurückligendes Thema zum Bau einer Cocktailmaschine, die brav ihren Dienst tut. Per Mail wurde mir nun von dem Wunsch größerer Flexibilität beim Wechsel von Rezepten berichtet. Dies nur als Hintergrund, mich interessiert nur das Programmieren.

Aufgabe: Zwei zweidimensionale Felder unterschiedlichen Typs in einem EEPROM speichern.

Ich verwende diese veränderten Methoden:

Code: [Select]
 // lesen beliebiger Datentypen
  template< typename T >
  uint16_t get(uint16_t address, T &customvar)
  {
    uint8_t *ptr = (uint8_t*) &customvar;
    uint16_t i = 0;
    for(i = 0; i < sizeof(T); i++)
      *ptr++ = read(address + i);
    return address + i;
  }

  // schreiben beliebiger Datentypen
  template< typename T >
   uint16_t put(uint16_t address,T &customvar)
  {
    uint8_t *ptr = (uint8_t*) &customvar;
    uint16_t i = 0;
    for(i = 0; i < sizeof(T); i++)
       update(address + i,*ptr++);
    return address + i;
  }

Lösung 1: Die Zeiger der Felder an die Methoden der Bibliothek übergeben:

Code: [Select]
eep.put(0, Cocktail);
eep.put(adresse, Rezept);

Der Wert von adresse muß berechnet werden, das kann man als Nachteil ansehen.

Lösung 2: Die Daten werden als Struktur gespeichert und auch als ganze Struktur den Methoden der Bibliothek übergeben:

Code: [Select]
eep.put(0, daten);
Basierend auf einem Bibliotheksbeispiel des komplette Testprogramm:

Code: [Select]
#include <Wire.h>
#include <I2C_EEPROM.h>
AT24C256<> eep; // default Adresse 0x50
// AT24C32<0x57> eep; // Das EEProm auf der china üblichen RTC3231

const int Anzahl_Rezepte = 12;  // anzahl Rezepte
const int Anzahl_Zutaten = 16;  // anzahl zutaten
const int Anzahl_Buchstaben = 20;
const int Anzahl_Messwerte = 35;
struct Co
{
  //Cocktailnamen
  char Cocktail[Anzahl_Rezepte][Anzahl_Buchstaben];
  byte Rezept[Anzahl_Rezepte][Anzahl_Zutaten];
};

Co daten =
{
  //Cocktailnamen
  {
    {"     Cuba Libre"}, {"     Pina Colada"}, {"      Cipirinha"}, {"     Touch Down"}, {"       Gin Tonic"},
    {"   Planters Wonder"},  {""}, {""}, {""}, {""}, {"Ventile Sp\365len"}, {"Pumpen Sp\365len"}
  },
  {
    //Angabe im ml  --> 5ml schritten  10-180ml Pumpen und 10-80ml Ventile
    {  0, 50,  0,   0,  0,  0,  0,  0,  0,  0, 180,   0,   0,   0,   0,   0},        // 1 Cuba Libre
    {  0, 25,  0,  60,  0,  0,  0,  0,  0,  0,   0,   0,   0, 115,   0,   0},        // 2 Pina Colada
    { 60,  0,  0,   0,  0,  0, 10,  0,  0,  0,   0,   0,   0,   0,   0,   0},        // 3 Caipirinha
    {  0, 20, 35,   0, 15,  0,  0,  0,  0,  0,   0,   0, 130,   0,   0,   0},        // 4 Touchdown
    {  0,  0,  0,   0,  0, 45, 15,  0,  0,  0,   0,   0,   0,   0, 140,   0},        // 5 Gin Tonic
    //Alkoholfrei
    {  0,  0,  0,  0,   20,  0,  0,  0,  0,  0,   0,  60,  60,  60,  0,   0},       // 6 Planters Wonder
    // Leere
    {  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,   0,   0,   0,   0,  0,   0},
    {  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},
    {  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},
    {  0,  0,  0,  0,   0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},
    //Spülen
    { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  0,  0,  0,  0,  0,  0},        // Taster 11 Ventile Spülen
    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10, 10, 10, 10, 10, 10},        // Taster 12 Pumpen Spülen
  }
};

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  Serial.print("EE Prom length: ");
  Serial.println(eep.length());

  if (eep.ready())
    Serial.println ("EE Prom ist bereit!");
  else Serial.println("EE Prom ist nicht bereit, Verkabelung prüfen ");

  uint16_t adresse = eep.put(0, daten); // ins EEProm schreiben
  Serial.print("Adresse put: ");
  Serial.println(adresse);
  char test[450];
  adresse = eep.get(0, test); // String lesen
  Serial.print("Adresse get: ");
  Serial.println(adresse);
  for (uint16_t j = 0; j < sizeof(test); j++)
  {
    if (j < 1000) Serial.print(' ');
    if (j < 100) Serial.print(' ');
    if (j < 10) Serial.print(' ');
    Serial.print(j);
    Serial.print('\t');
    if (j < (Anzahl_Rezepte * Anzahl_Buchstaben))
    {
      Serial.print((uint8_t)test[j], HEX);
      Serial.print('\t');
      if (test[j] >= ' ' && test[j] <= '~')
      {
        Serial.print(test[j]);
      } else {
        Serial.print(' ');
      }
    } else {
      Serial.print((uint8_t)test[j], DEC);
    }
    Serial.println();
  }
}

void loop()
{
}

Bei der Verwendung einer Sruktur muß put nur einmal aufgerufen werden, womit die Adressberechnung wegfällt.

Frage:
Unter zur Hilfenahme von: offsetof()
Die Idee mit der Struktur habe ich gerne aufgegriffen, wie mir offsetof() helfen soll, erschließt sich mir leider nicht.
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

combie

#43
Oct 22, 2018, 09:42 am Last Edit: Oct 22, 2018, 09:58 am by combie
Jetzt, nach dem ich deine Daten gesehen habe....
Sehe ich auch, dass offsetof() nicht unbedingt hilft.

Aber dennoch, kann man dem Compiler die Adressberechnung überlassen.
Stichwort "Pointer Arithmetik"

Meine Änderungen/Korrekturen, an der Lib, habe ich in die ZIP im Eingangspostig einfließen lassen.
Deine Änderung, mit der Adressrückgabe, ist nicht nötig.


Die Daten habe ich etwas umstrukturiert...
Schien mir Sinnvoll zu sein.

Code: [Select]

#include <Wire.h>
#include <I2C_EEPROM.h>
// AT24C256<> eep; // default Adresse 0x50
AT24C32<0x57> eep; // Das EEProm auf der china üblichen RTC3231

const int Anzahl_Rezepte = 12;  // anzahl Rezepte
const int Anzahl_Zutaten = 16;  // anzahl zutaten
const int Anzahl_Buchstaben = 20;
// const int Anzahl_Messwerte = 35;



struct Cocktail
{
  char name[Anzahl_Buchstaben];
  byte zutaten[Anzahl_Zutaten];
};

using Daten = Cocktail[Anzahl_Rezepte]; // custom array type definition


Daten daten {
              {{"     Cuba Libre"},   {  0, 50,  0,   0,  0,  0,  0,  0,  0,  0, 180,   0,   0,   0,   0,   0},},
              {{"     Pina Colada"},  {  0, 25,  0,  60,  0,  0,  0,  0,  0,  0,   0,   0,   0, 115,   0,   0},},
              {{"      Cipirinha"},   { 60,  0,  0,   0,  0,  0, 10,  0,  0,  0,   0,   0,   0,   0,   0,   0},},
              {{"     Touch Down"},   {  0, 20, 35,   0, 15,  0,  0,  0,  0,  0,   0,   0, 130,   0,   0,   0},},
              {{"       Gin Tonic"},  {  0,  0,  0,   0,  0, 45, 15,  0,  0,  0,   0,   0,   0,   0, 140,   0},},
              {{"   Planters Wonder"},{  0,  0,  0,   0, 20,  0,  0,  0,  0,  0,   0,  60,  60,  60,   0,   0},},
              {{""},                  {  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},},
              {{""},                  {  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},},
              {{""},                  {  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},},
              {{""},                  {  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,   0,   0,   0,   0,   0,   0},},
              {{"Ventile Sp\365len"}, { 10, 10, 10,  10, 10, 10, 10, 10, 10, 10,   0,   0,   0,   0,   0,   0},},
              {{"Pumpen Sp\365len"},  {  0,  0,  0,   0,  0,  0,  0,  0,  0,  0,  10,  10,  10,  10,  10,  10},},
            };


void writeAll()
{
   eep.put(0, daten); // ins EEProm schreiben
   Serial.println("Alle Daten geschrieben");
}

void setup()
{
  Serial.begin(9600);
  Wire.begin();

  Serial.print("EE Prom length: ");
  Serial.println(eep.length());

  if (eep.ready())
    Serial.println ("EE Prom ist bereit!");
  else Serial.println("EE Prom ist nicht bereit, Verkabelung prüfen ");

  // einmalig alle Daten ins EEPROM speichern (Per save Taster?)
  // writeAll();


//---------------------------

  // Alle Datensätze einzeln lesen
  Cocktail *cocktailPointer = 0; // Zeigt auf den Anfang des Arrays
  for(int i = 0; i<Anzahl_Rezepte; i++)
  {
    Cocktail cocktail;    // zwischenlager
    eep.get(uint16_t(cocktailPointer+i),cocktail); // Adresse berechnen + Datensatz lesen
    Serial.print(cocktail.name);  Serial.print("  :  ");
    for(int j = 0; j <Anzahl_Zutaten; j++)
    {
      Serial.print(cocktail.zutaten[j]);  Serial.print(" ");
    }
    Serial.println();
  }
 
// ------------------

}

void loop()
{
}



Ich hoffe, dass dir das so schmeckt...
Auf das using, kann man auch verzichten, wenn dir das lieber ist.
 
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

agmue

#44
Oct 22, 2018, 11:44 am Last Edit: Oct 22, 2018, 12:05 pm by agmue
Meine Änderungen/Korrekturen, an der Lib, habe ich in die ZIP im Eingangspostig einfließen lassen.
Der Link "I2C EEProm Library für Arduino, evtl. in einer neueren Fassung" in readme.html führt zur Fehlermeldung:
Quote
An Error Has Occurred
You are not allowed to access this section
Leider fehlt mit eine Idee, was ich mit return customvar; anfangen könnte. Die Beispiele der EEPROM-Bibliothek wie auch Dein Beispiel inspirieren mich leider nicht. Da ich es nicht verstehe, ist mir meine Variante momentan lieber. Ich lasse mich aber gerne überzeugen.


Jetzt, nach dem ich deine Daten gesehen habe....
Sehe ich auch, dass offsetof() nicht unbedingt hilft.
Gut.

Aber dennoch, kann man dem Compiler die Adressberechnung überlassen.
Stichwort "Pointer Arithmetik"
Ich bin faul, das kommt mir entgegen.


Quote
(Per save Taster?)
Die Daten sollen vom PC kommen ... andere Baustelle.

Die Daten habe ich etwas umstrukturiert...
... damit zusammenkommt, was zusammengehört. Das hatte ich so "befürchtet".

Ich werde mal abschätzen, wie hoch der Änderungsaufwand für das bestehende Programm wird und spiele jetzt mal mit den umstrukturierten Daten.

Danke bis hierhin :)
Die Vorstellungskraft ist wichtiger als Wissen, denn Wissen ist begrenzt. (Albert Einstein)

Go Up