EEPROM via I2C auslesen - HELP!

Hallo zusammen

Ich arbeite zur Zeit an meiner Diplomabschlussarbeit für eine Terrariensteuerung. Damit kann man die Temperaturen und Feuchtigkeit in einem Terrarium steuern.
Dazu gehört auch, dass ein Raspi ein paar Zahlen von einer Datenbank auf ein EEPROM via I2C schreibt. Ein Arduino liest dann das EEPROM an den genau vordefinierten Bytes aus und übernimmt dann den darin enthaltenen Wert als Integer oder Char in eine Variable.

So weit, so gut. Das funzt alles wenn man es wie hier im Setup - Loop einmal laufen lässt:

#include <Wire.h>
#define eeprom1 0x50    //Address of 24LC256 eeprom chip
#define WRITE_CNT 5

unsigned char rdata[32];

void setup(void)
{
  Serial.begin(9600);
  Wire.begin();  
 
  unsigned int i;

  // read back the data 28 bytes at a time
  // reading data doesn't suffer from the page boundary rules
  Serial.println("DATA READ");
  for(i=0x2a;i<=0x2e;i++) {
    readEEPROM(eeprom1, (i*1), rdata, 1);
    Serial.write(rdata,1);
  }  

}

void loop(){
}


void readEEPROM(int deviceaddress, unsigned int eeaddress,  
                 unsigned char* data, unsigned int num_chars) 
{
  unsigned char i=0;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
 
  Wire.requestFrom(deviceaddress,num_chars);
 
  while(Wire.available()) data[i++] = Wire.read();

}

Damit gibt er schön brav den Wert vom EEPROM ins Serial-Fenster.

Da ich aber mehrere Werte auslesen muss, und die in unterschiedliche Variablen abspeichern muss, um damit dann die Regulierung von z.B. der Heizung hin zu bekommen, muss ich dies über verschiedene Funktionen, welche ich selber definieren muss, machen.
Und genau da liegt irgendwo ein Hund, den ich mit dem mittlerweile 3m dicken Brett vorm Kopp echt nicht mehr sehe.
Ich hab jetzt das halbe Internet durchsucht, ein paar Sketch-Snipplets von bestehenden EEPROM-Projekten durchkonfiguriert, aber ich komm echt nicht auf nen grünen Zweig und blick echt voll mehr durch… :confused:

So sieht der Code aus:

#include <Wire.h>
#define eeprom1 0x50    //Address of 24LC256 eeprom chip
#define WRITE_CNT 5

unsigned char rdata[2];

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

}

void loop(){
//    unsigned int i;

  // read back the data 28 bytes at a time
  // reading data doesn't suffer from the page boundary rules
//  Serial.println("DATA READ");
//  for(i=0x2a;i<=0x2e;i++) {
//    readEEPROM(eeprom1, (i*1), rdata, 1);
Serial.println(' ');
    Serial.write(temp(0x2b, 0x2e, rdata));
    delay(600);
   
//  } delay(600);
}


void readEEPROM(int deviceaddress, unsigned int eeaddress,  
                 unsigned char* data, unsigned int num_chars) 
{
  unsigned char i=0;
  Wire.beginTransmission(deviceaddress);
  Wire.write((int)(eeaddress >> 8));   // MSB
  Wire.write((int)(eeaddress & 0xFF)); // LSB
  Wire.endTransmission();
 
  Wire.requestFrom(deviceaddress,num_chars);
 
  while(Wire.available()) data[i++] = Wire.read();

}

int temp(unsigned int b_a, unsigned int e_a, unsigned char* data)
{
//  unsigned char data[2];
  unsigned int i = b_a;
//    Serial.println("DATA READ");
  while(i < e_a)
  {i = i +1;
  }
    readEEPROM(eeprom1, (i*1), data, 1);
    data[i++];
    return i;
  }

Mittlerweile ists schon so schlimm, dass ich nicht mal mehr ne Zählschlaufe zum rennen kriege. Das wär nämlich einer der Hunde die begraben sind…

void setup(void)
{
  Serial.begin(9600);
}
void loop()
{
  Serial.write(count(1,9));
  delay(1000);
}
int count(int a, int e)
{ int i;
  for (i=a; i<e;i++)
  {return i;
  delay(50);
  }
}

Ich weiss echt nicht was ich da falsch mache. Muss noch sagen, dass ich auf Arduino ziemlich der Noobe bin :wink: .
Ich wär Euch echt Dankbar, wenn Ihr mir ein Lösungsansatz oder ein (gewaltigen) Kick in die richtige Richtung geben könnt!

Beste Grüsse
Pat

Hallo Pat,

