Wer kennt "LoRa" Long Range Telemetrie?

Status
Nicht offen für weitere Antworten.

AndreasL90

Erfahrener Benutzer
Hier der Code vom TX:

Code:
/*
**************************************************************************************************
ProMiniLoRaTracker_V1 Programs

Copyright of the author Stuart Robinson - 02/07/2015 15:00

These programs may be used free of charge for personal, recreational and educational purposes only.

This program, or parts of it, may not be used for or in connection with any commercial purpose without
the explicit permission of the author Stuart Robinson.

The programs are supplied as is, it is up to individual to decide if the programs are suitable for the
intended purpose and free from errors.
**************************************************************************************************
*/

//Hardware definitions
const byte lora_PNSS = 10;	               //pin number where the NSS line for the LoRa device is connected.
const byte PLED1 = 8;                      //pin number for LED on Tracker
const byte lora_PReset = 9;                //pin where LoRa device reset line is connected
const byte lora_PPWMCH = 3;                //pin number for tone generation, connects to LoRa device DIO2.
static const int RXPin = A5, TXPin = A6;   //pins for soft serial
static const uint32_t GPSBaud = 9600; //GPS

String InputString = "";                   //data on buff is copied to this string
String Outputstring = "";

float BattVolts; 
//char charVal[20];

#include <SPI.h>
#include "LoRaTX.h"
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

TinyGPSPlus gps;                   // The TinyGPS++ object
SoftwareSerial ss(RXPin, TXPin);   // The serial connection to the GPS device

///////////////////////////////////////////////////////////////////////////////////////
void loop()
{
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
    {
      displayInfo();
    }

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    digitalWrite(PLED1, HIGH);
    //Serial.println("No GPS detected!");
    while (true);
  }

}

/////////////////////////////////////////////////////////////////////////////////////////
void displayInfo()
{
  //Serial.print("Location: ");
  byte i;
  byte ltemp;
  batt_read();
  Outputstring = "";

  if (gps.location.isValid())
  {
    addtostring(gps.location.lat(), 5, 5, ",");
    addtostring(gps.location.lng(), 5, 5, ",");
    addtostring(gps.altitude.meters(), 3, 0, ",");
    addtostring(BattVolts, 4, 2, ",*");

    // at this point Outputstring has the LoRa Telemetry data to send
    //Serial.print("OutputString is ");
    //Serial.println(Outputstring);
    ltemp = Outputstring.length();
    lora_SetModem(lora_BW125, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON);		//Setup the LoRa modem parameters, default: (lora_BW41_7, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON)
    //lora_PrintModem();                                                                //Print the modem parameters
    lora_TXStart = 0;
    lora_TXEnd = 0;

    for (i = 0; i <= ltemp; i++)
    {
    lora_TXBUFF[i] = Outputstring.charAt(i);
    }
    i--;
    lora_TXEnd = i;
    
    digitalWrite(PLED1, HIGH);                                 //LED on during packet
    lora_Send(lora_TXStart, lora_TXEnd, 60, 255, 1, 10, 10);	 //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
    digitalWrite(PLED1, LOW);
    lora_TXPKTInfo();			                                     //print packet information
    lora_TXBuffPrint(0);
    //Serial.println();
    delay(1000);                                               //default: (7000)
  }
  else
  {
 // at this point Outputstring has the LoRa Telemetry data to send
    digitalWrite(PLED1, HIGH);
    Outputstring = "No GPS-Fix";
    //Serial.println(Outputstring);
    
    ltemp = Outputstring.length();
    lora_SetModem(lora_BW125, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON);    //Setup the LoRa modem parameters, default: (lora_BW41_7, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON)
    //lora_PrintModem();                                                                //Print the modem parameters
    lora_TXStart = 0;
    lora_TXEnd = 0;

    for (i = 0; i <= ltemp; i++)
    {
    lora_TXBUFF[i] = Outputstring.charAt(i);
    }
    i--;
    lora_TXEnd = i;

    digitalWrite(PLED1, HIGH);                                 //LED on during packet
    lora_Send(lora_TXStart, lora_TXEnd, 60, 255, 1, 10, 10);   //send the packet, data is in TXbuff from lora_TXStart to lora_TXEnd
    digitalWrite(PLED1, LOW);
    lora_TXPKTInfo();                                          //print packet information
    lora_TXBuffPrint(0);
    //Serial.println();
    delay(1000);                                               //default: (7000)
  }
}

