Forum: Mikrocontroller und Digitale Elektronik Schreiben oder Lesen eines I2C-EEPROMS funktioniert nicht


von Alexander S. (knut740)


Lesenswert?

Hallo,
ich versuche, mit einem Arduinoprogramm einige Zahlen in ein I2C-EEPROM 
zu schreiben und sie später wieder auszulesen. Dies funktioniert ganz 
gut, bis auf den ersten der sechs Werte, der einfach entweder nicht 
geschrieben oder nicht gelesen wird.
Im ersten Code-Schnipsel sieht man, wie die Daten (die Zeit und zwei 
Temperaturwerte) in das EEPROM geschrieben werden sollen:
1
// Zeit ins EEPROM schreiben
2
    int  Time = millis() /1000;                                // Sekunden seit Start  
3
    Time = 1234;                                              // hilfsweise
4
  
5
   schreibEEPROM(eepromadresse,highByte(Time));               // highByte(Time)  
6
   eepromadresse++;
7
   schreibEEPROM(eepromadresse,lowByte(Time));                // lowByte(Time)
8
   eepromadresse++;
9
...snip...
10
wird zweimal durchlaufen:
11
   schreibEEPROM(eepromadresse,highByte(Temp));               // highByte(Time)  
12
   eepromadresse++;
13
   schreibEEPROM(eepromadresse,lowByte(Temp));                // lowByte(Time)
14
   eepromadresse++;

Für das Auslesen ist ein anderes Programm (oder Sketch, wie das wohl bei 
Arduino heißt,) vorhanden:
1
 for (eepromadresse = 0;  eepromadresse < 5000; eepromadresse++){
2
                                              
3
  byte1 = (liesEEPROM(eepromadresse));        // highByte von Time
4
  eepromadresse++;
5
  byte2 = (liesEEPROM(eepromadresse));        // lowByte von Time
6
  eepromadresse++;
7
  byte3 = (liesEEPROM(eepromadresse));        // HighByte von Temp1
8
  eepromadresse++;
9
  byte4 = (liesEEPROM(eepromadresse));        // LowByte von Temp1
10
  eepromadresse++;
11
  byte5 = (liesEEPROM(eepromadresse));        // HighByte von Temp2
12
  eepromadresse++;
13
  byte6 = (liesEEPROM(eepromadresse));        // LowByte von Temp2  
14
15
  Serial.print(eepromadresse);
16
  
17
  Serial.print("\t");
18
  Serial.print(byte1);
19
  Serial.print("\t");
20
  Serial.print(byte2);
21
  Serial.print("\t");
22
  Serial.print(byte1 << 8 | byte2);
23
  Serial.print("\t");
24
  
25
  Serial.print(byte3);
26
  Serial.print("\t");
27
  Serial.print(byte4);
28
  Serial.print("\t");
29
  Serial.print(byte3 << 8 | byte4); 
30
  Serial.print("\t");
31
32
  Serial.print(byte5);
33
  Serial.print("\t");
34
  Serial.print(byte6);
35
  Serial.print("\t");
36
  Serial.println(byte5 << 8 | byte6);
37
  }  // Ende for

Das mir unverständliche Ergebnis ist im folgenden Abschnitt zu sehen:
1
Adresse        Zeit             Temp.  
2
 5  0  210  210  1      144  400  22  255  5887
3
11  0  210  210  1      162  418  22  193  5825
4
17  0  206  206  1  56  312  22  199  5831
5
23  0  174  174  1  69  325  22  186  5818
6
29  0  56  56  1  81  337  22  186  5818
7
35  0  217  217  1  87  343  22  186  5818
8
41  0  53  53  1  100  356  22  243  5875
9
47  0  221  221  1  131  387  22  243  5875
10
53  0  130  130  1  131  387  22  249  5881

