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