//////////////////////////////////////////////////////////////////////////////////////////
void addtostring(double lFloat, byte lmin, byte lprecision, String Stuff) // from dtostrf3
{
  char charVal[10];               //temporarily holds data from vals
  memset(charVal, 0, sizeof(charVal)); //clear array
  InputString = "";
  dtostrf(lFloat, lmin, lprecision, charVal);  //lmin is mininum width, lprecision is precision
  for (int i = 0; i < sizeof(charVal); i++)
  {
    if  (charVal[i] == 0)
    {
      break;
    }
    InputString += charVal[i];
  }
  //return InputString;
  Outputstring = Outputstring + InputString + Stuff;
}

/////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);               //Serial console ouput
  //Serial.println("ProMiniLoRaTracker_V1");
  //Serial.println("Stuart Robinson - July 2015");
  //Serial.println();
  pinMode(lora_PReset, OUTPUT);			// RFM98 reset line
  digitalWrite(lora_PReset, LOW);		// Reset RFM98
  pinMode (lora_PNSS, OUTPUT);			// set the slaveSelectPin as an output:
  digitalWrite(lora_PNSS, HIGH);
  pinMode(PLED1, OUTPUT);			      // for shield LED
  SPI.begin();					            // initialize SPI:
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  lora_ResetDev();			            //Reset the device
  lora_Setup();				              //Do the initial LoRa Setup
  lora_SetFreq(108, 153, 153);		  //Set the LoRa frequency, 434.400 Mhz
  lora_Tone(1000, 1000, 10);        //Transmit an FM tone, 1000hz, 100ms
  ss.begin(GPSBaud);                //Startup soft serial for GPS
}

///////////////////////////////////////////////////////////////////////////////////////
void batt_read()
{
  int BattRead = analogRead(A1);
  lora_TXBUFF[1] = (BattRead / 256);                     //MSB of battery volts
  lora_TXBUFF[0] = (BattRead - (lora_TXBUFF[1] * 256));  //LSB of battery volts

  BattVolts = (BattRead * (10.4 / 1023.0)); 

  Serial.print("lora_TXBUFF[0]  ");
  Serial.println(lora_TXBUFF[0]);
  Serial.print("lora_TXBUFF[1]  ");
  Serial.println(lora_TXBUFF[1]);
  Serial.println("Battery ");
  Serial.print(BattVolts, 2);
  Serial.println("V");
}
Höhere Bandbreite, kürzerer Delay, teilweise auskommentierte serielle Datenausgabe und angepasste Skalierung für BattVolts... Sonst sollte Alles so sein, wie von Klaus bereitsgestellt.
 
Zuletzt bearbeitet:

AndreasL90

Erfahrener Benutzer
Und der Code vom RX:

Code:
/*****************************************************************************************************
ProMiniLoRaTracker_RX_V2 Programs
Copyright of the author Stuart Robinson - 18/07/2015 15:00
These programs may be used free of charge for personal, recreational and educational purposes only.
This program, or parts of it, may not be used for or in connection with any commercial purpose without
the explicit permission of the author Stuart Robinson.
The programs are supplied as is, it is up to individual to decide if the programs are suitable for the
intended purpose and free from errors.

Modified by DJ7OO for transmitting the battery voltage and providing GGA output sentences serially. 
******************************************************************************************************/

//Hardware definitions
const byte lora_PNSS = 10;	       //pin number where the NSS line for the LoRa device is connected.
const byte PLED1 = 8;              //pin number for LED on Tracker
const byte PBUZZ = 4;              //pin number for Buzzer on Tracker
const byte lora_PReset = 9;	       //pin where LoRa device reset line is connected
const byte lora_PPWMCH = 3;        //pin number for tone generation, connects to LoRa device DIO2.
const int RXPin = A5, TXPin = A2;  //pins for soft serial
const uint32_t GPSBaud = 9600;     //GPS and Digole Serial LCD