In der zweiten Spalte sollte immer eine 4 stehen (aus dem Dummy  1234 
für die Variable Time), aber ich schaffe es einfach nicht, in die erste 
der EEPROM-Zellen das HighByte des ersten Wertes hineinzubekommen. 
Manchmal gelingt mir es zwar, aber der Code sieht dann genau so aus, 
sodaß ich nicht erkennen kann, woran es liegt.
Es wäre nett, wenn  einer der Experten mal eine Blick auf den Code 
werfen könnte und mir des Rätsels Lösung nennen würde. Da ich nicht 
weiß, ob es beim Schreiben oder Lesen daneben geht, habe ich beide 
Programmteile beigefügt - und ordentlich gekürzt, damit es nicht zu lang 
zum Lesen wird.
Da ich schier am Verzweifeln bin, würde ich mich über einen Hinweis sehr 
freuen.
VG
Alexander

: Bearbeitet durch User
von asdfasd (Gast)


Lesenswert?

Der "ordentlich gekürzte" Code sieht OK aus. Der Fehler scheint im 
weggekürzten Rest zu liegen.

von M. K. (sylaina)


Lesenswert?

Die Zeilen sehen alle OK aus, wie schon gesagt wurde, der weggelassene 
Code wäre interessant. Erste/spontane Vermutung: Du hast irgendwo bei 
dir statt ein >= oder <= ein > bzw. <. Ist aber nur geraten.

Einige Anmerkungen aber auch mal grundsätzlich:

Man kann ein EEPROM natürlich Byte für Byte beschreiben, sehr sinnvoll 
ist das aber nicht. Eigentlich haben EEPROMs Funktionen mit denen sich 
auch gleich eine ganze Batterie an Bytes drauf schreiben lassen. Das 
Maximum an Bytes, dass man "gleichzeitig" schreiben lassen kann nennt 
man einen Pagewrite.

Einige EEPROMs haben auch einen Adress-Auto-Increment, d.h. man muss nur 
einmal die Adresse setzen bei der man starten will und kann dann ein 
Byte nach dem anderen schicken, die Adresse wird automatisch 
incrementiert.

