Fahrzeug mit PS4 Controller steuern bei Signal Abbruch

Moin Moin,

Projektbeschreibung: Fahrzeug wird über zwei Hydraulisch einzelnd angetriebene Ketten bewegt.
Drehzahl wird über 2 Frequenzumrichter bestimmt. (Wie ein Panzer)

Gesteuert soll es über einen PS4 Controller/bluetooth werden.

Als Empfänger wird ein Arduino Uno mit USBHostschield sowie bluetooth Dongel verwendet.

Verbindung zwischen Arduino und PS4 controller konnte hergestellt werden.
Habe erstmal LED lampen leuchten lassen um es zu testen.

Problem: Wenn die Verbindung aufgrund von zu großer Entfernung abbricht bleibt die LED an, dies ist in sofern problematisch als das mein kleiner Panzer dann abdüsen würde. Ich hätte gerne das im Falle eines Verbindungsabbruchs der Panzer stehen bleibt. Habt ihr da eine Idee wie ich dies realisieren könnte?

Wenn mir da jemand weiterhelfen könnte würde ich mich sehr freuen.
Unter umständen bin ich ja auch auf einem völlig falschen Weg.

/*
Ansteuern eines Arduino mit PS4 Controler über USB Host shield
 */

#include <PS4BT.h>
#include <usbhub.h>

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

USB Usb;
//USBHub Hub1(&Usb); // Für dongel mit HUB
BTD Btd(&Usb); // Bluetooth dongel Hub

/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
//PS4BT PS4(&Btd, PAIR);

// After that you can simply create the instance like so and then press the PS button on the device
PS4BT PS4(&Btd);

bool printAngle, printTouch;
uint8_t oldL2Value, oldR2Value;

void setup() {
  pinMode(3, OUTPUT); //LED rot
  pinMode(4, OUTPUT); //LED blau
  pinMode(5, OUTPUT); //LED grün
  pinMode(6, OUTPUT); //LED gelb
  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); // Halt
  }
  Serial.print(F("\r\nPS4 Bluetooth Library Started"));
}
void loop() {
  Usb.Task();

  if (PS4.connected()) { // Nur bewegen wenn verbunden
    if (PS4.getAnalogHat(LeftHatX) > 137 || PS4.getAnalogHat(LeftHatX) < 117 || PS4.getAnalogHat(LeftHatY) > 137 || PS4.getAnalogHat(LeftHatY) < 117 || PS4.getAnalogHat(RightHatX) > 137 || PS4.getAnalogHat(RightHatX) < 117 || PS4.getAnalogHat(RightHatY) > 137 || PS4.getAnalogHat(RightHatY) < 117) {
      Serial.print(F("\r\nLeftHatX: "));
      Serial.print(PS4.getAnalogHat(LeftHatX));
      Serial.print(F("\tLeftHatY: "));
      Serial.print(PS4.getAnalogHat(LeftHatY));
      Serial.print(F("\tRightHatX: "));
      Serial.print(PS4.getAnalogHat(RightHatX));
      Serial.print(F("\tRightHatY: "));
      Serial.print(PS4.getAnalogHat(RightHatY));
    }
    /*Simulation der Bewegungen des Fahrzeugs durch LED´s */ 
  if (PS4.getAnalogHat(LeftHatY) > 137){ //Linker Reifen rückwärts
      digitalWrite(3, HIGH); // Rote LED an
    }
   else if (PS4.getAnalogHat(LeftHatY) < 137) {
      digitalWrite(3, LOW); // Rote LED aus
    }
    if (PS4.getAnalogHat(LeftHatY) < 117){ //Linker Reifen vorwärts
      digitalWrite(4, HIGH); // Blaue LED an
    }
   else if (PS4.getAnalogHat(LeftHatY) > 117) {
      digitalWrite(4, LOW); // Blaue LED aus
      }
if (PS4.getAnalogHat(RightHatY) > 137){ //Rechter Reifen rückwärts
      digitalWrite(5, HIGH); // Grün LED an
    }
   else if (PS4.getAnalogHat(RightHatY) < 137) {
      digitalWrite(5, LOW); // Grün LED aus
}
   if (PS4.getAnalogHat(RightHatY) < 117){ //Rechter Reifen vorwärts
      digitalWrite(6, HIGH); // Gelb LED an
    }
   else if (PS4.getAnalogHat(RightHatY) > 117) {
      digitalWrite(6, LOW); // Gelb LED aus
      }
      
    /*Wenn PS button auf controller betätigt wird trennt sich die Verbindung
      und die Ausgänge werden auf 0 gesetzt*/
    if (PS4.getButtonClick(PS)) { 
      Serial.print(F("\r\nPS"));
      PS4.disconnect();
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5,LOW);
      digitalWrite(6,LOW);
    }
    
          }
        }

