Erste Gehversuche mit Klassen

Aloa,

ich habe mal versucht deine TestLambda für meinen Anwendungsfall zu übersetzen:

#include <Bluepad32.h>
#include <uni.h>
#include <Arduino.h>
#include <Streaming.h> 
class TestLambda
{
  private:
    int zahl;
    ControllerPtr myControllers[1];
  public:
    void onConnectedController(ControllerPtr ctl) {

     myControllers[0] = nullptr;
    };
     void onDisconnectedController(ControllerPtr ctl) {
        bool foundController = false;
     };


    int gibZahl()
    {
      return zahl;
    }

    TestLambda(Bluepad32  &testCallback)
    {
      testCallback.setup(
                                []()->const ControllerCallback&
                                {
                                  extern TestLambda tl; // unangenehme Abhängigkeit
                                  return TestLambda::onConnectedController;
                                },
                                []()->ControllerCallback&
                                {
                                  extern TestLambda tl; // unangenehme Abhängigkeit
                                  return &tl.onDisconnectedController;
                                }
                             );
    }
};

Die INO-Datei:

#include <C:\Users\User1796\Documents\Arduino\NewRcEsp32\Controller.cpp>

TestLambda   tl{BP32};



void setup() {
  
  // Setup the Bluepad32 callbacks
  BP32.setup()
  // put your setup code here, to run once:

}

Dort gibt es allerdings trotzdem den Fehler:

*hier stand quatsch*

Hier nochmal die Funktionierende Variante:

#include <Bluepad32.h>
#include <uni.h>
#include <ESP32Servo.h>

#define MOTORREGL_PIN 9 // ESP32 pin GPIO26 connected to servo motor
#define LENKSERVO_PIN 8
#define MIN_MILLS 1300
#define MAX_MILLS 2000
#define NULLPUNKT 1620
#define SPEEDDOWN 18
#define BLINKER_LINKS_PIN 7
#define BLINKER_MS 5000 //5s



static const char * controller_addr_string = "5C:BA:37:0C:F0:C5"; //Controller BT Addr

Servo pwmMotor;
Servo pwmLenkung;
int speedMics;
bool bewVorwaerts;
bool getUpdate;
int lenkWinkel;
int pwmRange;
int beschl;
int bremse;
int geschw;
int geschw2;
int limit;
int maxLimit;
float base;
float exponent ;
unsigned long lastchange_Blinker;
unsigned long lastUpdate;
unsigned long maxUpdate;
int blinkerState = LOW;


ControllerPtr myControllers[BP32_MAX_GAMEPADS];
// this function to calculate the Speed

int vBerechnung(int forword, int backword) {
  // Richtungswechsel nur im stillstand
  
  if (speedMics == NULLPUNKT ){
    if(forword >0 && backword ==0){
      bewVorwaerts = true;
    }
    else if (forword ==0 && backword >0){
      bewVorwaerts = false;
    };
  };
  // SPEED berechnen

  if (bewVorwaerts){
    beschl = forword;
    bremse = backword;
    pwmRange = 270;
  }else{
    beschl = backword;
    bremse = forword;
    pwmRange = 330;
  };
 geschw2 = beschl;

  if(beschl > 1000 && bremse > 1000){
    geschw =  NULLPUNKT;
  }else{
    if(beschl == 0 && bremse == 0){
      geschw =  NULLPUNKT;
    }else{
    // Berechnung: Exponential mit Exponent 1-10 zur Basis 1.3 mit Verschiebung auf 0 über den Verfügbarem Range -> Somit 0-50 % curser = 0-20% Speed  
    // 1.2 => 050% curser = 25% speed
    beschl = int((((pow(1.3,(1.0+(float(beschl)/113.66)))-1.3)/12.486)*(pwmRange-maxLimit)));
    //Bremse 1023/2 = 0-512= = 1,5 Fache der Beschl.
    geschw =  (constrain((beschl - (bremse/2)),0,(pwmRange-maxLimit)) +50);
      if (bewVorwaerts){
          geschw = NULLPUNKT - geschw;
      }else{
          geschw = NULLPUNKT + geschw;
      };
    };
  };

  return geschw;// = 1800;
};



// This callback gets called any time a new gamepad is connected.
// Up to 4 gamepads can be connected at the same time.
void onConnectedController(ControllerPtr ctl) {
    maxUpdate = 0;
    bool foundEmptySlot = false;
    for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
        if (myControllers[i] == nullptr) {
            Serial.printf("CALLBACK: Controller is connected, index=%d\n", i);
            // Additionally, you can get certain gamepad properties like:
            // Model, VID, PID, BTAddr, flags, etc.
            ControllerProperties properties = ctl->getProperties();
            Serial.printf("Controller model: %s, VID=0x%04x, PID=0x%04x\n", ctl->getModelName().c_str(), properties.vendor_id,
                           properties.product_id);
              const uint8_t* addr =   properties.btaddr;         
            Serial.printf("BD Addr: %2X:%2X:%2X:%2X:%2X:%2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
            myControllers[i] = ctl;
            foundEmptySlot = true;
            break;
        }
    }

    if (!foundEmptySlot) {
        Serial.println("CALLBACK: Controller connected, but could not found empty slot");
    }
}

