TCP Verbindung 2 Adafruit WIFI CC3000 Shields

Guten Morgen zusammen,

Nachdem ich jetzt sehr lange einen Bogen um das Thema WIFI gemacht habe, muss es jetzt einfach sein. Und wie zu erwarten, wirklich kein einfaches Thema. Ich hoffe Ihr könnt mir ein wenig helfen.

Wie ist der Stand:

  • Ich habe ein kleine Modellboot, mit dem Mega, CC3000 Wifi Shield von Adafruit, ein paar Servos, ner IMU und GPS. (Also somit der Empfänger)

  • Auf der anderen Seite nen Uno, ebenfalls einen CC3000, sowie einen Joystick, von dem im Moment erstmal nur 2 Achsen analog eingelesen werden. Also 2 Int Werte. (Sender)

Was passiert „an Bord“? Die IMU+GPS+ Servos (welche 4 Flügel unter Wasser am Rumpf ansteuern) steuern über einen internen Algorithmus die Lage des Bootes abhängig von der der Geschwindigkeit und Lenkeinschlag. (Der Loop muss also immer laufen)

Bisher habe ich den Joystick zu testzwecken direkt am Boot an gestöpselt. Es funktioniert auch alles besten.

Nun ist das mit dem Kabel aber keine Lösung und somit muss eine Drahtlose Übertragung her. 

Und da habe ich mich jetzt die letzten Tage beschäftig und stelle fest, dass mir zum einen einfach die Kenntnisse etwas fehlen, zum anderen, wieder mal mein Englisch mir im Wege steht…  Vor allem diese beiden Shields von Adafruit…

Was habe ich bisher:

  • Beide Shields konnte ich mit einer festen IP (192.168.1.2 sowie 3) an einem AP anmelden.
  • Ich habe das Beispiel ECHOServer laufen lassen und konnte von meinem PC aus über einen TCP Packet Sender zeichen an den Server senden. (Code anbei)
  • Ich habe auf der anderen Seite eine Client aufmachen können (Code anbei), der sich mit dem Server verbindet. Leider sendet er meine Zeichen nicht. Und hier check ich noch nicht, wie das aussehen muss.

Diesen Teil führe ich hier nochmal explizit auf.

ECHO SERVER:

/***************************************************
  Adafruit CC3000 Breakout/Shield TCP Echo Server
    
  This is a simple implementation of the echo 
  protocol, RFC 862 http://tools.ietf.org/html/rfc862 , 
  for the Arduino platform and Adafruit CC3000 breakout
  or shield.  This sketch will create a TCP server that 
  listens by default on port 7 and echos back any data
  received.  Up to 3 clients can be connected concurrently
  to the server.  This sketch is meant as an example of how 
  to write a simple server with the Arduino and CC3000.

  See the CC3000 tutorial on Adafruit's learning system
  for more information on setting up and using the
  CC3000:
    http://learn.adafruit.com/adafruit-cc3000-wifi  
    
  Requirements:
  
 
           
 
 ****************************************************/
#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   2  // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  3
#define ADAFRUIT_CC3000_CS    4
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed

#define WLAN_SSID       "Sky-Net"           // cannot be longer than 32 characters!
#define WLAN_PASS       "myPassword"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define LISTEN_PORT           7    // What TCP port to listen on for connections.  The echo protocol uses port 7.

Adafruit_CC3000_Server echoServer(LISTEN_PORT);

void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Hello, CC3000!\n")); 

  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
  
  /* Initialise the module */
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
  
  Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }
   
  Serial.println(F("Connected!"));
  
  Serial.println(F("Request DHCP"));
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }  

  /* Display the IP address DNS, Gateway, etc. */  
  while (! displayConnectionDetails()) {
    delay(1000);
  }


  
  // Start listening for connections
  echoServer.begin();
  
  Serial.println(F("Listening for connections..."));
}

void loop(void)
{
  // Try to get a client which is connected.
  Adafruit_CC3000_ClientRef client = echoServer.available();
  if (client) {
     // Check if there is data available to read.
     if (client.available() > 0) {
       // Read a byte and write it to all clients.
       uint8_t ch = client.read();
       client.write(ch);
     }
  }
}