Du musst festlegen, dass mindestens aller x Sekunden ein (Steuer-)Signal vom Controller kommt. Wenn eins kommt, den letzten Zeitpunkt merken (millis()) wenn die aktuellen millis() - gemerkte millis > x Sekunden ist --> abschalten

Gruß Tommy

Hallo Tommy,

Danke für deine schnelle Antwort!

Dein Lösungsweg ist elegant und einfach, dankeschön.

Nun ist es so das ich ungefähr bei lvl null in diesem Gebiet bin, daher stelle ich womöglich recht offensichtliche fragen.

Was Könnte man als Signal vom Controller nehmen? Sendet dieser zufälligerweise sowieso in einem Abstand X Informationen wo ich etwas abgreifen kann oder macht er dies nur wenn sich ein Zustand am Controller ändert?

Beim Schreiben merke ich das ich mich etwas mit dem BT Protokoll beschäftigen sollte.

Spontan würde mir das gyroskop einfallen als Ständiges Signal.

Gruß Gunnar

Da ich keinen PS2-Controller habe, kann ich nichts dazu sagen. Es wäre aber evtl. eine Möglichkeit.

Gruß Tommy

Besten dank Tommy, ich werde es mal ausprobieren.
Bei Erfolg werde ich berichten.

Das wäre schön - bei Mißerfolg auch, evtl. hat dann eion Anderer noch eine Idee.

Gruß Tommy

Hmm… du könntest dem if (PS4.connected()) einen else Zweig verpassen und schauen, ob as schon reicht.

Moin Moin Rintin,

danke für deine Beteiligung, dieses Ansatz habe ich auch versucht zu verfolgen.

USB.Task() macht ja wenn ich es richtig verstanden habe eine Status Abfrage am PS4 Controller.

Bei meinem ersten Versuch hat dies leider nicht funktioniert. Die LED leuchtete trotz Verbindungsabbruch
Heute abend werde ich es nocheinmal ausprobieren. Könnte ja sein das ich da einen Fehler gemacht habe.

Mfg Gunnar

Kurzes Update

Einfach mit “else” geht es nicht, bei Verbindungsunterbrechnung durch zu große Entfernung denkt das Board es würde den letzten Befehl des Controllers weiterhin bekommen.

/*
Ansteuern eines Arduino mit PS4 Controler über USB Host shield
 */

#include <PS4BT.h> //einbinden der PS4BT.h Bibilliothek
#include <usbhub.h> //einbinden der usbhub.h Bibilliothek  

// Satisfy the IDE, which needs to see the include statment in the ino too.
#ifdef dobogusinclude
#include <spi4teensy3.h>
#endif
#include <SPI.h>

USB Usb;
//USBHub Hub1(&Usb); // Für dongel mit HUB
BTD Btd(&Usb); // Bluetooth dongel Hub

/* You can create the instance of the PS4BT class in two ways */
// This will start an inquiry and then pair with the PS4 controller - you only have to do this once
// You will need to hold down the PS and Share button at the same time, the PS4 controller will then start to blink rapidly indicating that it is in pairing mode
//PS4BT PS4(&Btd, PAIR);