Hier mal ein Beispiel wie eine Bibliothek zu sowas aussehen kann (hier 
für ein 24LC1025 EEPROM von Mikrochip, da ich die "kleineren" nicht habe 
weiß ich nicht wie gut die damit laufen, sollten aber auch problemlos 
damit funktionieren)
1
#ifndef _4lc1025_h
2
#define _4lc1025_h
3
// define Adress: Controlsequence(bit 7:4, hardcoded at 1010) Blockselect(bit 3) A1(bit 2) A0(bit 1) R/W(bit 0)
4
#define i2c_Adress_24LC1025  0b10100000
5
6
#include "24lc1025.h"
7
#include "i2c.h"
8
#include <util/delay.h>
9
10
uint8_t readByte24LC1025(uint32_t adress){
11
    uint8_t data = 0;
12
    if(adress > 0xffff){ // read from second block
13
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
14
        i2c_byte((uint8_t)(adress >> 8));
15
        i2c_byte((uint8_t)(adress & 0xff));
16
        i2c_start(i2c_Adress_24LC1025 | (1 << 3) | 1);
17
    }else{ // read from first block
18
        i2c_start(i2c_Adress_24LC1025);
19
        i2c_byte((uint8_t)(adress >> 8));
20
        i2c_byte((uint8_t)(adress & 0xff));
21
        i2c_start(i2c_Adress_24LC1025 | 1);
22
    }
23
    data = i2c_readNAck();
24
    i2c_stop();
25
    return data;
26
}
27
void writeByte24LC1025(uint32_t adress, uint8_t data){
28
    if(adress > 0xffff){ // write to second block
29
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
30
    }else{ // write to first block
31
        i2c_start(i2c_Adress_24LC1025);
32
    }
33
    i2c_byte((uint8_t)(adress >> 8));
34
    i2c_byte((uint8_t)(adress & 0xff));
35
    i2c_byte(data);
36
    i2c_stop();
37
    _delay_ms(5);
38
}
39
40
uint16_t readWord24LC1025(uint32_t adress){
41
    uint16_t data = 0;
42
    if(adress > 0xffff){ // read from second block
43
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
44
        i2c_byte((uint8_t)(adress >> 8));
45
        i2c_byte((uint8_t)(adress & 0xff));
46
        i2c_start(i2c_Adress_24LC1025 | (1 << 3) | 1);
47
        data = i2c_readAck() << 8;
48
    }else if(adress < 0xffff){ // read from first block
49
        i2c_start(i2c_Adress_24LC1025);
50
        i2c_byte((uint8_t)(adress >> 8));
51
        i2c_byte((uint8_t)(adress & 0xff));
52
        i2c_start(i2c_Adress_24LC1025 | 1);
53
        data = i2c_readAck() << 8;
54
    }else{
55
        i2c_start(i2c_Adress_24LC1025);
56
        i2c_byte(0xff);
57
        i2c_byte(0xff);
58
        i2c_start(i2c_Adress_24LC1025 | 1);
59
        data = i2c_readNAck() << 8;
60
        i2c_stop();
61
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
62
        i2c_byte(0x00);
63
        i2c_byte(0x00);
64
        i2c_start(i2c_Adress_24LC1025 | (1 << 3) | 1);
65
    }
66
    data |= i2c_readNAck();
67
    i2c_stop();
68
    return data;
69
}
70
void writeWord24LC1025(uint32_t adress, uint16_t data){
71
    if(adress > 0xffff){ // write to second block
72
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
73
        i2c_byte((uint8_t)(adress >> 8));
74
        i2c_byte((uint8_t)(adress & 0xff));
75
        i2c_byte((uint8_t)(data >> 8));
76
    }else if(adress < 0xffff){ // write to first block
77
        i2c_start(i2c_Adress_24LC1025);
78
        i2c_byte((uint8_t)(adress >> 8));
79
        i2c_byte((uint8_t)(adress & 0xff));
80
        i2c_byte((uint8_t)(data >> 8));
81
    }else{ // adress height at first block, adress low byte at second block
82
        i2c_start(i2c_Adress_24LC1025); // write height byte
83
        i2c_byte((uint8_t)0xff);
84
        i2c_byte((uint8_t)0xff);
85
        i2c_byte((uint8_t)(data >> 8));
86
        i2c_stop();
87
        i2c_start(i2c_Adress_24LC1025 | (1 << 3)); // write low byte
88
        i2c_byte((uint8_t)0x00);
89
        i2c_byte((uint8_t)0x00);
90
    }
91
    i2c_byte((uint8_t)(data & 0xff));
92
    i2c_stop();
93
    _delay_ms(5);
94
}
95
void writePage24LC1025(uint32_t adress, uint8_t len, uint8_t data[]){
96
    uint8_t i;
97
    if(adress > 0xffff){ // start adress at second block
98
        i2c_start(i2c_Adress_24LC1025 | (1 << 3));
99
        i2c_byte((uint8_t)(adress >> 8));
100
        i2c_byte((uint8_t)(adress & 0xff));
101
        for (i=0; i <= len; i++) {
102
            if(adress < 0x1ffff && i < 0x08){
103
                i2c_byte(*data++);
104
                adress++;
105
            }
106
        }
107
    }else if(adress+len <= 0xffff){ // start adress at first block, end adress at first block
108
        i2c_start(i2c_Adress_24LC1025);
109
        i2c_byte((uint8_t)(adress >> 8));
110
        i2c_byte((uint8_t)(adress & 0xff));
111
        for (i=0; i <= len; i++) {
112
            i2c_byte(*data++);
113
            adress++;
114
        }
115
    }else{ // start adress at first block, end adress at second block
116
        i2c_start(i2c_Adress_24LC1025); // write to first block
117
        i2c_byte((uint8_t)(adress >> 8));
118
        i2c_byte((uint8_t)(adress & 0xff));
119
        while(adress <= 0xffff){
120
            i2c_byte(*data++);
121
            adress++;
122
            len--;
123
        }
124
        i2c_stop();
125
        i2c_start(i2c_Adress_24LC1025 | (1 << 3)); // write to last block
126
        i2c_byte((uint8_t)(adress >> 8));
127
        i2c_byte((uint8_t)(adress & 0xff));
128
        while (len > 0) {
129
            i2c_byte(*data++);
130
            adress++;
131
            len--;
132
        }
133
    }
134
    
135
    i2c_stop();
136
    _delay_ms(5);
137
}

