Hallo,
mich beschäftigt ein wahrscheinlich ziemlich einfacher Fehler in einem
Arduino-Code, den ich mir nicht erklären kann.
Ich habe jedes Beiwerk weggelassen und poste nur die wichtigste Stelle:
1
// i2c_eeprom_buch_1
2
#include <Wire.h>
3
// #include <twi.h>
4
#define i2cadresse 0x57 ; // I2C-Adresse des EEPROMS
5
// Achtung: wahrscheinlich darf es nicht
6
// heißen eeprom
7
// gibt sonst Fehlermeldung bei Serial.begin(9600)
8
void setup()
9
{
10
Wire.begin(); // join i2c bus (address optional for master)
Die Fehlermeldung lautet:
i2c_eeprom_buch_1.ino: In function 'void setup()':
i2c_eeprom_buch_1:13: error: expected `)' before ';' token
i2c_eeprom_buch_1:13: error: expected primary-expression before ','
token
i2c_eeprom_buch_1:13: error: expected `;' before ')' token
i2c_eeprom_buch_1:14: error: expected `)' before ';' token
i2c_eeprom_buch_1:14: error: expected primary-expression before ','
token
i2c_eeprom_buch_1:14: error: expected `;' before ')' token
Der Fehler geschieht also, wie es aussieht, in der Zeile mit
byte wert = 7;.
Der Abschluß dieser Instruktion kommt mir ganz normal vor. Ob da
irgendwelche nicht lesbaren Sonderzeichen im Spiel sind?
Ich sollte vielleicht erwähnen, daß ich bei der Fehlersuche immer weiter
rückwärts geschritten bin und schließlich bei der vorliegenden Version
gelandet bin, die eine wörtliche Abschrift aus einem Buch von Erik
Bartmann ist.
Vielen Dank schon mal
Alexander
Danke - es hat etwas geholfen.
Ich hatte Semikolon und Komma auch schon gestrichen und wieder
eingesetzt- mit mäßigen Erfolg
Ich weiß zwar, daß da kein Semikolon hingehört, aber die Variation
Semikolon / kein Semikolon ist nicht überzeugend:
Fehlermeldung m i t Semikolon:
i2c_eeprom_buch_1:10: error: expected ',' or '...' before numeric
constant
i2c_eeprom_buch_1:10: error: expected `)' before ';' token
i2c_eeprom_buch_1:10: error: expected unqualified-id before ',' token
i2c_eeprom_buch_1:10: error: expected unqualified-id before 'unsigned'
i2c_eeprom_buch_1:22: error: expected ',' or '...' before numeric
constant
i2c_eeprom_buch_1:22: error: expected `)' before ';' token
i2c_eeprom_buch_1:22: error: expected unqualified-id before ',' token
i2c_eeprom_buch_1:22: error: expected unqualified-id before 'unsigned'
Fehlermeldung o h n e Semikolon:
i2c_eeprom_buch_1:10: error: expected ',' or '...' before numeric
constant
i2c_eeprom_buch_1:22: error: expected ',' or '...' before numeric
constant
Ohne Semikolon ist's natürlich besser, aber immer noch nicht lauffähig
und (für mich) noch unerklärlich.
Gruß
A
> ... ist nicht überzeugend:
Nun ja. Es geht hier nicht darum ob Du Joghurt mit Erdbeergeschmack oder
Pfirsich bevorzugst. :-) Auch sollst nicht DU "überzeugt" werden,
sondern der Compiler. :-)
Es gibt eindeutige Regeln, wie C-Programme geformt sein müssen. Die
sogenannte Syntax.
Glaub' mir. Da gehört kein Semikolon hin. Und ich hoffe der Kommentar
danach war hier nur zur Erklärung.
Der Code muss jetzt so aussehen:
1
// i2c_eeprom_buch_1
2
#include<Wire.h>
3
// #include <twi.h>
4
#define I2CADRESSE 0x57
5
// I2C-Adresse des EEPROMS
6
// Achtung: wahrscheinlich darf es nicht
7
// heißen eeprom
8
// gibt sonst Fehlermeldung bei Serial.begin(9600)
9
voidsetup()
10
{
11
Wire.begin();// join i2c bus (address optional for master)
Der Fehler muss nicht unbedingt in dem von dir geposteten Codeabschnitt
liegen. Es kann auch sein, dass du weiter oben eine Klammer geöffnet,
aber nicht wieder geschlossen hast. Oder aber du hast vorher ein
Semikolon vergessen.
Zugegeben, die Fehlermeldungen sind manchmal nicht ganz einfach zu
verstehen.
Aber das ist eine Übungssache. Fast immer ist die erste Meldung, so
seltsam sie erscheinen mag, die relevante.
Wenn ich einmal Deinen obigen Code nehme und Präprozessor spiele dann
kommt folgendes heraus:
1
schreibEEPROM(i2cadresse0x57;// I2C-Adresse des EEPROMS, speicheradresse, wert);
2
Serial.println(liesEEPROM(i2cadresse0x57;// I2C-Adresse des EEPROMS, speicheradresse) HEX);
3
}
Du siehst wahrscheinlich selbst, dass das Semikolon und der Kommentar
überhaupt keinen Sinn machen.
Noch zur Erklärung:
Die Kommentarzeichen "//" bzw. "/*" und "*/" sind Elemente der
C-Sprache. NICHT aber des Präprozessors. In der Präprozessorsprache gibt
es keine Kommentare.
Die Syntax-Definition des Präprozessor-Befehls "#define" in der
verwendeten Form (ohne Parameter) ist:
"#define" <identifier> <token-sequence>
Die Bedeutung ist folgende:
"Ersetze im folgenden Programmtext jedes Auftreten von <identifier>
durch die <token-sequence>
Wobei die <token-sequence> (abgesehen von einem Detail in Bezug auf
Leerzeichen) die Zeichen sind die nach <identifier> folgen. Egal, was
das für Zeichen sind!
Lies mal in einem guten C-Buch nach! Das ist sehr wichtig!
lass die #defines einfach weg. Je weniger, desto besser.
nimmt ein
const int i2cadresse= 0x57 ;
Dann gibt es keine bizarren Textersetzungen, die Anfänger überfordern.
Und der Compiler sollte den gleichen Code erzeugen.
deine Deklarationen der Variablen dürfen bei einem C-Compiler nicht
mitten in der Funktion stehen, sondern immer am Anfang. Nur bei C++ ist
dies erlaubt.
Daher kann es durchaus sein, dass der abgeschriebene Code bei dem Autor
funktioniert, wenn dieser ein C++ Compiler verwendet, bei dir geht das
aber in die Hose wenn du einen C Compiler verwendest.
1
voidsetup()
2
{
3
unsignedintspeicheradresse;
4
bytewert;
5
6
Wire.begin();// join i2c bus (address optional for master)
ConvertsQuestionsToAnswers schrieb:> Die Kommentarzeichen "//" bzw. "/*" und "*/" sind Elemente der> C-Sprache. NICHT aber des Präprozessors. In der Präprozessorsprache gibt> es keine Kommentare.
Das war vor 100 Jahren mal ein Problem, alle heutigen Compiler haben
damit keine Probleme, iirc ist das mitlerweile sogar Standardkonform,
das C-Comment // machte noch nie Probleme, das C++ Comment /* */
vielleicht noch bei Asbachuraltcompilern.
Mitleser schrieb:> deine Deklarationen der Variablen dürfen bei einem C-Compiler nicht> mitten in der Funktion stehen, sondern immer am Anfang. Nur bei C++ ist> dies erlaubt.
Für C99 gilt das nicht mehr, da kannste wie in C++ deklarieren wo du
willst.
Zudem war das bei C89 auch kein Problem, man hat einfach einen neuen
Scope mit einem neuen Block erzeugt, nat. musste man aufpassen wegen der
Sichtbarkeit, i.d.R sind das eh meistens Hilfsvariablen innerhalb von
Blöcken von if else ...
Der Übersichtlichkeit wegen deklariert man seine Variablen trozdem am
Anfang einer Funktion, ausser vielleicht Zählvaribalen für for-schleifen
wenn man sie sonst nicht mehr braucht.
Mitleser schrieb:> deine Deklarationen der Variablen dürfen bei einem C-Compiler> nicht> mitten in der Funktion stehen, sondern immer am Anfang. Nur bei C++ ist> dies erlaubt.
Es ging hier um Arduino. Dahinter steht ein C++ Compiler. Sollte also
kein Problem sein.
@ Schwen Gel (sean_l)
> ... ist das mitlerweile sogar Standardkonform,
Ja richtig. Ich vergaß das.
An sich sollten nach C99 Kommentare durch ein Whitespace ersetzt werden,
bevor die Ersetzung erfolgt. Allerdings haben viele C-Compiler das
nicht richtig implementiert, so daß ich mir das wieder abgewöhnt habe.
Formal hast Du recht.
Jedoch: // ist der C++-Kommentar und /* */ der C-Kommentar. :-)
Letztlich sollte man bei Problemen, bei denen der Präprozessor beteiligt
sein könnte, die Präprozessor-Ausgabe anschauen.
isnah schrieb:> Der Fehler muss nicht unbedingt in dem von dir geposteten Codeabschnitt> liegen. Es kann auch sein, dass du weiter oben eine Klammer geöffnet,> aber nicht wieder geschlossen hast. Oder aber du hast vorher ein> Semikolon vergessen.
Das hatte ich auch immer gemeint. Mein Programmschnipsel ist der oberste
Teil, darüber gibt es nichts mehr, es kann also nicht die sattsam
bekannten Probleme mit weiter oben vergessenen Kommata oder Klammern
geben.
ABER: Was mich sehr wundert ist, folgendes: Ich habe die Version von
ConvertsQuestionsToAnswers in ein neues Blatt kopiert und es dem
Compiler ausgesetzt, der erwartungsgemäß nicht zu maulen fand.
Dann habe ich unten einige angefangene Instruktionen zugefügt und prompt
kam die Fehlermeldung wieder.
Kommt mir sehr merkwürdig vor.
Programmschnipsel (erweiterte Version von ConvertsQuestionsToAnswers):
1
// i2c_eeprom_forum
2
#include <Wire.h>
3
// #include <twi.h>
4
#define I2CADRESSE 0x57 // wird beanstandet, wenn liesEEPROM... nicht auskommentiert ist
5
//const int I2CADRESSE = 0x57; // läßt sich unbeanstandet kompilieren
6
7
void setup()
8
{
9
Wire.begin(); // join i2c bus (address optional for master)
byte liesEEPROM(int I2CADRESSE, unsigned int speicheradresse) // byte datenbyte=0xFF)
22
{
23
Wire.beginTransmission(I2CADRESSE);
24
}
25
26
//void schreibEEPROM(int I2CADRESSE, unsigned int speicheradresse, byte wert)
27
//{}
Die Fehlermeldung:
i2c_eeprom_forum:10: error: expected ',' or '...' before numeric
constant
i2c_eeprom_forum:21: error: expected ',' or '...' before numeric
constant
Ich weiß, der Compiler hat immer recht, deshalb werde ich nach dem
Vorschlag von PittyJ verfahren. Verstehen würde ich aber trotzdem gern,
was da schief läuft.
Gruß
Alexander
Ich werde
Alexander Schmeil schrieb:> byte liesEEPROM(int I2CADRESSE, unsigned int speicheradresse) //
Das sollte nicht gehen. Überleg Dir mal was '#define' macht: er ersetzt
den Text. Und was sollte
byte liesEEPROM(int 0x57, unsigned int speicheradresse)
dann bedeuten?