/**************************************************************************/
/*!
    @brief  Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
  
  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!\r\n"));
    return false;
  }
  else
  {
    Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

2.ter Teil:

CLIENT:

#include <Adafruit_CC3000.h>
#include <SPI.h>
#include "utility/debug.h"
#include "utility/socket.h"

// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ   3 // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10

Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); // you can change this clock speed

#define WLAN_SSID       "XRay"           
#define WLAN_PASS       "tiger234"
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

/////

  uint32_t serverIPAddr = cc3000.IP2U32(192, 168, 1, 3);
  uint32_t serverPortNumber = 7;

/////


 Adafruit_CC3000_Client client; 
  


//08:00:28:58:D8:D9

void setup(void)
{
  Serial.begin(115200);
  Serial.println(F("Hello, CC3000!\n")); 
  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
  /* Initialise the module */
  Serial.println(F("\nInitializing..."));
  if (!cc3000.begin())
    {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
    }
  
  Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) 
    {
    Serial.println(F("Failed!"));
    while(1);
    }
   
  Serial.println(F("Connected!"));
  
 

  /* Eigene IP usw. anzeigen  */  
  while (! displayConnectionDetails()) 
    {
    delay(1000);
    }
    
    Serial.println("Remote IP:")
    Serial.println(F("\nIP Addr: ")); cc3000.printIPdotsRev(serverIPAddr);
    Serial.println(" ");

}






void loop(void)
{
  
  Adafruit_CC3000_Client client_X = cc3000.connectTCP(serverIPAddr, serverPortNumber); // connect to the server
  if (client_X.connected()) 
  

  {
    Serial.println("connection successfull!!!!! ");
    
    delay(1000);
    
    
    client_X.write(1);
    delay(2000);
    client_X.print("2");

    
  }
  
}







/**************************************************************************/
/*!
    @brief  Tries to read the IP address and other connection details
*/
/**************************************************************************/
bool displayConnectionDetails(void)
{
  uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
  
  if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
  {
    Serial.println(F("Unable to retrieve the IP Address!\r\n"));
    return false;
  }
  else
  {
    Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
    Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
    Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
    Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
    Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
    Serial.println();
    return true;
  }
}

Teil im Client, der wohl so nicht richtig ist:

void loop(void)
{
  
  Adafruit_CC3000_Client client_X = cc3000.connectTCP(serverIPAddr, serverPortNumber); // connect to the server
  if (client_X.connected()) 
  

  {
    Serial.println("connection successfull!!!!! ");
    
    delay(1000);
    
    
    client_X.write(1);  //Test 
    delay(2000);
    client_X.print("2");

    
  }
  
}

Bis zum Teil connection successfull!!!!! läuft es, aber er sendet keine Daten.
Dazu kommt, dass er vielleicht 2,3 mal durch den Loop läuft sich dann der Server verabschiedet, also aufhängt.

Mir ist überhaupt nicht klar, wie ich jetzt meine Daten da rüber buxiere...

Vielen Dank schon mal, für die Hilfe, ich weiß, das ist ein ziemlich langer Post.

Gruß Michl

Um was für Entfernungen geht es denn? Und was für Geschwindigkeiten?

Mit Wifi TCP würde ich das eher nicht lösen.

Wäre wohl eher was für UDP. Wenn mal eine Nachricht nicht ankommt ist das nicht so schlimm, den Joystick hast du ja dann immer noch betätigt bis dein Befehl ausgeführt wird.

Gruß

Ja, UDP wäre auch ok. Wenn die Nachricht mal nicht ankommt, auch nicht so schlimm. Was ich ja trotzdem noch einbauen kann, ist eine Checksumme oder so, dass ein fehlerhaftes Datenpaket nicht verwendet wird.

Was halt nicht passieren sollte, ist, dass das Boot dann z.B. einfach davon rast, weil es "vollgas" verstanden hat... Dann ist es unter umständen weg oder geht unter. Da stecken mittlerweile 4 Monate arbeit drin.

Die Distanz ist erstmal kein Problem. Wenn dann teste ich nur in Ufernähe und im Moment erstmal nur in einem kleinen Pool, bis wirklich alles korrekt funktioniert. Ich habe die Shield Variante mit externer Antenne. An den AP sowie das Boot habe ich eine ziemlich große Antenne dran geschraubt. Ich denke, 100 Meter sollten auf offenem Gelände, Was ja ein See meist ist, locker gehen.

Also UDP wäre absolut kein Problem denke ich, vor allem ist es glaub ich stabieler. Die bisherigen TCP Versuche hängen doch recht of auf, immer zu einem anderen Zeitpunkt. Mal läufts 1 mal mal 10 mal...