: Bearbeitet durch User
von Alexander S. (knut740)


Lesenswert?

ok, hier schicke ich die beiden kompletten (aber noch unfertigen) 
Programme. Ich habe allen Kram drin gelassen, nichts gekürzt.
Nr 1, für das Schreiben:
1
// _2DS18_ins_I2C-EEPR_vorl_171226-test-2               26.12.17
2
// _2DS18_ins_I2C-EEPR_vorl_170522                      22.05.17
3
4
// neuer Versuch wg der Timerausgabe (erste Stelle)
5
// funktioniert, wenn Relaisabfrage ausgeschaltet ist
6
7
// Zwischenversion mit unförmiger Abfrage
8
// gehört zu _I2C_EEPR_9_vorl_170522
9
10
//   +++ Heizungskontrolle
11
12
// Zunächst wird die Zeit seit Programmstart ins EEPROM geschrieben, 
13
// danach werden zwei DS18B20 ausgelesen, die Ergebnisse auf LCD dargestellt und ins EEPROM geschrieben.
14
// Alle diese Werte werden in jeweils in zwei Bytes zerlegt und in hintereinander folgende EEPROM-Zellen geschrieben. 
15
16
// Problem: der erste der sechs EEPROM-Einträge ist immer Null (statt Highbyte von Time!)
17
18
19
// Der Zustand des heizungsparallelen Relay wird 12-mal mit 1 sec Zwischenzeiten abgefragt. 
20
// Daraus wird auf das Ende des Brennerlaufs geschlossen und in diesem Fall nach 3 min 
21
// die Werte für Außen- und Vorlauftemperatur ins I2C-EEPROM geschrieben.
22
23
// Hardware: Board 151113 mit Iteaduino 2.2 mit zwei Anschlüssen für die
24
// DS18B20 und zwei nicht mehr benutzten für SMT 160-30
25
26
27
/* YourDuino Multiple DS18B20 Temperature Sensors on 1 wire
28
  Connections:
29
  DS18B20 Pinout (Left to Right, pins down, flat side toward you)
30
  - Left   = Ground
31
  - Center = Signal (Pin 2):  (with 3.3K to 4.7K resistor to +5 or 3.3 )
32
  - Right  = +5 or +3.3 V
33
34
   Questions: terry@yourduino.com 
35
   V1.01  01/17/2013 ...based on examples from Rik Kretzinger
36
37
38
   
39
/*-----( Import needed libraries )-----*/
40
// Get 1-wire Library here: http://www.pjrc.com/teensy/td_libs_OneWire.html
41
#include <OneWire.h>
42
43
//Get DallasTemperature Library here:  http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library
44
#include <DallasTemperature.h>
45
46
/*-----( Declare Constants and Pin Numbers )-----*/
47
#define ONE_WIRE_BUS_PIN 2
48
49
/*-----( Declare objects )-----*/
50
// Setup a oneWire instance to communicate with any OneWire devices
51
OneWire oneWire(ONE_WIRE_BUS_PIN);
52
53
// Pass our oneWire reference to Dallas Temperature.
54
DallasTemperature sensors(&oneWire);
55
56
/*-----( Declare Variables )-----*/
57
// Assign the addresses of your 1-Wire temp sensors.
58
// See the tutorial on how to obtain these addresses:
59
// http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html 0x28, 0x22, 0xEC, 0xEA, 0x07, 0x00, 0x00, 0x15
60
61
DeviceAddress Probe01 = { 0x28, 0x22, 0xEC, 0xEA, 0x07, 0x00, 0x00, 0x15};    // 
62
DeviceAddress Probe02 = { 0x28, 0xD1, 0xD3, 0xEA, 0x07, 0x00, 0x00, 0xD5 };   // kurzes Kabel 7t98r5
63
64
65
#include <Wire.h> 
66
#include <LiquidCrystal_I2C.h>
67
LiquidCrystal_I2C lcd(0x20,16,2);      // Achtung: auf den neuen I2C-LCD gibt es Adressjumper.
68
const int I2CADRESSE = 0x51;           // A0 = high, 
69
int eepromadresse = 0;
70
int adresse = 0;
71
 int a = 10;                           // zum Testen der lcd-Ausgabe
72
int relaispin = 9;                                      
73
unsigned long time;
74
75
void setup()   /****** SETUP: RUNS ONCE ******/
76
{
77
    Serial.begin(9600);                // für Ausgabe über Terminal
78
    pinMode (relaispin, INPUT);
79
    delay(4000); 
80
    lcd.init();
81
    lcd.backlight();
82
    lcd.clear();
83
    lcd.print(" _2_DS18_ins_EEPROM");
84
    lcd.setCursor(0,1);
85
    lcd.print("relaisgest_m_Zeit");
86
    delay(4000);
87
    lcd.clear(); 
88
  
89
  
90
  // start serial port to show results
91
  Serial.begin(9600);
92
  Serial.print("Initialisierung Temperature Control Library Version ");
93
  Serial.println(DALLASTEMPLIBVERSION);
94
  delay(2000);
95
  
96
  // Initialize the Temperature measurement library
97
  sensors.begin();
98
  
99
  // set the resolution to 12 bit (Can be 9 to 12 bits .. lower is faster)
100
  sensors.setResolution(Probe01, 12);
101
  sensors.setResolution(Probe02, 12);
102
103
} //--(end setup )---
104
105
void loop()   /****** LOOP: RUNS CONSTANTLY ******/
106
{
107
108
// Abfrage des Brennerrelais, genauer, des Relais, das dem eigentlichen Brennerrelais 
109
// nachgeschaltet ist.
110
     int i;
111
     int summe1= 0;
112
     int ersterRelaiszustand[6];
113
     for (i=0; i<7; i++){
114
     ersterRelaiszustand[i] = digitalRead(relaispin);
115
      summe1 = summe1 + ersterRelaiszustand[i];
116
      delay(100);
117
     }
118
     int summe2= 0;    
119
     int zweiterRelaiszustand[6];
120
     for (i=0; i<7; i++){
121
      zweiterRelaiszustand[i] = digitalRead(relaispin);
122
      summe2 = summe2 + zweiterRelaiszustand[i];
123
      delay(100);
124
     } 
125
126
     if(summe2 > summe1)           // muß ausprobiert werden, da nicht bekannt ist,  w i e  das Relais geschaltet ist,
127
                                   // am Ende der Brennerlaufzeit abgefallen oder angezogen???
128
                                   // while(!....  gibt pausenlose Ausgabe und die erste Zelle ist ok, nicht leer
129
                                   // if(......    liefert Ausgabe wie gewünscht, aber zweite Spalte ist leer.
130
     { 
131
      
132
  
133
   delay(12000);                // z.  Zt. 0,2 min Wartezeit, bis Außen- und Vorlauftemperatur gemessen wird
134
135
// Zeit ins EEPROM schreiben
136
    int  Time = millis() /1000;                                // Sekunden seit Start  
137
    Time = 1234;                                              // hilfsweise
138
  
139
   schreibEEPROM(eepromadresse,highByte(Time));               // highByte(Time)  
140
   eepromadresse++;
141
   schreibEEPROM(eepromadresse,lowByte(Time));                // lowByte(Time)
142
   eepromadresse++;
143
   
144
145
// Command all devices on bus to read temperature  
146
147
  sensors.requestTemperatures();  
148
  delay(100);
149
  lcd.clear();
150
  delay(100);
151
  lcd.setCursor(0,0);
152
  lcd.print("aus ");
153
  Serial.print("am langen Kabel (aussen):   ");             //langes Kabel
154
  printTemperature(Probe01);
155
  Serial.print("     ");
156
  Serial.println(Time);
157
  lcd.setCursor(10,0);
158
  lcd.print(millis()/1000);                                    // Sekunden
159
160
//  lcd.clear();
161
//  lcd.print("lang    ");
162
163
  
164
  sensors.requestTemperatures();
165
  lcd.setCursor(0,1);
166
  lcd.print("Vor ");    
167
  Serial.print("am kurzen Kabel (Vorlauf):   ");
168
  printTemperature(Probe02);
169
  lcd.setCursor(10,1);
170
  lcd.print(eepromadresse);
171
  Serial.println();
172
  
173
  }          // Ende Relaispinabfrage 
174
175
}//--(end main loop )---
176
177
//  Unterfunktionen
178
179
void schreibEEPROM(int adresse, byte daten) 
180
  {  
181
  Wire.beginTransmission(I2CADRESSE);
182
  Wire.write ((byte) (adresse >> 8));
183
  Wire.write ( (byte) (adresse & 0xFF));
184
  Wire.write (daten);
185
  Wire.endTransmission();  
186
  delay(5);
187
  }