float Hlat, Hlon, Tlat, Tlon, Tvolt; //define the GPS lat and long variables
int Talt;                            //define GPS altitude variable
const int PayloadArraySize = 4;
String results[PayloadArraySize];
String InputString = "";             //data on buff is copied to this string
String outString = "";
String Ns, Ew;
float Lat, Lon;

byte index = 0;   
byte start_with = 0;
byte end_with = 78;    
byte CRC = 0;
int cnt = 1;

#include <SPI.h>
#include "LoRaCommon.h"
#include "LoRaRXonly.h"
#include "LoRaTXonly.h"
#include "U8glib.h"

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE);

///////////////////////////////////////////////////////////////////////////////////
void loop()
{
  checkforpacket();
  delay(1000);
}

///////////////////////////////////////////////////////////////////////////////////
float convertstring(String inString)
{
  char buf[20];
  inString.toCharArray(buf,(inString.length()+1));
  float val = atof(buf);
  return val;
}

//////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);   //Serial console ouput

// OLED startmessage
  u8g.firstPage();  
   do {
  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(16,10);
  u8g.print("LoRa-DECODER"); 
  u8g.setPrintPos(1,40);
  u8g.print("WAITING FOR DATA");  
  } while ( u8g.nextPage() );
  delay(100);

  //ss.begin(GPSBaud);              //Startup soft serial for GPS
  pinMode(lora_PReset, OUTPUT);			// RFM98 reset line
  digitalWrite(lora_PReset, LOW);		// Reset RFM98
  pinMode (lora_PNSS, OUTPUT);			// set the slaveSelectPin as an output:
  digitalWrite(lora_PNSS, HIGH);
  pinMode(PLED1, OUTPUT);			      // for shield LED
  pinMode(PBUZZ, OUTPUT);           // for shield Buzzer
  SPI.begin();					            // initialize SPI:
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE0);
  SPI.setBitOrder(MSBFIRST);
  lora_Setup();				              //Do the initial LoRa Setup
  lora_SetFreq(108, 153, 153);		  //Set the LoRa frequency, 434.400 Mhz
  lora_Tone(1000, 1000, 10);        //Transmit an FM tone
  lora_SetModem(lora_BW125, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON);		//Setup the LoRa modem parameters, default: (lora_BW41_7, lora_SF12, lora_CR4_5, lora_Explicit, lora_LowDoptON)
  //lora_PrintModem();              //Print the modem parameters
  lora_RXtoReady();
}

//////////////////////////////////////////////////////////////////////////////////
void FillPayloadArray(byte llora_RXStart, byte llora_RXEnd)
//fills payload array from RC buffer
{
  byte i = 0;
  byte j = 0;
  byte lvar1 = 0;
  String tempstring;

  for (i = llora_RXStart; i < llora_RXEnd; i++)
  {
    lvar1 = lora_RXBUFF[i];
    if (lvar1 == 44)
    {
      results[j] = tempstring;
      j++;
      tempstring = "";
      if (j > PayloadArraySize)
      {
        //Serial.print("ERROR To many Payload Fields ");
        //Serial.println(j);
        break;
      }
    }
    else
    {
      tempstring = tempstring + char(lvar1);
    }
  }
}