Ich dachte eher, dass du nur eine dedizierte Funkstrecke nehmen solltest, kein Wifi, und erst recht nicht über einen AP. Auch würde ich für RC Boote nicht unbedingt 2,4 Ghz nehmen.

Eher 433 oder so, und da eine transparente serielle Verbindung. Module gibt es da bestimmt schon fertig.

und dann die Werte dauernd schicken, und sobald am Empfänger nix oder falsche Checksum ankommt, sofort in Failsafe.

Schau dir mal das an
http://www.seeedstudio.com/depot/433Mhz-Wireless-Serial-Transceiver-Module-1-Kilometer-p-1733.html

Ja, ich versteh was Du meinst. Aber ich will das schon über WIFI lösen.

Warum:

  • Zum einen ist das Boot nur eines von mehreren Projekten, ich mach noch nebenzu ein bissl was für die Uni, und da wollen sie mehrere Roboter mit WIFI in einem Netzt steuern. Soll heißen, ein AP und alle melden sich da an.

  • Des weiteren ist die Fernbedienung nur eine Zwischenlösung. Ich will über kurz oder lang so eine Lösung verwirklichen. ROV Cockpit (Im Moment acker ich mich durch verschieden VB Bücher... )

  • Dazu kommt, das ich das Thema einfach mal verstehen will. Und mich da wirklich auführlich einarbeiten.

Gruß Michl

ok, dann sieht es wieder anders aus. Ich dachte, das Boot sei das Ziel, aber bei dir ist der Weg das Ziel :wink:

Dann würde ich auf alle Fälle UDP einsetzen, aber trotzdem mit FailSafe im Boot, dass von nicht vorhandenen oder unsinnigen Daten ausgelöst wird. Rückkanal ist dann nur interessant, wenn du Rückmeldung über ggf. Failsafe Status, Connects (z.B. "Boot ready") oder Telemetrie haben willst.

FailSafe Reaktion: Motor aus, Empfangsantenne teleskopisch 1 m nach oben fahren ;D ;D

Moin zusammen.

Danke für die Antwort, dann ist die Frage schon mal geklärt. VIA UDP! :slight_smile:

Was meinen Fail Safe betrifft visiere ich eine noch elegantere Lösung an. :wink:

Mein Boot besitzt ja eine IMU mit Kompass (Pololu ALTIMU10),GPS und nen SD Leser. Damit habe ich schon recht viel gemacht. Aus beiden kann ich ja meine Positionrelativ genau bestimmen. Beim Start, also da wo ich das Ding in Wasser setzte (und später die Roboter, welche ja auch noch Ultraschalls haben) speichere ich die Position. Aus den Daten der IMU errechne ich die ständige Position mit Hilfe der Koppel- Navigation. (Also Vektoren addieren) Diese noch mit den Daten des GPS abgleichen. (Da muss ich noch über Versuche austüfteln, was genauer ist und wie ich das dann zusammen wurstel.) Bei Signal Verlust soll das Boot einfach mit sehr geringer Fahrt an die Startposition zurück fahren. Muss ja nur wieder in meine Nähe kommen um das Signal wieder zu bekommen. Aber soweit bin ich ja noch nicht.

Ich habe mir den Arduino Teil von dem RoV Cockpit (siehe Link weiter oben) mal angesehen, und glaube, dass es genau das ist, was ich brauche. Leider ist mir noch nicht ganz klar, was der da eigentlich genau mach. Evtl. könnt Ihr das ja mal kurz ansehen und mir sagen, was ich überhaupt brauche für den Anfang. Also meine beiden Integer werte. Telemetrie brauche ich (später) auf jeden Fall. Vor allem der Ladestand des Akkus wäre doch sehr wichtig. Weil, wenn der auf dem See die grätsche macht, hilft mir der beste Fail Safe nix. :wink: Also wie bei folgenden Beispiel. Der meldet auch einiges zurück.

Also fangen wir mal klein an: 2 Integer Werte sollen vom Sender-Arduino zum Boot und einer vom Boot-Arduino zum Sender. (Für den Sender habe ich noch ein kleines Display hier rum liegen, was da dann noch dran kommt.)

Vielen Dank!
Gruß Michl

#include <stdio.h>       // Ein- Ausgabe Bibliothek
#include <SPI.h>         // SPI Bibliothek (Serial Peripheral Interface für die Kommunikation mit der Ethernet-Baustein)
#include <Ethernet.h>    // Arduiono Ethernet Library 
#include <EthernetUdp.h> // UDP library von: bjoern@cs.stanford.edu 12/30/2008