// After that you can simply create the instance like so and then press the PS button on the device
PS4BT PS4(&Btd);

bool printAngle, printTouch;
uint8_t oldL2Value, oldR2Value;

void setup() {
  pinMode(3, OUTPUT); //LED rot
  pinMode(4, OUTPUT); //LED blau
  pinMode(5, OUTPUT); //LED grün
  pinMode(6, OUTPUT); //LED gelb
  Serial.begin(115200);
#if !defined(__MIPSEL__)
  while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
  if (Usb.Init() == -1) {
    Serial.print(F("\r\nOSC did not start"));
    while (1); // Halt
  }
  Serial.print(F("\r\nPS4 Bluetooth Library Started"));
}
void loop() {
  Usb.Task(); //abfragen von verbundenen USB geräten nach ihrem Status

  if (PS4.connected()) { // Nur bewegen wenn verbunden
    if (PS4.getAnalogHat(LeftHatX) > 137 || PS4.getAnalogHat(LeftHatX) < 117 || PS4.getAnalogHat(LeftHatY) > 137 || PS4.getAnalogHat(LeftHatY) < 117 || PS4.getAnalogHat(RightHatX) > 137 || PS4.getAnalogHat(RightHatX) < 117 || PS4.getAnalogHat(RightHatY) > 137 || PS4.getAnalogHat(RightHatY) < 117) {
      Serial.print(F("\r\nLeftHatX: "));
      Serial.print(PS4.getAnalogHat(LeftHatX));
      Serial.print(F("\tLeftHatY: "));
      Serial.print(PS4.getAnalogHat(LeftHatY));
      Serial.print(F("\tRightHatX: "));
      Serial.print(PS4.getAnalogHat(RightHatX));
      Serial.print(F("\tRightHatY: "));
      Serial.print(PS4.getAnalogHat(RightHatY));
    }
    /*Simulation der Bewegungen des Fahrzeugs durch LED´s */ 
  if (PS4.getAnalogHat(LeftHatY) > 137){ //Linker Reifen rückwärts
      digitalWrite(3, HIGH); // Rote LED an
    }
   else if (PS4.getAnalogHat(LeftHatY) < 137) {
      digitalWrite(3, LOW); // Rote LED aus
    }
    if (PS4.getAnalogHat(LeftHatY) < 117){ //Linker Reifen vorwärts
      digitalWrite(4, HIGH); // Blaue LED an
    }
   else if (PS4.getAnalogHat(LeftHatY) > 117) {
      digitalWrite(4, LOW); // Blaue LED aus
      }
if (PS4.getAnalogHat(RightHatY) > 137){ //Rechter Reifen rückwärts
      digitalWrite(5, HIGH); // Grün LED an
    }
   else if (PS4.getAnalogHat(RightHatY) < 137) {
      digitalWrite(5, LOW); // Grün LED aus
}
   if (PS4.getAnalogHat(RightHatY) < 117){ //Rechter Reifen vorwärts
      digitalWrite(6, HIGH); // Gelb LED an
    }
   else if (PS4.getAnalogHat(RightHatY) > 117) {
      digitalWrite(6, LOW); // Gelb LED aus
      }
      
    /*Wenn PS button auf controller betätigt wird trennt sich die Verbindung
      */
    if (PS4.getButtonClick(PS)) { 
      Serial.print(F("\r\nPS"));
      PS4.disconnect();
      
    }
    
          }
          else { // ist PS4 nicht verbunden werden alle Ausgänge auf 0 gesetzt
            digitalWrite(3, LOW);
            digitalWrite(4, LOW);
            digitalWrite(5,LOW);
            digitalWrite(6,LOW);
          }
          }

Neue Idee: Ich sende den Befehl die Farbe der LED am controller zu ändern. Danach mache ich eine Abfrage ob sich diese geändert hat. Ist dem nicht so wird abgebrochen.
Muss nurnoch überprüfen ob der Controller ein Feedback über die Farbe der led gibt.

mfg Gunnar