//////////////////////////////////////////////////////////////////////////////////
void checkforpacket()
{
  byte lora_LRegData;
  byte lora_Ltemp;
  String floatstring;
  lora_Ltemp = lora_readRXready();
  if (lora_Ltemp == 0)
  {
  //Serial.print("NP.");   //NP = No Packet
  }
  if (lora_Ltemp == 64)    //if no receive error, print packet contents as ASCII
  {
    digitalWrite(PLED1, HIGH);
    digitalWrite(PBUZZ, HIGH);  
    //Serial.println("Packet Ready ");
    lora_ReadPacket();
    //lora_RXPKTInfo();      //print the info on received packet
    //lora_RXBuffPrint(0);   //Print contents of RX buffer as ASCII,decimal or HEX 
    FillPayloadArray(lora_RXStart, lora_RXEnd);
    Tlat = convertstring(results[0]);
    Tlon = convertstring(results[1]);
    Talt = results[2].toInt();
    Tvolt = convertstring(results[3]);

 if(Tlat<0) { Ns = "S"; } else { Ns = "N"; } 
 if(Tlon<0) { Ew = "W"; } else { Ew = "E"; } 

 //Serial.println(Tlat,5);
 //Serial.println(Tlon,5);
 //Serial.println(Talt);
 //Serial.println(Tvolt);    

 if(Tlat < 0) { Tlat= -Tlat; }
 unsigned int Deg_Lat = Tlat; 
 Lat = 100*(Deg_Lat) + (Tlat - Deg_Lat)*60; 

 if(Tlon < 0) { Tlon= -Tlon; }
 unsigned int Deg_Lon = Tlon; 
 Lon = 100*(Deg_Lon) + (Tlon - Deg_Lon)*60; 

 //Serial.println(" ");
 //Serial.print("Lat: ");
 //Serial.println(Lat);
 //Serial.print("Lon: ");
 //Serial.println(Lon);
 //Serial.println(" ");

// building GGA sentence
 outString = "GNGGA,000000,";   //SentenceIdentifier,Time
 if(Tlat<10) {outString += "0"; }
 outString += String(Lat,4);    //latitude
 outString += ",";
 outString += Ns;               //N or S latitude   
 outString += ",";
 if(Tlon<100) {outString += "0"; }
 if(Tlon<10) {outString += "0"; }
 outString += String(Lon,4);     //longitude
 outString += ",";
 outString += Ew;                //E or W longitude
 outString += ",1,10,1.5,";      //,FixQuality,NumberOfSats,HDOP,  
 outString += Talt;              //Altitude [m]  
 outString += ".0,M,0.0,M,,,";   //,M,HeightAboveWGS84,M,-,-,
 
 // checksum calculation 
   for (byte x = start_with; x<end_with; x++) 
   {  // XOR every character in between '$' and '*'
   CRC = CRC ^ outString[x] ;
    }    
 
// finalizing and sending GPGGA sentence 
   Serial.print("$");
   Serial.print(outString);
   Serial.print("*");
   Serial.println(CRC,HEX);

// OLED Display
   Display();

// Upcounter
    cnt = cnt+1;
    if(cnt>999) {cnt=1; }  
   
   outString = "";  
   lora_RXtoReady();                    // ready for next and clear flags
   digitalWrite(PLED1, LOW);
   digitalWrite(PBUZZ, LOW);
  }
  if (lora_Ltemp == 96)
  {
    //Serial.println();
    //Serial.println("CRC Error in packet");
    lora_RXtoReady();                    // ready for next and clear flags
  }
}

////////////////////////////////////////////////////////////////////////
void Display()
  {
  u8g.firstPage();  
  do {
  u8g.setFont(u8g_font_unifont);
  u8g.setPrintPos(2,10);
  u8g.print("LoRa-Decoder"); 

  u8g.setPrintPos(104,10);
  if(cnt<100) {
  u8g.print("0"); }
  if(cnt<10)  {    
  u8g.print("0"); }
  u8g.print(cnt);  
  
  u8g.setPrintPos(5,28);
  u8g.print("Lat: ");
  u8g.print(Tlat,5);
 // u8g.print(" ");
 // u8g.print(Ns);    
  
  u8g.setPrintPos(5,40);  
  u8g.print("Lon: "); 
  u8g.print(Tlon,5);
 // u8g.print(" ");
 // u8g.print(Ew);
 
  u8g.setPrintPos(5,52);
  u8g.print("A: ");
  u8g.print(Talt);
  u8g.print("m");  

  u8g.setPrintPos(80,52);
  if (lora_PacketSNR > 127)
  {
  u8g.print("-");
  u8g.print((255 - lora_PacketSNR) / 4);
  }
  else
  {
  u8g.print("+");
  u8g.print( (lora_PacketSNR) / 4);
  }
  u8g.print("db"); 

  u8g.setPrintPos(5,64);
  u8g.print("UBatt: ");
  u8g.print(Tvolt);
  u8g.print("V");

 } while 
( u8g.nextPage() );  
}
Auch hier (und in den dazugehörigen H-Dateien) hab ich ein paar serielle Ausgaben auskommentiert und - wie oben schon beschrieben - die Ausgabe des $GNGGA Strings etwas verändert.
 