void onDisconnectedController(ControllerPtr ctl) {
    bool foundController = false;

    for (int i = 0; i < BP32_MAX_GAMEPADS; i++) {
        if (myControllers[i] == ctl) {
            Serial.printf("CALLBACK: Controller disconnected from index=%d\n", i);
            myControllers[i] = nullptr;
            foundController = true;
            break;
        }
    }

    if (!foundController) {
        Serial.println("CALLBACK: Controller disconnected, but not found in myControllers");
    }
}

void updatePwmSignale(ControllerPtr ctl) {

    //------ Control Servo   --------
  //speed = 0;
  //base = 0.0;
  speedMics = vBerechnung( (ctl->throttle()),(ctl->brake()));   //float( ctl->throttle()) / 5,69 ;
  pwmMotor.writeMicroseconds(speedMics);
  lenkWinkel =  NULLPUNKT + int((float(ctl->axisX())*-1.761));
  Serial.printf("Lenkwinkel: %d\n", lenkWinkel);
  pwmLenkung.writeMicroseconds(lenkWinkel);
}



void dumpGamepad(ControllerPtr ctl) {
    Serial.printf(
        "idx=%d, dpad: 0x%02x, buttons: 0x%04x, axis L: %4d, %4d, axis R: %4d, %4d, brake: %4d, throttle: %4d, "
        "misc: 0x%02x, gyro x:%6d y:%6d z:%6d, accel x:%6d y:%6d z:%6d\n",
        ctl->index(),        // Controller Index
        ctl->dpad(),         // D-pad
        ctl->buttons(),      // bitmask of pressed buttons
        ctl->axisX(),        // (-511 - 512) left X Axis
        ctl->axisY(),        // (-511 - 512) left Y axis
        ctl->axisRX(),       // (-511 - 512) right X axis
        ctl->axisRY(),       // (-511 - 512) right Y axis
        ctl->brake(),        // (0 - 1023): brake button
        ctl->throttle(),     // (0 - 1023): throttle (AKA gas) button
        ctl->miscButtons(),  // bitmask of pressed "misc" buttons
        ctl->gyroX(),        // Gyro X
        ctl->gyroY(),        // Gyro Y
        ctl->gyroZ(),        // Gyro Z
        ctl->accelX(),       // Accelerometer X
        ctl->accelY(),       // Accelerometer Y
        ctl->accelZ()        // Accelerometer Z
    );
    //------ Control Servo   --------
  //speed = 0;
  //base = 0.0;
  speedMics = vBerechnung( (ctl->throttle()),(ctl->brake()));   //float( ctl->throttle()) / 5,69 ;
  pwmMotor.writeMicroseconds(speedMics);
  lenkWinkel =  NULLPUNKT + int((float(ctl->axisX())*-1.761));
  Serial.printf("Lenkwinkel: %d\n", lenkWinkel);
  pwmLenkung.writeMicroseconds(lenkWinkel);
}



void processGamepad(ControllerPtr ctl) {
    // There are different ways to query whether a button is pressed.
    // By query each button individually:
    //  a(), b(), x(), y(), l1(), etc...
    if (ctl->a()) {
        maxLimit = 150;
//        colorIdx++;
    }

    if (ctl->y()) {
        // Turn on the 4 LED. Each bit represents one LED.
      maxLimit = 0;
    }
    if (ctl->x() /*|| getUpdate*/) {

        maxLimit = 110;

    }

    // Another way to query controller data is by getting the buttons() function.
    // See how the different "dump*" functions dump the Controller info.
    dumpGamepad(ctl);
    updatePwmSignale(ctl);
}


void processControllers() {
    for (auto myController : myControllers) {
        if (myController && myController->isConnected() ){
        Serial.printf("Call Update  1 %d\n",(millis() - lastUpdate));
          if( myController->hasData()) {
            lastUpdate = millis();
            if (myController->isGamepad()) {
              processGamepad(myController);
            } 
          }
          else {
            Serial.printf("Call Update 2 %d\n",(millis() - lastUpdate));
          }
        }
    }
}