// MAC Adresse. Allenfalls anpassen.
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

// IP Adresse. Bitte Adresse allenfalls abhängig vom Netzwerk anpassen
IPAddress ip(192, 168, 1, 177);

// lokaler Port = remote Port
unsigned int Port = 1100; 

// Ethernet Instanz zum senden und empfangen von UDP Packeten
EthernetUDP Udp;




// Hilfsvariablen 
int tiefe = 0;
int neigung = 0;
int kippwinkel = 0;
int richtung = 0;

// Buffer zum Empfangen der UDP Daten
char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; 



void setup() 

{
  // Starte Ehternet und UDP Empfang
  Ethernet.begin(mac,ip);
  Udp.begin(Port);

// Falls für fehleranalyse benötigt, entkommentieren
//  Serial.begin(19200);

}

// Antwort bzw. Key und Value als String an den Client senden (Valueübergabe als Integer)
void SendAcknowledge(char key[], int value) {
   
   char ReplayBuffer[25];
   
   sprintf(ReplayBuffer,key,value);
   
   Udp.beginPacket(Udp.remoteIP(), Port); 
   Udp.write(ReplayBuffer);
   Udp.endPacket();
   
//   Serial.println(Udp.remotePort());

   
}

// Antwort bzw. Key und Value als String an den Client senden (Valueübergabe als Character Array)
void SendAcknowledge(char key[], char value[]) {
   
   char ReplayBuffer[25];
   
   sprintf(ReplayBuffer,key,value);
   Udp.beginPacket(Udp.remoteIP(), Port);    
   Udp.write(ReplayBuffer);
   Udp.endPacket();
   
//   Serial.println(Udp.remotePort());
}






void loop() 

{
  
   // UDP Pakete laufend lesen, auswerten und Rückmeldungen simulieren
   ReadUdp();
   
}

Unterprogramm Read UDP im Loop

(Hat nicht mehr in einen Post gepasst)