AndreasL90

Erfahrener Benutzer
@Klaus
Wozu dient der Delay (7000ms) im Loop eigentlich?

Ich schaff es ausserdem nicht, dass der Ublox Empfänger seine Einstellungen behält. Trotz Batterie (voll - nachgemessen)... Aber in den default-Einstellungen werden ja auch die benötigten Parameter ausgegeben, neben vielen in diesem Fall unnützen Messages.
 
Zuletzt bearbeitet:
@Klaus
Wozu dient der Delay (7000ms) im Loop eigentlich?
Hmmmh, soweit ich mich erinnere, stand dieser Wert einmal am Loopende bei der Sender-Version. Ganz einfach: mit den ursprünglich gewählten Übertragungsparametern ( mit ca. 3 Sekunden On-Air-Zeit ) ergab sich dabei eine Sendefolge von etwa 10 Sekunden.

Da ich selbst kein Modellbauer bin, würden mich Eure LoRa-Anwendungen interessieren. Geht es Euch dabei um das Auffinden ggf. verloren gegangener Modelle oder gibt es da noch mehr?
Der Grund für meine Frage ist, dass ich eine Software entdeckt habe, mit der man wirklich sehr einfach anwenderspezifische Android-Programme erstellen kann und sich damit auch hinsichtlich der Auswertung von LoRa-Daten m.E. hochinteressante neue Möglichkeiten ergeben. Dafür ist es natürlich auch wichtig zu wissen, welche Parameter anzuwerten sind.

Gruß Klaus
 
Zuletzt bearbeitet:

AndreasL90

Erfahrener Benutzer
Hallo Klaus,

vorweg: Es scheint jetzt zu funktionieren. Mit der Bandbreite bin ich im Moment bei 62,5kHz und den Delay hab ich auf 1500 gesetzt.
Warum das nun klappt kann ich nicht sagen.
Leider hab ich den Fuß beim Joggen etwas lädiert - desswegen kann ich grad keine Testrouten ablaufen. Aber ich bin mit dem Auto um den Block und da sah es ganz gut aus.

In der displayInfo() Funktion des Senders kommt auch dieser Delay vor. Beim Empfänger, wie du schreibst, nur am Ende der Loop. Dann müsste man diesen doch z.B. auch auf lediglich 100ms einstellen können, oder?

Mir ist das live-Tracking in 3D mit Google Earth oder anderer Software mit einer Updaterate von <2s wichtig. Konkret bei mir/uns soll so die Trajektorie einer Rakete während dem Flug am Boden dargestellt werden. Diese fliegt auf ca. 5000m Höhe

@cesco1
"Save settings" hab ich benutzt und es scheint tatsächlich so zu sein, dass die Einstellungen bleiben wenn ich den GNSS Empfänger nur kurz (10s) vom USB-Seriell Adapter (und damit der externen Stromversorgung) trenne. Wenn ich ihn für ca. 1min abgesteckt lasse, sind die Einstellungen wieder auf Default.

@digaus
Interessant; ist an mir leider vorbei gegangen...
Kann ein zu kurzer Delay bei der aktuellen Variante des Trackers zu Problemen führen?
 
Zuletzt bearbeitet:

AndreasL90