// Arduino setup function. Runs in CPU 1
void setup() {
  //little FS
  



      bd_addr_t controller_addr;
    // Parse human-readable Bluetooth address.
    sscanf_bd_addr(controller_addr_string, controller_addr);
    // Notice that this address will be added in the Non-volatile-storage (NVS).
    // If the device reboots, the address will still be stored.
    //uni_bt_allowlist_add_addr(controller_addr);

    // Finally, enable the allowlist.
    //uni_bt_allowlist_set_enabled(true);
    Serial.begin(115200);
    Serial.printf("Firmware: %s\n", BP32.firmwareVersion());
    const uint8_t* addr = BP32.localBdAddress();
    Serial.printf("BD Addr: %2X:%2X:%2X:%2X:%2X:%2X\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);

    // Setup the Bluepad32 callbacks
    BP32.setup(&onConnectedController, &onDisconnectedController);

    // "forgetBluetoothKeys()" should be called when the user performs
    // a "device factory reset", or similar.
    // Calling "forgetBluetoothKeys" in setup() just as an example.
    // Forgetting Bluetooth keys prevents "paired" gamepads to reconnect.
    // But it might also fix some connection / re-connection issues.
    BP32.forgetBluetoothKeys();

    // Enables mouse / touchpad support for gamepads that support them.
    // When enabled, controllers like DualSense and DualShock4 generate two connected devices:
    // - First one: the gamepad
    // - Second one, which is a "virtual device", is a mouse.
    // By default, it is disabled.
    BP32.enableVirtualDevice(false);

    //pwmMotor.setPeriodHertz(50);    // standard 50 hz servo
    pwmMotor.writeMicroseconds(NULLPUNKT);
    pwmLenkung.writeMicroseconds(NULLPUNKT);
    pwmMotor.attach(MOTORREGL_PIN);  // define pin 26 to PWM
    pwmLenkung.attach(LENKSERVO_PIN);  // define pin 26 to PWM
    maxUpdate = 0;
    speedMics =  NULLPUNKT;
    
    pwmMotor.writeMicroseconds(NULLPUNKT);
    pwmLenkung.writeMicroseconds(NULLPUNKT);
    //LED PINS
    pinMode(BLINKER_LINKS_PIN, OUTPUT);// pin 7
    digitalWrite(BLINKER_LINKS_PIN, HIGH);
  lastchange_Blinker = millis();


}

// Arduino loop function. Runs in CPU 1.
void loop() {
    // This call fetches all the controllers' data.
    // Call this function in your main loop.
    //processControllers();

    if ((millis()-lastchange_Blinker) > BLINKER_MS){
        lastchange_Blinker = millis();
          if (blinkerState == LOW) {
              blinkerState = HIGH;
          } else {
              blinkerState = LOW;
          };
          Serial.printf("Wechsel Blinkerstate!\n");
      digitalWrite(BLINKER_LINKS_PIN, blinkerState);
    }




    bool dataUpdated = BP32.update();
    if (dataUpdated){//*
      processControllers();

      //Serial.printf("Maximal Update time 3 %d\n",(millis() - lastUpdate));
    }else{
      ///
      if (speedMics != NULLPUNKT){
        
        //Limit umschalten
        if (geschw2 == 1023){
            limit = 2000;
        } else {
            limit = 650;
        }
        //getUpdate = false;
        if((millis() - lastUpdate) > limit ){
          //getUpdate = true;
          if(speedMics > NULLPUNKT){
            speedMics -= SPEEDDOWN;
          }else{
            speedMics += SPEEDDOWN;
          };

          if (((NULLPUNKT - SPEEDDOWN) <= speedMics) && (speedMics <= (NULLPUNKT + SPEEDDOWN))){
            speedMics = NULLPUNKT;
          };
          ///
          Serial.printf("Bremsung einleiten | Beschleunigung: %d Zeit: %d\n",geschw2,(millis() - lastUpdate));
          Serial.printf("Bremsung einleiten | Beschleunigung: %d Zeit: %d\n",geschw2,(millis() - lastUpdate));

          pwmMotor.writeMicroseconds(speedMics);
        }
      }//if (speedMics != NULLPUNKT)
    }/*  // ELSE (dataUpdated)
    Serial.printf("NoUpdate - Speed: %d  Time %d  \n",speedMics,(millis() - lastUpdate));
    speedMics= speedMics + 20;
    // 1720-2000 =  Rückwart
    // 1300-1520 = Vorwärts
    if(speedMics > 2000){
      speedMics = 1620;
      pwmMotor.writeMicroseconds(speedMics);
      delay(2000);
      speedMics = 1200;
      
    };



    pwmMotor.writeMicroseconds(speedMics);
    pwmLenkung.writeMicroseconds(1600);
    */
    // The main loop must have some kind of "yield to lower priority task" event.
    // Otherwise, the watchdog will get triggered.
    // If your main loop doesn't have one, just add a simple `vTaskDelay(1)`.
    // Detailed info here:
    // https://stackoverflow.com/questions/66278271/task-watchdog-got-triggered-the-tasks-did-not-reset-the-watchdog-in-time

    //vTaskDelay(1);
    delay(60);
}

Guten Morgen :grin: