Hallo zusammen,
Ich habe ein ausführliches Programm geschrieben, das mir fürs Erste Stepper- Motoren betreiben soll. Das Programm lief auf dem Arduino Nano einwandfrei. Da aber nun der Nano für das Projekt nicht weiter ausreichend ist, aufgrund zu kleinem Arbeitsspeicher und Ausstattung, wollte ich zum ESP32 wechseln. Allerdings bekomme ich es darauf nicht mehr zum laufen. Kleinere Tests mit einfachen Ausgaben mit Serial.println() macht der ESP32 (Wollte einen gravierenden Defekt ausschließen). Zum Einsatz kommen die AccelStepper. 1.64, BluetoothSerial-2.0.0, Queue-1.11 und Wire-2.0.0. Der ESP32 steigt aus, wenn er das Array instanziieren soll, sobald er in der Zeile:
Hat jemand vll einen Rat? Ich kann leider nicht das ganze Projekt posten, da es mehr als 23 Files hat mit dementsprechend vielem Code.
ebenso zeigt es mir folgende Fehler an:
E0059|Der Funktionsaufruf ist in einem Konstantenausdruck nicht zulässig.|C:\Users\frogg\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.11\tools\sdk\esp32\include\soc\esp32\include\soc\soc_caps.h|32||
E0351 Der erste Parameter der Speicherbelegungsfunktion muss vom Typ "size_t" sein. C:\Users\frogg\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\esp-2021r2-patch5-8.4.0\xtensa-esp32-elf\include\c++\8.4.0\new 122
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben
Da wir nicht wissen sollen was engines und Engine ist, kann man das nicht sagen.
AccelStepper implementiert zumindest einen KopyKonstruktor und evtl. auch den = Operator.
Kann also so klappen. (ohne Gewähr)
@DrDiettrich wie bereits erwähnt, ist das ganze ja schon bereits gelaufen bzw. läuft auf dem Nano. Ich bin auch gern bereit mehr von meinen geheimen code zu zeigen @combie
Diese Implementierung arbeitet mit dem Array:
#include "EngineControler.h"
EngineControler::EngineControler() {}
void EngineControler::initEngines(Engine** enginesArray, int numberOfEngines) {
this->enginesCount = numberOfEngines;
for (size_t i = 0; i < numberOfEngines; i++)
{
engines[i] = enginesArray[i];
pinMode(engines[i]->SleepPin, OUTPUT);
engines[i]->Stepper.setAcceleration(engines[i]->Acceleration);
engines[i]->Stepper.setMaxSpeed(engines[i]->Max_Speed);
Serial.println(String(engines[i]->EngineId));
}
}
/// <summary>
/// Controls the spinning of the motors.
/// </summary>
/// <param name="repetitionFrequency"></param>
void EngineControler::RunEngines(Engine* runningEngines[], int repetitionFrequency) {
wakeUpMotors();
for (size_t f = 0; f < repetitionFrequency; f++)
{
for (size_t i = 0; i < this->enginesCount; i++)
{
runSingleEngine(engines[i]);
}
}
}
/// <summary>
/// Sets the motors back to startposition
/// </summary>
void EngineControler::goHome() {
Serial.println("Wait while moving homepos...");
wakeUpMotors();
for (size_t i = 0; i < enginesCount; i++)
{
engines[i]->Stepper.stop();
}
for (size_t i = 0; i < enginesCount; i++)
{
engines[i]->Stepper.runToNewPosition(0);
}
for (size_t i = 0; i < enginesCount; i++)
{
engines[i]->Stepper.setCurrentPosition(0);
}
for (size_t i = 0; i < enginesCount; i++)
{
engines[i]->Stepper.disableOutputs();
}
setSleepMotors();
Serial.println("Done moving homepos...");
}
/// <summary>
/// Sets the the stepperdriver to sleeping-mode so the motors are without electricity
/// </summary>
void EngineControler::setSleepMotors() {
//If A4988 is LOW Motors off, if TMC2209 is LOW Motors on
for (size_t i = 0; i < enginesCount; i++)
{
switch (engines[i]->DriverType)
{
case DRIVER_A4988:
digitalWrite(engines[i]->SleepPin, LOW);
break;
case DRIVER_TMC2209:
digitalWrite(engines[i]->SleepPin, HIGH);
break;
}
}
}
/// <summary>
/// Brigns the stepperdriver back from sleepingmode and sets the motors under electricity
/// </summary>
void EngineControler::wakeUpMotors() {
//If A4988 is HIGH Motors on, if TMC2209 is HIGH Motors off
for (size_t i = 0; i < enginesCount; i++)
{
switch (engines[i]->DriverType)
{
case DRIVER_A4988:
digitalWrite(engines[i]->SleepPin, HIGH);
break;
case DRIVER_TMC2209:
digitalWrite(engines[i]->SleepPin, LOW);
break;
}
}
}
/// <summary>
/// Eexecutes the movement for the specific motor
/// If engine.StepSpeed is 128 so there is no movement. If the engine.StepSpeed is between 128 and 255 so the motor will move forward.
/// The higher the number between 128 and 255, the faster the motor will move forwart.
/// </summary>
/// <param name="engine"></param>
void EngineControler::runSingleEngine(Engine* engine) {
if (engine->StepTemp.StepSpeed > 128) {
int speed = map(engine->StepTemp.StepSpeed, 128, 255, 0, engine->Max_Speed);
engine->Stepper.setSpeed(speed);
engine->Stepper.move(1);
}
else if (engine->StepTemp.StepSpeed < 126) {
int speed = map(engine->StepTemp.StepSpeed, 126, 0, 0, engine->Max_Speed);
engine->Stepper.setSpeed(-speed);
engine->Stepper.move(-1);
}
engine->Stepper.run();
}
/// <summary>
/// Sets the motors at his current position on zero so this new position is the new homposition
/// </summary>
void EngineControler::SetHomePos() {
Serial.println(F("Wait while setting homeoffstets..."));
for (size_t i = 0; i < enginesCount - 1; i++)
{
engines[i]->Stepper.setCurrentPosition(0);
}
Serial.println(F("Homeoffstets now to zero on this Position!"));
}
Allerdings habe ich die ganzen Fehler auch in einem leeren Projekt, sobald ich ESP Dev Module auswähle.
@combie, minimaler lässt es sich doch kaum darstellen. Es wird ein Array mit Engine- Objekten erstellt, mit dem in der Klasse gearbeitet wird. Das engines Array ist Teil des RoboticArm und beinhaltet dessen Motoren. Der EngineControler stellt Methoden bereit, die bestimmte Bewegungsabläufe für die Motoren ermöglichen. Somit kann ich dann sagen: EngineControler -> nimm den Motor mit der ID 1 aus deinem Array -> drehe ihn. Das ganze soll eine starke Abstraktion sein, da ich vor habe, das Objekt "RoboticArm" aus einem JSON von einem Speichermedium zu laden, um dementsprechende Setups machen zu können ohne jedes Mal an den Code zu müssen. Nun bin ich halt aber mit der Serialisierung der JSON -Objekte an die Grenze des Nano gestoßen. Wie bereits erwähnt lief auf dem Nano der Code bereits, mit Umstieg auf den ESP32 gab's auf einmal Probleme. Ich vermute desshalb nicht, dass es an meinem Code liegt, sondern an der Bibliothek des ESP32. Da ja auch dementsprechend Fehler gefunden werden in der ESP32 Bibliothek ( wie oben auch schon bereits erwähnt )
Espressif ist Schuld! (ich bin nicht Espressif!)
Du magst recht haben (mit einer geschätzten Wahrscheinlichkeit von 1%).
Die Ansage ist somit eine ganz schlechte Voraussetzung um Fehler im eigenen Code zu finden.
Eine selbst gebaute mentale Hürde.
Bei einer Komponenten basierten, modularen Programmierung kann man alle Komponenten einzeln testen.
Ich kann gar nix von dir testen. (sehe nur verstümmelte Fragmente)
Und du offensichtlich auch nicht.
Irgendwie fällt es mir schwer zu erkennen wozu das gehört. Kannst du die Code Zeile markieren?
Wenn du nicht weiterkommst würde ich vllt auch ein kleines Refactoring probieren und in RoboticArm die engines vllt als statische struktur mit initialisierungsliste probieren
@db-engineerDiese Fehler kommen eben aus der Bibliothek von Espressif aus dem Dateipfad: ...\Arduino15\packages\esp32\hardware\esp32\2.0.11\tools\sdk\esp32\include\soc\esp32\include\soc\soc_caps.h und ...\Arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\esp-2021r2-patch5-8.4.0\xtensa-esp32-elf\include\c++\8.4.0\new. Sie werden permanent angezeigt im Visual Studio, so bald ich auf den Nano wechsle und kompiliere sind sie weck.
#ifndef _ENGINECONTROLER_h
#define _ENGINECONTROLER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
#include <AccelStepper.h>
enum StepperDriverType
{
DRIVER_A4988,
DRIVER_TMC2209
};
struct Engine
{
int EngineId;
int SleepPin;
int Max_Speed;
int Acceleration;
AccelStepper Stepper;
StepperDriverType DriverType;
struct EngineStepTemplate {
int Steps;
int StepSpeed;
};
EngineStepTemplate StepTemp;
Engine() = default;
};
class EngineControler
{
private:
Engine* engines[3];
int enginesCount;
void runSingleEngine(Engine* engine);
public:
EngineControler();
void initEngines(Engine** enginesArray, int enginesCount);
void RunEngines(Engine* runningEngines[], int repetitionFrequency);
void setSleepMotors();
void wakeUpMotors();
void SetHomePos();
void goHome();
};
#endif
und das Minimalbeispiel, das auf dem Nano ohne Probleme klappt, aber nicht auf dem ESP32 (Dort geht die Initialisierung des "EngineControler" schon daneben :
#include "RoboticArm.h"
#include "EngineControler.h"
EngineControler _engineControler;
RoboticArm _roboticArm;
String _output;
void setup() {
Serial.println(F("Start Setup"));
_engineControler.initEngines(_roboticArm.getPointersOfEngines(), _roboticArm.getNumEngines());
}
void loop(){
if (Serial.available()) {
char command = Serial.read();
if (command == 'W') {
//hohlt den Treiber aus dem Schafzustand
_engineControler.wakeUpMotors();
_output = "Wakeup";
}
else if (command == 'S') {
//setzt z.B. den Treiber in den Schlafzustand
_engineControler.setSleepMotors();
_output = "Sleep";
}
}
if (_output.length() > 0) {
Serial.println(_output);
_output = "";
}
}
und die .h Files für das Beispiel:
#ifndef _ENGINECONTROLER_h
#define _ENGINECONTROLER_h
#if defined(ARDUINO) && ARDUINO >= 100
#include "arduino.h"
#else
#include "WProgram.h"
#endif
#include <AccelStepper.h>
enum StepperDriverType
{
DRIVER_A4988,
DRIVER_TMC2209
};
struct Engine
{
int EngineId;
int SleepPin;
int Max_Speed;
int Acceleration;
AccelStepper Stepper;
StepperDriverType DriverType;
struct EngineStepTemplate {
int Steps;
int StepSpeed;
};
EngineStepTemplate StepTemp;
Engine() = default;
};
class EngineControler
{
private:
Engine* engines[3];
int enginesCount;
void runSingleEngine(Engine* engine);
public:
EngineControler();
void initEngines(Engine** enginesArray, int enginesCount);
void RunEngines(Engine* runningEngines[], int repetitionFrequency);
void setSleepMotors();
void wakeUpMotors();
void SetHomePos();
void goHome();
};
#endif
Dazu kann ich nur sagen, dass ich die Meldung noch nie gesehen habe.
Und ja: Ich verwende auch ESP32 Boards und auch new
Allerdings mit der Arduino IDE,
@combie, wenn du keine Lust hast mir zu helfen, dann Antworte doch einfach nicht. Ich gebe mir ja Mühe, das wie gesagt nicht kleine Projekt auf notwendige Stück runter zu brechen. Ein Minimal- Testbeispiel habe ich doch jetzt auch erstellt.
ist das ein PlatformIO Projekt?
Sind alle Libs im Projektordner?
Also ist das Projekt als solches portabel?
Wenn ja, werfe nochmal alles raus was zur Fehlersuche nicht benötigt wird und den Fehler noch zeigt. Dann stelle das Projekt als .zip zur Verfügung. Dann stehen die Chancen besser das jemand mit PlatformIO und ESP32 Kenntnissen reinschauen kann.
Glaube es, oder lasse es...
Ich habe wirklich versucht mit deinen bisherigen spärlichen Angaben deine Probleme zu reproduzieren.
Ist mir nicht gelungen. Magst du meiner Dummheit zurechnen dürfen.
Hat wohl nicht geklappt....
Nano:
sketch_aug25b.ino:11: undefined reference to `_ZN10RoboticArm20getPointersOfEnginesEv'
ESP:
e:/programme/arduino/portable/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.exe: E:\temp\Arduino\sketch\sketch_aug25b.ino.cpp.o:(.literal.startup._GLOBAL__sub_I__engineControler+0x10): undefined reference to `RoboticArm::RoboticArm()'
e:/programme/arduino/portable/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.exe: E:\temp\Arduino\sketch\sketch_aug25b.ino.cpp.o:(.literal._Z5setupv+0x4): undefined reference to `RoboticArm::getPointersOfEngines()'
e:/programme/arduino/portable/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.exe: E:\temp\Arduino\sketch\sketch_aug25b.ino.cpp.o:(.literal._Z5setupv+0x8): undefined reference to `RoboticArm::getNumEngines()'
e:/programme/arduino/portable/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.exe: E:\temp\Arduino\sketch\sketch_aug25b.ino.cpp.o: in function `_GLOBAL__sub_I__engineControler':
E:\Programme\arduino\portable\sketchbook\sketch_aug25b/sketch_aug25b.ino:5: undefined reference to `RoboticArm::RoboticArm()'
e:/programme/arduino/portable/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.exe: E:\temp\Arduino\sketch\sketch_aug25b.ino.cpp.o: in function `setup()':
E:\Programme\arduino\portable\sketchbook\sketch_aug25b/sketch_aug25b.ino:11: undefined reference to `RoboticArm::getPointersOfEngines()'
e:/programme/arduino/portable/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.exe: E:\Programme\arduino\portable\sketchbook\sketch_aug25b/sketch_aug25b.ino:11: undefined reference to `RoboticArm::getNumEngines()'
collect2.exe: error: ld returned 1 exit status