Erfahrener Benutzer
Bei deiner angepassten Bibliothek?
Wie ist das mit der ursprünglichen Bibliothek? Ich verstehe noch nicht wirklich, wofür das Delay in displayInfo() (Siehe Beitrag #202) genau benötigt wird.
 

digaus

Erfahrener Benutzer
Das delay ist dafür da, dass man Nachrichten nicht zu schnell hintereinander schickt. Mit dem lora calculator kann man ja die on air time berechnen. Genau so lange braucht der tx auch zum senden. Wenn du jetzt schon eine neue Nachricht sendest bevor die alte beendet wurde, wird das Senden abgebrochen und es kommt nix am rx an.

Ich habe die Bibliothek von github genommen die ich dort im Post verlinkt habe. Da gab es noch einige Probleme mit, man konnte z.b. nicht so einfach umschalten zwischen senden und empfangen.
Mit meiner Bibliothek wird auf ein Interrupt vom Lora Modul geguckt, welches je nach Betriebsart ausgelöst wird, wenn eine Nachricht empfangen wurde, oder wenn eine Nachricht komplett gesendet wurde.
So braucht man kein delay und der Controller kann noch andere Sachen machen während er darauf wartet bis er wieder senden kann.

Das Senden und empfangen ist mit der Bibliothek auch deutlich simpler als mit dem Code den du z.b. in Post 202 gepostet hast.

In der zip ist ein Beispiel drin wie die Bibliothek verwendet wird.
 

AndreasL90

Erfahrener Benutzer
Hört sich gut an. Wenn Zeit ist, werde ich mit der von dir angepassten Bibliothek was basteln...

Bei der bisherigen Bibliothek, wie sie auch im Post #202 verwendet wird, bin ich davon ausgegangen, dass der delay sequentiell zur Sendedauer hinzugerechnet wird. Aber wenn ich mir das jetzt nochmal so ansehe... Dann wird also verhindert, dass in der Zeit des Delays keine neuen Daten vom Microprozessor an das RFM98W geschickt werden?
Sry für die dumme Fragerei, aber ich bin damit noch nicht ganz so fit. ;)
 

AndreasL90

Erfahrener Benutzer
Das könnte Einiges erklären. Mit dem Lora Rechner ist die Sendezeit etwas über 1s; der eingestellte Delay war bei 1000ms - da wird sich das Ganze wohl verschluckt haben...
 

digaus

Erfahrener Benutzer
Oh ich hatte deine frage bezüglich des delays in Post 208 wohl falsch verstanden oder hast du den Beitrag nochmal geändert?
Also ja ein zu kurzer delay führt bei dem code den du verwendest dazu, dass nicht korrekt gesendet wird ;)
 

AndreasL90

Erfahrener Benutzer
Passt... :D Hab ihn jetzt auf 2000ms gesetzt - das passt ganz gut (LED leuchtet bei BW=125kHz ca. 1,3-1,5s was sich mit dem Calculator gut deckt).

Der Rechner gibt mit den übrigen Parametern auch eine RX Sensivität von -138dBm an. Damit sind die angestrebten 5000m Reichweite locker drin. :D
Mal sehen, ob die Antennen-Null noch einen Strich durch die Rechnung macht. Diese lässt sich wegen ihrer Länge leider nur axial zur Raketenlängsachse montieren. Evtl. ginge noch leicht schräg (20°)... (Was meint ihr?)
 

QuadMax

Erfahrener Benutzer
Toll :(.
Letzte Woche kam Platinenversion 1.7 bei mir an :).
Hatte deine Library digaus auch nicht mehr auf dem Schirm.
Habe meine Hardware geändert, damit sie deine Library ab jetzt auch unterstützt.
Ich präsentiere Version 1.9:
Unterschied zur 1.8: DIO0 und DIO1 sind jetzt mit an den ATMEGA angeschlosssen.

Datei ist im Anhang, Bilder siehe Version 1.8.

Ich werde Version 1.7 zusammenlöten und dann Bericht erstatten.
Falls alles wie gewünscht funktioniert und meine Hobbyzeit es erlaubt,
fertige ich vielleicht meinen Überschuss per Hand und gebe sie für Bauteilkosten
an die Interessierten hier im Thread ab.
 

Anhänge

Zuletzt bearbeitet:

digaus

Erfahrener Benutzer
Das tx done flag kann man über spi abfragen, da braucht man keinen weiteren Pin für. Ich habe das bei mir mit nem Interrupt gemacht weil das in der Bibliothek die ich als Vorlage genommen habe, auch so gemacht wurde.
 
Status
Nicht offen für weitere Antworten.
FPV1

Banggood

Oben Unten