Hallo,
kann mal jemand testen ob das compiliert? Ich hab heute Arduino auf Windows installiert aber es spinnt rum. Ich vermute die #define werden nicht in der richtigen Reihenfolge abgearbeitet, so dass die Funktion (oder die ganze .cpp Datei?) nicht gefunden wird. Dasselbe Spiel hatte ich anfangs mit dem struct KINGMETER_t KM; er wollte partout die header Datei nicht einlesen. Erst als ich das #include weiter nach unten gesetzt habe ging's plötzlich weiter...
Ich vermute die #define werden
nicht in der richtigen Reihenfolge abgearbeitet
soso
, so dass die Funktion
(oder die ganze .cpp Datei?) nicht gefunden wird.
Das wird es wohl sein, hat aber nicht mit den CPP-Macros zu tun.
Dasselbe Spiel hatte
ich anfangs mit dem struct KINGMETER_t KM; er wollte partout die header
Datei nicht einlesen. Erst als ich das #include weiter nach unten
gesetzt habe ging's plötzlich weiter...
Die Header-Datei braucht die CPP-Macros ...
Wenn ich die Funktion ohne Argumente aufrufe, dann sagt er mir welche
Argumente fehlen, also hat er die Deklaration. Mit Argumenten heißt es
dann undefined reference.
D.h., die Definition in der Funktion fehlt.
Dann musst Du die .cpp-Datei suchen, in der diese Funktion definiert wird.
Die config.h fehlt bei mir, ich habe nur eine .h und eine .cpp Datei in
den Sketch kopiert.
C++-Programmieren nach nicht nach dem Zufallsprinzip.
In Summe würde ich sagen: kauf die ein C++-Buch mit den Grundlagen.
Schau doch bitte zuerst in das log. Es ist alles da. Bis auf die config.h - die will ich nicht. Ich habe die relevanten Zeilen daraus in die .ino kopiert.
Wenn ich die Funktion ohne Argumente aufrufe, dann sagt er mir welche
Argumente fehlen, also hat er die Deklaration. Mit Argumenten heißt es
dann undefined reference.
Die config.h fehlt bei mir, ich habe nur eine .h und eine .cpp Datei in
den Sketch kopiert.
lib: https://github.com/jenkie/Arduino-Pedelec-Controller
Dann ist der Header vorhanden, aber der Quellcode wurde nicht dazugelinkt.
Das Projekt sieht auch sehr angestaubt aus. Es wird CMake verwendet, aber der Autor hat offensichtlich noch geübt.
Und über so eine Bild Schlagzeile als Threadtitel kann man nur den Kopf schütteln.
Ich möchte nicht das gesamte Projekt, ich möchte nur diese beiden Dateien display_kingmeter.h und display_kingmeter.cpp in ein Sketch einbinden. Dazu habe ich diese von github heruntergeladen und in den Sketch Ordner kopiert. Aus dem Log geht hervor das diese auch compiliert werden.
Vielleicht liegt es am Windows. Oder an der Arduino IDE, da hatte ich schon mal ein anderes Problem.
du kratzt ohne Plan Dateien aus einem komplexen Projekt, und wenn es nicht funktioniert liegt es an Windows. Unfassbar.
Dann benutze doch ein anderes OS.
Geh mal davon aus, das eine Abhängigkeit besteht zwischen dem was da
heraus kopiert hast und dem was du da nicht heraus kopiert hast.
Ich bin es Zeile für Zeile durchgegangen und alles was in der .h und der .cpp abgefragt wird, habe ich in der .ino definiert. Ich kann mir die Werte auch über Serial.print() anzeigen lassen, da stimmt alles. Allerdings weiß ich nicht ob die Reihenfolge der #define stimmt, oder wie ich die überprüfen könnte.
/home/mint/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/sketch_oct25a.ino.cpp.o:(.literal._Z5setupv+0x14): undefined reference to `KingMeter_Init(KINGMETER_t*, HardwareSerial*)'
3
/home/mint/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/esp-2021r2-patch5-8.4.0/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld: sketch/sketch_oct25a.ino.cpp.o: in function `setup()':
4
/home/mint/Arduino/sketch_oct25a/sketch_oct25a.ino:20: undefined reference to `KingMeter_Init(KINGMETER_t*, HardwareSerial*)'
Geht das so nicht? D.h. es muss zwingend in eine Header Datei kopiert
werden?
durch das #include wird die angegebene Datei in den Quelltext eingefügt. Die Datei kann auch Kai-Uwe.irgendwas heißen, das ist völlig egal für den Compiler. Insofern ist es ok wenn man den Inhalt per cut & paste in den Quelltext bringt.
Man muss aber alle Abhängigkeiten erfassen und verschachtelte Funktionen müssen als Quelltext in das Projekt übernommen werden. Und die wollen wieder irgendwelche defines haben.
Der Compiler liest alles Zeilenweise ein, da gibt es keine Magie und kein unterschiedliches Verhalten zwischen OS. Wenn irgendwo ein #ifdef steht dann kommt es darauf an ob das abgefragte define vorher gesetzt wurde oder nicht.
Alternativ kann das auch dem Compiler mitgegeben werden, aber das wird im einfachen Arduino Buildsystem nicht gut unterstützt, deshalb hat der Autor von dem github Projekt das wohl auch mit CMake angefangen. Oder platformIO verwenden, da kann man einfach mehrere Konfigurationen mit verschiedenen defines anlegen.
Geh mal davon aus, das eine Abhängigkeit besteht zwischen dem was da
heraus kopiert hast und dem was du da nicht heraus kopiert hast.
Ich bin es Zeile für Zeile durchgegangen und alles was in der .h und der
.cpp abgefragt wird, habe ich in der .ino definiert. Ich kann mir die
Werte auch über Serial.print() anzeigen lassen, da stimmt alles.
Allerdings weiß ich nicht ob die Reihenfolge der #define stimmt, oder
wie ich die überprüfen könnte.
Die config.h fehlt bei mir, ich habe nur eine .h und eine .cpp Datei in
den Sketch kopiert.
display_kingmeter.h inkludiert aber config.h. Irgendetwas musst du getan haben, um dieses Problem zu umgehen. Und dabei hast du wahrscheinlich eine Inkonsistenz erzeugt, zum Beispiel display_kingmeter.o für SoftwareSerial übersetzt, das .ino aber mit HardwareSerial.
Laut Log wurde die passende cpp-Datei problemlos compiliert. Dann müsste
sie eigentlich auch mitgelinkt werden.
Wenn der Linker eine compilierte Funktion nicht findet, kann es daran
liegen, dass bei ihrem Aufruf ein 'full qualified name' nötig gewesen
wäre.
Vielleicht bezieht sich die Fehlermeldung aber auf einen der
Aufruf-Parameter der Funktion und nicht auf die Funktion selbst?
Ich habe nun mal alle unnötigen #if und #ifndef auskommentiert, nun bekomme ich andere Fehlermeldung. Sollte doch aber mit #include <Arduino.h> oder #include <stdint.h> erschlagen sein?
1
display_kingmeter.cpp:36:7: error: 'uint8_t' does not name a type
Und dabei hast du wahrscheinlich eine Inkonsistenz erzeugt, zum Beispiel
display_kingmeter.o für SoftwareSerial übersetzt, das .ino aber mit
HardwareSerial.
Aber ohne alle Sketch-Dateien exakt zu sehen bleibt nur Spekulatius ...
Mehr als im OP gepostet gibt's da nicht. Es muss auch niemand die zip herunterladen der keine Sandbox hat, die Datei ist auf github. Es ist ein leeres Sketch, ich wollte einfach nur die display_kingmeter.cpp auf dem ESP32 testen, bzw. wie man diese minimalistisch einbindet.
Es kann sein das bei diesem ESP32 Board Serial die USBSerial ist, dann passt das nicht. Der Rest sollte schon ok sein.
Probiere mal Serial1 aus.
edit:
habe es mal q&d in platformIO geworfen, kompiliert. Einfach die originale config.h verwendet und den DisplayType gesetzt. Dann meckert der Compiler noch ein unbekanntes A2 an, habe ich durch A10 und A11 ersetzt. Die Konstanten für TX und RX scheinen mir noch falsch zu sein, da müssen die Pinnummern rein.
Habe das auf github hochgeladen:
https://github.com/JojoS62/ESP32-serial
Serial ist da HardwareSerial, das kompiliert ohne Fehler.
Danke. da es an der config.h liegen musste, bin ich die noch mal durchgegangen. Es fehlten fünf Parameter.
Kompilieren ließ es sich dann aber immer noch nicht. 'uint16_t' does not name a type sowie 'HardwareSerial' does not name a type. Gehirn angestrengt und die #include <stdint.h> #include <Arduino.h> aus der .ino rausgelöscht und in die display_kingmeter.h eingetragen.
Dann kam error: 'name' was not declared in this scope für die fünf Parameter. Diese aus der .ino rausgelöscht und in die display_kingmeter.cpp eingetragen, nun kompiliert es.
Ziel war es aber eigentlich die Dateien original zu belassen. Keine Chance?
Arduino ignoriert die fehlende config.h einfach, hatte es mit und ohne Auskommentierung versucht und keinen Unterschied feststellen können. Daher habe ich die Dateien dann original belassen.
'Arduino' kann die nicht ignorieren. In config.h wird Arduino.h inkludiert und display_kingmeter.h braucht beide.
Es reicht nicht die includes nur in die .ino zu schreiben, das display_kingmeter.cpp kennt die ino nicht und muss für sich kompilierfähig sein.
Es reicht nicht die includes nur in die .ino zu schreiben, das
display_kingmeter.cpp kennt die ino nicht und muss für sich
kompilierfähig sein.
Das war das ganze Problem. Aber warum reklamiert der Compiler nicht die fehlende config.h - ich hatte nie eine erstellt? Erst der Linker scheint ein Problem damit zu haben.
wenn man #include "datei.xy" im Code hat und die Datei existiert nicht, dann meckert der Compiler definitiv. Und es gelten die Regeln des Dateisystems, d.h. unter Linux ist der Name auch case sensistive.
Du hattest das config.h aber nicht benutzt und ein paar defines selber gesetzt, aber im config.h sind noch mehr nötige Codezeilen für das Kingmeter drin.
Das Arduino.h fügt das Arduino Buildsystem in das .ino ein und es kopiert .ino und .pde Dateien zusammen, ein bisschen fummelt es an diesen Quellen schon rum. Aber das Arduino Buildsystem ist wieder gleich, egal ob Arduino IDE, PIO oder die Arduino CLI Tools.
aber im config.h sind noch mehr nötige Codezeilen für das
Kingmeter drin.
fünf Parameter aus den Config Options (Zeile 200) die ebenfalls nicht angemeckert wurden, da die Makros gar nicht erst funktionierten und die Funktion nicht bekannt war
In file included from C:\Users\Hobbyraum\Documents\Arduino\sketch_oct26a\sketch_oct26a.ino:1:0:
11
test.h:1:10: fatal error: config.h: No such file or directory
12
#include "config.h"
13
^~~~~~~~~~
14
compilation terminated.
15
exit status 1
16
config.h: No such file or directory
Es scheint also, dass die Arduino-Umgebung bei #include "config.h" trotz der Anführungszeichen (also nicht der spitzen Klammern) nach einer entsprechenden Bibliothek sucht? Das wäre allerdings eine Böse Falle!
es wird irgendeine andere config.h finden, z.B. in mbedtls. Ein fehlendes include ist ein Fehler, da braucht es keinen Loglevel.
Könnte man testen durch umbenennen in "configxyz.h".
Also so wie es bei Sebastian passiert. AVR hat kein mbedtls, also wird die config.h da nicht gefunden.
Deshalb mag ich CMake, und nicht das file globbing benutzen. Ausschreiben was includiert werden soll, nicht von einem magischen Builder suchen lassen. Kenne ich auch von Mbed...
das mbedtls ist ja im ESP SDK mit drin, dann reicht es wenn der Suchpfad da schon eingetragen ist.
..\ArduinoData\packages\esp32\hardware\esp32\1.0.4\tools\sdk\include\mbedtls\mbedtls\config.h
Es ist auch sehr däml^H^H^H^Hunklug vom Kingmeter-Autor, die Konfigurationsdatei für die Kingmeter-Sources config.h zu nennen. Wenn schon display_kingmeter.h und display_kingmeter.cpp, dann sollte das config_kingmeter.h oder kingmeter_config.h heißen.
So mache ich das in meinen Paketen auch, z.B. irmpconfig.h usw.
da ist die komplette config für den Pedelec Controller drin, es können verschiedene Displays ausgewählt werden und die ganzen Parameter sind da drin.
Das wollte der TO ja nicht übernehmen, für den Fall wäre eine gestrippte Version als king_config natürlich besser.
Es ist auch sehr däml^H^H^H^Hunklug vom Kingmeter-Autor, die
Konfigurationsdatei für die Kingmeter-Sources config.h zu nennen.
Der einzige, der hier recht "dämlich" war, war der TO.
Der hat nämlich die config.h nicht mit kopiert und hat sich dennoch nicht gewundert, dass es trotzdem compiliert bzw. "nur" ein Linker-Fehler auftaucht.
Ich habe die relevanten Zeilen daraus in
die .ino kopiert.
Geht das so nicht? D.h. es muss zwingend in eine Header Datei kopiert
werden?
Um das noch zu beantworten: Nein, das geht so nicht. Zwar sind die "relevanten Zeilen" dann während der Übersetzung der .ino bekannt, aber nicht während der Übersetzung der .cpp.
Die einfachste Lösung wäre, display_kingmeter.h anzupassen. Dort muss ja eh die Zeile #include "config.h" entfernt werden. Und an genau dieser Stelle sollten stattdessen die "relevanten Zeilen" aus der ehemaligen config.h eingefügt werden.
Dann stehen sie sowohl der .cpp als auch der .ino beim Übersetzen zur Verfügung.
Ich habe jetzt alles was ich wirklich brauche in einer einzigen Datei display_kingmeter.ino zusammengefasst. Die Funktionen waren nur zum Testen des Protokolls, mittels Jumper auf Rx+Tx.