da scheint ja noch einiges im Argen zu liegen und ich glaube, dass du erstmal ein paar Basics lernen solltest, bevor du Code irgendwo kopierst, den du dann nicht verstehst.
Doch fangen wir mal konstruktiv mit deiner Zählschleife an:
was willst du erreichen? Es sieht so aus, als wenn du die gezählten Werte aus einer Funktion ausgeben willst.

  1. Fehler: die Schleife in der Funktion bricht mit return immer im ersten Durchlauf ab, der Rückgabewert ist also immer "1". Eins Schleife mit dem Sinn verschiedene Werte aus einer Funktion zurückzugeben ist also keine gute Idee.
  2. Fehler: Serial.write(1) schreibt eine 1 (binär) auf die serielle Schnittstelle, der ASCii Wert von 1 ist aber kein darstellbarer Buchstabe. Wenn du Serial.print(count(1,9)) schreibst, wirst du sehen, dass er immer die Zahl 1 ausgeben wird.

Besser wäre es die Schleife direkt ausserhalb der Funktion zu bauen.

Andere Frage: wie soll der Zugriff vom Raspberry (vermutlich als Master) auf das i2c Eprom funktionieren, wenn gleichzeitig der Arduino als Master darauf zugreifen soll? Es kann nur einen Master am 12c Bus geben.

Soviel fürs erste
Reinhard

Hallo Reinhard

Besten Dank für Dein Reply!

Jep I know. Da liegt noch einiges im Argen... Darum wende ich mich ja auch an Euch Pros :wink: .

Die Basics hab ich im Ansatz schon via YT und verschiedenen Foren und Büchern gelernt. Hab auch schon einiges mit dem Arduino rumgespielt. Aber eben, nur im Ansatz.
Die Regulierung z.B. funzt ohne Probleme. Auch die Zeitsteuerung usw... Das tut wies tun soll.

Aber eben, da geb ich Dir recht. Ich hab Code zusammenkopiert und dann mit meinem halt noch beschränkten Wissen zusammengefügt. Was dann halt jetzt hängt...

Wegen der Zählschleife. Ich glaub genau da ist der Hund begraben.
Was meinst Du bei der 1. Frage? Ich mach doch kein break, damit die Zählschleife abbricht. Kannst Du mir da ein Beispiel geben, damit der Wert auch zurückgegeben wird? Würde dann auch zur Lösung meines eigentlichen Problemes beitragen.

Zur zweiten Frage: Ich bin doch der Meinung dass mit dem Befehl Serial.write(count(1,9)) Die Funktion "count" aufgerufen wird und dann die Werte a = 1 und e = 9 and die Funktion übergeben wird? Oder liege ich da auch falsch?

Wie soll ich denn die Schleife ausserhalb der Funktion machen, wenn ich mehrere Funktionen machen muss um einzelne Werte aus dem EEPROM zu lesen welche dann in die entsprechenden Variablen gespeichert werden müssen?
Wär da auch um ein Beispiel voll Dankbar!

Zum Zugriff auf den I2C - Bus: Der Code ist im Moment Stand-Alone mit dem EEPROM zusammen. Der Arduino ist in diesem Code natürlich Master. Sobald das Auslesen der Werte funzt, wird der zum Slave gemacht und der Raspi ist Masta auf dem Bus. Der Arduino erhält dann nur noch den Command via I2C den Write-Enable Port vom EEPROM zu enablen.

Wie gesagt, ich hab im Moment ein riiiesen Brett vor dem Kopf um das Problem zu lösen. Vielleicht auch wegem Abschlussprüfungsstress... Deshalb bin ich wirklich auf Eure konstruktive Hilfe angewiesen. :wink: .

Falls ihr noch mehr Infos braucht, bitte nachfragen! Ich liefere die gerne nach!

Besten Dank schon mal und freundliche Grüsse
Pat

Hallo,

Du rufst die count Funktion schon richtig auf. Abgesehen davon man hier Serial.print statt Serial.write verwendet.
Dein Problem ist der Code in der count Funktion. Ein Break haste nicht, aber ein return haste drin. Macht das gleiche bzw. hat bei den gleichen Effekt.

Geh mal jede Zeile der count Funktion durch. Sie wird aufgerufen, alles wird lokal definiert und übergeben, dann wird sofort mit return i rausgesprungen. Ende. Das Spiel beginnt von vorn. Immer mit den gleichen Werten.
Die Abbruchbedingung der for Schleife ist i < e und kommst dem immer zuvor mit dem return.

Vorschlag

void setup(void)
{
Serial.begin(9600);
}
void loop()
{
count(1,9);
delay(1000);
}
int count(int a, int e)
{
int i = 0;
for (i=a; i<e; i++) {
Serial.println(i);
delay(50);
}
}

und verwende in Deiner Diplomarbeit nicht das Wort “funzt”.
Ich frage mich gerade. Wer hat den Raspberry programmiert?

Hallo Doc

Besten Dank für den Vorschlag.
Ich probier das heute Abend mal aus.

Das Raspi hab ich mit nem Kumpel zusammen programmiert. Aber eher Web-Oberfläche.
Für die wenigen Scripts die ich da drauf brauche fürs EEPROM zu schreiben hab ich ein Package geladen.

Grüsse
Pat