188
189
190
void printTemperature(DeviceAddress deviceAddress)       // h i e r  wird die Temp. vom Sensor gelesen
191
{
192
   float tempC = sensors.getTempC(deviceAddress)*100;
193
   if (tempC == -12700){                                  // Format von tempC = 12700
194
   Serial.print("Lesefehler am Temp.-Sensor  ");
195
   } 
196
   else
197
   {
198
//   Serial.print("C: ");
199
   Serial.print(tempC/100);                               // hier wird die Temp. geschrieben
200
   lcd.print(tempC/100);
201
   int TempC = int(tempC);                                // damit es in low- und highbyte zerlegt werden kann (wg. des EEPROMs)
202
203
  
204
   schreibEEPROM(eepromadresse,highByte(TempC));               // highByte(Time)  
205
   eepromadresse++;
206
   schreibEEPROM(eepromadresse,lowByte(TempC));                // lowByte(Time)
207
   eepromadresse++;
208
   }            // End printTemperature
209
//*********( THE END )***********
210
}

Und hier Nr. 2, für das Auslesen:
1
// _I2C_EEPR_alles_Zeit+2_Werte_171028                              28.10.17
2
// _J2C_EEPR_1_Wert_ u_Bytes                                       26.3.17
3
4
//_2_Werte_write_read_I2C_EEPROM                                   5.2.17
5
//
6
//  ++ für Heizungskontrolle
7
8
9
10
#include<Wire.h>
11
//#include<EEPROM.h>            // nur für internes EEPROM benötigt
12
const int I2CADRESSE = 0x51;
13
int eepromadresse;
14
int Time, Wert1, Wert2;
15
byte byte1, byte2, byte3, byte4, byte5, byte6, byte7, byte8;
16
17
void setup() {
18
int Wert = 0;
19
   Wire.begin();
20
   Serial.begin(9600);
21
int eepromadresse = 0;
22
  Serial.println();
23
  Serial.println(" Ergebnisse (dauert ziemlich lange)");
24
  Serial.println("  ");
25
Serial.println("Adresse        Zeit             Temp.  ");
26
27
 for (eepromadresse = 0;  eepromadresse < 5000; eepromadresse++){
28
                                              
29
  byte1 = (liesEEPROM(eepromadresse));        // highByte von Time
30
  eepromadresse++;
31
  byte2 = (liesEEPROM(eepromadresse));        // lowByte von Time
32
  eepromadresse++;
33
  byte3 = (liesEEPROM(eepromadresse));        // HighByte von Temp1
34
  eepromadresse++;
35
  byte4 = (liesEEPROM(eepromadresse));        // LowByte von Temp1
36
  eepromadresse++;
37
  byte5 = (liesEEPROM(eepromadresse));        // HighByte von Temp2
38
  eepromadresse++;
39
  byte6 = (liesEEPROM(eepromadresse));        // LowByte von Temp2  
40
//  eepromadresse++;
41
//  byte7 = (liesEEPROM(eepromadresse));  
42
//  eepromadresse++;
43
//  byte8 = (liesEEPROM(eepromadresse));
44
45
  Serial.print(eepromadresse);
46
  Serial.print("\t");
47
  Serial.print(byte1);
48
  Serial.print("\t");
49
  Serial.print(byte2);
50
  Serial.print("\t");
51
  Serial.print(byte1 << 8 | byte2);
52
  Serial.print("\t");
53
  
54
  Serial.print(byte3);
55
  Serial.print("\t");
56
  Serial.print(byte4);
57
  Serial.print("\t");
58
  Serial.print(byte3 << 8 | byte4); 
59
  Serial.print("\t");
60
61
  Serial.print(byte5);
62
  Serial.print("\t");
63
  Serial.print(byte6);
64
  Serial.print("\t");
65
  Serial.print(byte5 << 8 | byte6);
66
  Serial.print("\t");
67
  Serial.print("Byte1...");
68
  Serial.print("\t");
69
  Serial.println(byte1);
70
71
  
72
  }  // Ende for
73
}  
74
 
