Wert einer Variable ändert sich während des Programmablaufs

Bin im Moment dabei ein wenig mit einem externen EEPROM Baustein zu experimentieren. Bisher funktioniert das auch ganz gut soweit... - bis auf eine Sache:
Eine variable ändert sich, ohne mein zutun, während das Programm läuft.
Es geht um "pages".
Hier erstmal der komplette Code:

#include "SPI.h"
#define ss 10
#define wEn 0x6
#define wDis 0x4
#define writeEEP 0x2
#define readEEP 0x3
#define startPage 0x10


int size;  //Anzahl der Buchstaben vorher
byte a = 149;
byte b = 53;
byte c;
byte d;
char myStr[] = "Zeichen 15 Stck";   //max 15 Buchstaben
byte strSize;  //Anzahl der Buchstaben, gelesen aus Speicher
int pages;   // Anzahl der benötigeten Pages
char ausgabe[14] ;





void writeDisable(){
	digitalWrite(ss, LOW);
	delay(10);
	SPI.transfer(wDis);       //Schreiben ausschalten
	digitalWrite(ss, HIGH);
}

void writeEnable(){
	digitalWrite(ss, LOW);   //Schreiben einschalten
	SPI.transfer(wEn);
	digitalWrite(ss, HIGH);
}

int checkLenght(int strSize){  //Funktion funktioniert
	int ergebnis;
 ergebnis = strSize / 17;
	return ergebnis ;
	}

void setup()
{


	Serial.begin(9600);
	delay(50);

   size  = sizeof(myStr) / sizeof(char);   //Gibt die Anzahl der Bytes wieder

   pages = checkLenght(size);

   Serial.println(pages);


	pinMode(ss, OUTPUT);
	pinMode(9, OUTPUT);
	digitalWrite(9, HIGH);
	pinMode(8, OUTPUT);
	digitalWrite(8, HIGH);
	SPI.begin();
	SPI.setBitOrder(MSBFIRST);
	SPI.setClockDivider(4);
	digitalWrite(ss, HIGH);


	delay(100);



writeEnable();  //Schreiben einschalten

	delay(10);

	digitalWrite(ss, LOW);  //Beispiel schreiben
	SPI.transfer(writeEEP);
	SPI.transfer(0x05);
	SPI.transfer(a);
	SPI.transfer(b);
	digitalWrite(ss, HIGH);

	delay(100);

	writeEnable();  //Schreiben einschalten

	digitalWrite(ss, LOW);  //Char Array Schreiben
	delay(10);
	SPI.transfer(writeEEP);
	SPI.transfer(startPage);
	SPI.transfer(size);



for (int i = 0; i < size - 1; i++){
 SPI.transfer(myStr[i]);
}

	 digitalWrite(ss, HIGH);

	delay(10);


void writeDisable();  //Schreiben beenden



delay(100);

	digitalWrite(ss, LOW);
	delay(10);
	SPI.transfer(readEEP);   //Lese ein
	SPI.transfer(0x05);		//Adresse
	c = SPI.transfer(0xFF);
	d = SPI.transfer(0xFF);
	digitalWrite(ss, HIGH);
delay (100);

Serial.println(pages);

digitalWrite(ss, LOW);
delay(10);
SPI.transfer(readEEP);   //Lese ein
SPI.transfer(startPage);
strSize = SPI.transfer(0xFF);    //Anzahl der Buchstaben einlesen


for(int n=0; n < strSize -1; n++){
ausgabe[n] = SPI.transfer(0xFF);
}

digitalWrite(ss, HIGH);               //Lesen Ende

Serial.print(pages);
Serial.print("  ");
Serial.print(strSize);
Serial.print("  ");
Serial.print(d);
Serial.print("  ");
Serial.print(c);
Serial.print("  ");
Serial.println(ausgabe);

}

void loop()
{

}

Die Variable "pages" soll den Wert enthalten, wie viele Pages für den String im EEPROM beschrieben werden sollen (beginnend bei 0).
(mehr als eine Page geht zurzeit auch noch nicht, aber das soll hier nicht das Problem sein)

Mein Text, den ich in den EEPROM schreibe enthält 15 Buchstaben, der Befehl size zählt 16. Im ersten Byte das geschrieben wird steht die Anzahl der nachfolgenden Bytes.

"pages" teilt die Größe durch 17;
bei 17 chars = 1
bei 16 chars = 0

Funktioniert auch alles.

Nach dem letzten Lese-befehl ändert sich allerdings der Wert der Variable von anfangs 0 auf 107, und ich habe keine Ahnung wieso?!

Die Serielle Ausgabe sieht so aus;

0

0
107  16  53  149  Zeichen 15 Stck

Die erste Null: unmittelbar nach dem die Variable das erste mal aufgerufen worden ist: passt!

Die zweite Null: Vor dem letzten Lese-befehl aus dem EEPROM: passt!

Das dritte mal: 107 ???

Dass C Strings Null-terminierte char Arrays sind ist dir klar? Das Array ist 1 länger als die Anzahl der sichtbaren Zeichen, weil der String mit 0, bzw. '\0' terminiert ist.

sizeof() zählt den Terminator mit. Wenn du die eigentliche Länge des Strings willst, gibt es dafür strlen() (string length). Da wird der Terminator nicht gezählt. Welches aber anders als sizeof() eine Funktion ist die immer zur Laufzeit ausgeführt wird!

Wenn du den Terminator nicht im EEPROM speicherst (was nicht sein muss), musst du ihn beim Auslesen per Hand hinten anfügen. Und dein Ziel-Array muss auch mindestens Länge + 1 groß sein

EDIT: Wenn du mehrere Strings unterschiedlicher Länge speichern willst, kann es sich aber anbieten den Terminator mitzuspeichern. Dann kannst du einfach solange auslesen bis 0 kommt und dann aufhören.

Das ist ein klasischer Index-Überlauf.
Du definierst myStr 16 elemente (15 Buchstaben/Leerzeichen und abschließende null)
und schreibst sie ins EEprom.
beim lesen willst Du diese 15-1 Zeichen in ein 14 elemente Array schreiben. Dabei wird die Speicherzelle des RAMs nach den Speicherzellen des Arrays ausgabe[] überschrieben.

Abhilfe: vergrößere ausgabe[] auf 15, besser 16 Elemente.

Grüße Uwe

Was mir aufgefallen ist, du hast einen Funktionsaufruf mit "void" davor.

void writeDisable(); //Schreiben beenden

Das funktioniert doch meiner Meinung nach nicht, oder liege ich da falsch.
Er kompiliert zwar, aber der Aufruf funktioniert nicht.

Solltest richtig liegen. Dadurch wird writeDisable neu bekannt gegeben und aufgrund dessen, dass diese innerhalb der Funktion loop steht, wird die andere globale Funktion nicht mehr beachtet.

sschultewolter:
Solltest richtig liegen. Dadurch wird writeDisable neu bekannt gegeben und aufgrund dessen, dass diese innerhalb der Funktion loop steht, wird die andere globale Funktion nicht mehr beachtet.

Dann häng es wohl (unter anderem) daran.

Problem gelöst!
Besten Dank an Uwe, da wäre ich nie drauf gekommen!

@Serenifly; das ganze ist mehr Feierabend-Bastelei, bisher ohne sinnvollen Nutzen. Ob ich das Nullzeichen mit aufnehme oder nicht, darum mache ich mir ein anderes mal Gedanken.

@HotSystems / sschultewolter
Edit: Ja das ist ein Fehler, hab es korrigiert. Danke!

bananenjoe:
@Serenifly; das ganze ist mehr Feierabend-Bastelei, bisher ohne sinnvollen Nutzen. Ob ich das Nullzeichen mit aufnehme oder nicht, darum mache ich mir ein anderes mal Gedanken.

Es ist deshalb wichtig weil die Länge deines Ziel Arrays nicht passt