// =======================================================================
// Routine welches die UDP Pakete empfängt und auswertet
// =======================================================================
void ReadUdp() 
{
  
  // Falls Daten verfügbar sind, dann UDP Packet lesen
  int packetSize = Udp.parsePacket();
  if(packetSize)
  {
    
    // Empfange Zeichen in packetBufffer schreiben.
    // Der Inhalt eines UDP Packets setzt sich aus Key, Wert und Checksumme zusammen
    Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
    
    // Checksumme bilden und mit Empfangener Checksumme vergleichen
    // Oder anders gesagt - prüfen, ob die Daten korrekt angekommen sind.
    char checkSum = packetBuffer[0] ^ packetBuffer[1];
    if (checkSum == packetBuffer[2]) { 

// ======================================================================
// Ausgabe auf Seriel-Port z.B für Fehleranalyse. Allenfalls entkommentieren 
// ======================================================================
//    Serial.print("Received packet of size ");
//    Serial.println(packetSize);
//    Serial.print("From ");
//    IPAddress remote = Udp.remoteIP();
//    for (int i =0; i < 4; i++)
//    {
//      Serial.print(remote[i], DEC);
//      if (i < 3)
//      {
//        Serial.print(".");
//      }
//    }
//    Serial.print(", port ");
//    Serial.println(Udp.remotePort());
//    Serial.println("Contents:");
//    Serial.print("Key : ");
//    Serial.print(packetBuffer[0], DEC);
//    Serial.print(" Value : ");
//    Serial.print(packetBuffer[1], DEC);
//    Serial.print(" Checksum : ");
//    Serial.println(packetBuffer[2], DEC);


   // Kommandos auswerten und entsprechende Rückmeldung geben
   switch (packetBuffer[0]) {
    
    // ================================================================================ 
    // ================ Dimmer-Stellungen/Kommandosc ==================================
    //
    // Wenn Dimmer-Stellung zur Kamera Neigung, dann Meldung mit Wert zurücksenden
    case 12: 
        SendAcknowledge("Cam Track: %d",packetBuffer[1] & 0xff );  
    break;  
    // Dimmer-Stellunng zu Kamera links/rechts, dann Meldung mit Wert zurücksenden  
    case 13: 
        SendAcknowledge("DIM1: %d",packetBuffer[1] & 0xff );  
    break;
    // Dimmer-Stellung zu Schalter S1, dann Meldung mit Wert zurücksenden    
    case 23: 
        SendAcknowledge("DIM2: %d",packetBuffer[1] & 0xff );  
    break;  
    // Dimmer zu Schalter S2, dann Meldung mit Wert zurücksenden 
    case 33: 
        SendAcknowledge("DIM3: %d",packetBuffer[1] & 0xff );  
    break; 
    // Dimmer zu Schalter S3, dann Meldung mit Wert zurücksenden  
    case 43: 
        SendAcknowledge("DIM4: %d",packetBuffer[1] & 0xff );  
    break;  
    // Dimmer zu Schalter S4, dann Meldung mit Wert zurücksenden 
    case 53: 
        SendAcknowledge("DIM5: %d",packetBuffer[1] & 0xff );  
    break;  
    // Dimmer zu Schalter S5, dann Meldung mit Wert zurücksenden 
    case 63: 
        SendAcknowledge("DIM6: %d",packetBuffer[1] & 0xff );  
    break;    
    
    // =============================================================================
    // ================ Schalter Stellungen/Kommandos ==============================
    //    
    // Schalten Licht Ein/Aus
    case 11:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S0;%d", 1); } else  { SendAcknowledge("#S0;%d", 0); }
    break;
    // Schalter S1 Ein/Aus
    case 21:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S1;%d", 1); } else  { SendAcknowledge("#S1;%d", 0); } 
    break;
    // Schalter S2 Ein/Aus
    case 31:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S2;%d", 1); } else  { SendAcknowledge("#S2;%d", 0); }
    break;
    // Schalter S3 Ein/Aus
    case 41:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S3;%d", 1); } else  { SendAcknowledge("#S3;%d", 0); }
    break;
    // Schalter S4 Ein/Aus
    case 51:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S4;%d", 1); } else  { SendAcknowledge("#S4;%d", 0); }
    break;
    // Schalter S5 Ein/Aus
    case 61:
      if (packetBuffer[1] == 1) { SendAcknowledge("#S5;%d", 1); } else  { SendAcknowledge("#S5;%d", 0); }
    break;
    
 
  
}

passt immer noch nicht...

2.ter teil von UDP Read:

  // ============================================================================
    // ================ Button Kommandos vom Client ===============================
    //    
    // Tastatur-Matrix zurückmelden
    case 100:  
        switch (packetBuffer[1]) {   
          case 10: 
              SendAcknowledge("Button: %s", "Links oben");  
          break;
          case 15:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 20:
               SendAcknowledge("Button: %s", "Mitte oben"); 
          break;
          case 25:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 30:
               SendAcknowledge("Button: %s", "Rechts oben");
          break;
          case 35:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 40:
              SendAcknowledge("Button: %s", "Links mitte");
          break;
          case 45:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 50:
               SendAcknowledge("Button: %s", "Mitte mitte");
          break;
          case 55:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 60:
               SendAcknowledge("Button: %s", "Rechts mitte");
          break;
          case 65:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 70:
               SendAcknowledge("Button: %s", "Links unten");
          break;
          case 75:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 80:
               SendAcknowledge("Button: %s", "Mitte unten");
          break;
          case 85:
               SendAcknowledge("Button: %s", "Stopp");
          break;
          case 90:
               SendAcknowledge("Button: %s", "Rechts unten");
          break;  
          case 95:
               SendAcknowledge("Button: %s", "Stopp");
          break;      
          case 100:
               SendAcknowledge("Button: %s", "Sinken");
          break;
          case 105:
               SendAcknowledge("Button: %s", "Sinken stopp");
          break;
          case 110:
               SendAcknowledge("Button: %s", "Steigen");
          break;
          case 115:
               SendAcknowledge("Button: %s", "Steigen stopp");
          break;
        }           
    break;
    
    // ============================================================================
    // ================ Abrufkommando für Analogwerte =============================
    //   
    case 120:
       if (packetBuffer[1] == 127)
    {
       // Analogwerte zurückmelden (in der Simulation als Konstante)
       SendAcknowledge("#AC0;%d", 6);
       SendAcknowledge("#AC1;%d", 7);
       SendAcknowledge("#AC2;%d", 64);
       SendAcknowledge("#AC3;%d", 20);
       SendAcknowledge("#AC4;%d", 12);
    }
    break;
    
    // ===========================================================================
    // ================ Initialisierungskommando vom Client ======================
    // Damit können Schalterzustände auf einen definierten Zustand gebracht und 
    // zurückgemeldet werden
    case 127: 
       if (packetBuffer[1] == 1)
    {
       SendAcknowledge("#S0;%d", 0);
       SendAcknowledge("#S1;%d", 0);
       SendAcknowledge("#S2;%d", 0);
       SendAcknowledge("#S3;%d", 0);
       SendAcknowledge("#S4;%d", 0);
       SendAcknowledge("#S5;%d", 0);
       SendAcknowledge("#DIM1;%d", 127);
       SendAcknowledge("#DIM2;%d", 127);
       SendAcknowledge("#DIM3;%d", 127);
       SendAcknowledge("#DIM4;%d", 127);
       SendAcknowledge("#DIM5;%d", 127);
       SendAcknowledge("#DIM6;%d", 127);
       SendAcknowledge("#TRACK;%d", 127);
    }
    break;
    
    // ============================================================================
    // ======== Joy-Stick Button-Kommandos auswerten und zurückmelden =============
    // 
    case 160:
       switch (packetBuffer[1]) {      
           case 0:
               SendAcknowledge("Joy-Button: %d", 0);
           break;
           case 1:
               SendAcknowledge("Joy-Button: %d", 1);
           break;
           case 4:
               SendAcknowledge("Joy-Button: %d", 4);
           break;
           case 8:
               SendAcknowledge("Joy-Button: %d", 8);
           break;
           case 16:
               SendAcknowledge("Joy-Button: %d", 16);
           break;
           case 32:
               SendAcknowledge("Joy-Button: %d", 32);
           break;
           case 64:
               SendAcknowledge("Joy-Button: %d", 64);
           break;
           case 128:
               SendAcknowledge("Joy-Button: %d", 128);
           break;   
       }
    break;
    
    // =============================================================================
    // = Joy-Stick Kommandos (x,y, z-Werte auswerten und Stellungen simulieren =====
    //     
    // Rückmeldung der Neigung links und rechts
    case 161:
      neigung = packetBuffer[1] & 0xff;
      neigung = (neigung / 5) - 25;
      SendAcknowledge("#NEIGUNG;%d", neigung);
      
      // In der Simulation die Richtung in Anhängigkeit der Neigung zurückmelden
      SendAcknowledge("#RICHTUNG;%d", neigung * 5);      
    break;
    
    // Rückmeldung des Kippwinkels nach vorn und hinten
    case 162:
      kippwinkel = packetBuffer[1] & 0xff;
      kippwinkel = (kippwinkel / 5) - 25;
      SendAcknowledge("#KIPPWINKEL;%d", kippwinkel); 
    break;
    
    // Rückmeldung der Tiefe
    case 163:
      tiefe  = packetBuffer[1] & 0xff;;
      tiefe = (tiefe / 5) * -1;
      if (tiefe < -52) {
        tiefe = -52;
      }
      SendAcknowledge("#TIEFE;%d", tiefe);          
    break;
    
    }
   
   }
    
  }  
  
}