75
76
void loop()
77
 {};
78
79
//  Unterprogramme
80
81
  byte liesEEPROM( unsigned int eepromaddress)   // byte datenbyte=0xFF)
82
{
83
  byte  datenbyte = 0x00;
84
  Wire.beginTransmission(I2CADRESSE);
85
  Wire.write ((byte) (eepromaddress >> 8));
86
  Wire.write ( (byte) (eepromaddress & 0xFF));
87
  Wire.endTransmission();
88
  Wire.requestFrom(I2CADRESSE, 1);         //  1 ... heißt ein Byte ???
89
  if (Wire.available())                    //  wahrsch. ack ?
90
    datenbyte = Wire.read();
91
  return datenbyte;
92
}
93
94
/*
95
void   schreibEEPROM(int adresse, byte daten) 
96
  {  
97
  Wire.beginTransmission(I2CADRESSE);
98
  Wire.write ((byte) (adresse >> 8));
99
  Wire.write ( (byte) (adresse & 0xFF));
100
  Wire.write (daten);
101
  Wire.endTransmission();  
102
  delay(5);
103
  }
104
  */

VG
Alexander

: Bearbeitet durch User
von Alexander S. (knut740)


Lesenswert?

Edit:
Das Dilemma scheint mit der im Programm als Brennerabfrage bezeichneten 
Passage bzw. der if- oder while- Schleife zusammenzuhängen. Deaktiviert 
man sie, wird es besser. Allerdings kann ich nicht nachvollziehen, 
weshalb.

VG
Alexander

von M. K. (sylaina)


Lesenswert?

Sieht mir erstmal zu komplex aus um mich da reinzufuchsen und ich 
schätze mal, anderen geht es ähnlich.
Ich empfehle dir: Reduziere den Code so weit dass er nicht mit Elementen 
beladen ist, die mit dem Problem nichts zu tun haben, d.h. baue ein 
Beispiel-Programm, dass den Fehler zeigt. Das ist natürlich etwas 
aufwand, es kann aber durchaus dabei passieren, dass du dabei den Fehler 
selber findest.

Was mir auffällt: Bei "schreibeEEPROM()" hast du die Speicheradresse als 
int deklariert obwohl es ein uint16_t ist. Das ist auch wenig schön. 
Hier solltest du mehr eine rote Linie in deinen Code rein bekommen, 
sprich ordentlicher arbeiten. Es ist sicher von Vorteil wenn der 
Programmierstyle gleich ist, so sieht man insbesondere bei ähnlichen 
Funktionen direkt die Unterschiede. Das wird bei dir schon schwer, da du 
einmal den Parameter für die Speicheradresse eepromadress nennst und 
einmal adresse.

: Bearbeitet durch User
von Alexander S. (knut740)


Lesenswert?

M. K. schrieb:

Mache ich, also alles raus, was nichts mit dem Problem zu tun hat.

> Was mir auffällt: Bei "schreibeEEPROM()" hast du die Speicheradresse als
> int deklariert obwohl es ein uint16_t ist.
Bereitet mir etwas Schwierigkeiten, da ja in Arduino für Duo das int aus 
zwei Bytes besteht. Ich bin mir auch nicht sicher, ob die Zerlegung von 
int in HighByte und Lowbyte so zulässig ist, wie ich es gemacht habe 
(funktioniert aber).
Mit den Adressen habe ich auch long bzw. unsigned int probiert, hat aber 
nichts geändert.

VG
Alexander

von Jan L. (ranzcopter)


Lesenswert?

...mach‘ in deiner Leseroutine zum „if Wire.available()“ doch mal einen 
else-Zweig dazu, „Serial.println(„hallo“)“ reicht ja...

Hier wird beim Lesen auf‘s available() verzichtet, dafür aber gewartet:
https://breadboardtronics.wordpress.com/2013/08/27/at24c32-eeprom-and-arduino/

von M. K. (sylaina)


Lesenswert?

Alexander S. schrieb:
> Bereitet mir etwas Schwierigkeiten, da ja in Arduino für Duo das int aus
> zwei Bytes besteht. Ich bin mir auch nicht sicher, ob die Zerlegung von
> int in HighByte und Lowbyte so zulässig ist, wie ich es gemacht habe
> (funktioniert aber).

Würde auch sagen, dass das so zulässig ist, ist halt nur wegen der 
Lesbarkeit etwas schwierig.

Hier mal ein Beispiel wie ich die Funktionen zum Lesen und Schreiben 
aufgebaut hätte (ich kenne allerdings die Wire-Library nicht, daher sind 
die Funktionen nur "geschätzt" von mir eingesetzt)
EEPROM lesen
1
uint8_t readByteFromEEPROM(uint16_t adressToRead){
2
  uint8_t data = 0xff;
3
  Wire.beginTransmission(I2CADRESSE); // Ich schätze mal, das sendet die Startcondition
4
  Wire.write((uint8_t)adressToRead >> 8);
5
  Wire.write((uint8_t)adressToRead & 0xff);
6
  Wire.beginTransmission(I2CADRESSE|1); // vergleiche Datenblatt EEPROM, wahrscheinlich muss das LSB der I2C-Adresse 1 sein um das EEPROM zum Senden zu bewegen, das wäre zumindest nicht unüblich.
7
  data = Wire.read(); // Vermute read liest das Byte vom i2c-Bus, wie gibt man ACK oder NACK vor? Wahrscheinlich kann man da noch einen Parameter mit übergeben, oder?
8
  Wire.endTransmission(); // Hier, vermute ich, wird die Stopcondition gesendet
9
  return data;
Und EEPROM schreiben
1
void writeByteToEEPROM(uint16_t adressToWrite, uint8_t valueToWrite){
2
  Wire.beginTransmission(I2CADRESSE);
3
  Wire.write((uint8_t)adressToWrite >> 8);
4
  Wire.write((uint8_t)adressToWrite & 0xff);
5
  Wire.write(valueToWrite);
6
  Wire.endTransmission();

Welches EEPROM benutzt du denn?

von Peter D. (peda)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.