Das das Boot mit dem Failsafe zur Ausgangsposition zurückkommt, nennt man Return-to-home, kurz RTH. Haben einige Vereinskollegen in ihren FPV-Flugmodellen drin.

ElEspanol:
Das das Boot mit dem Failsafe zur Ausgangsposition zurückkommt, nennt man Return-to-home, kurz RTH. Haben einige Vereinskollegen in ihren FPV-Flugmodellen drin.

Oder "Coming Home" Wie es bei der Arduino FPV Ardupilot heißt. Also gibt es das auch schon alles, kannst dich selbst dran versuchen oder vielleicht Teile davon übernehmen. Einige haben schon den Ardupilot den du für Kopter, Hubschrauber und Autos benutzen kannst, auch schon auf ein Boot geschnallt.

Gruß

Jo, wobei das eigentlich im Moment gar nicht das Thema ist. :slight_smile: Eigentlich gehts hier ums WLAN, und jetzt sind wir ja schon einen Schritt weiter, um den letzten Code den ich da gepostet habe.

Was haltet Ihr davon und welcher Teil erstmal für mich wichtig wäre. 2 Integer Werte sollen vom Sender-Arduino zum Boot und einer vom Boot-Arduino zum Sender.

:slight_smile:

TEC_MICHL:
Jo, wobei das eigentlich im Moment gar nicht das Thema ist. :slight_smile:

Ja ich weiß, dachte nur das es könnte interesant sein. :slight_smile: