Tracker GPS, sur base ESP32
+5
LDami
bruno1963
BALDO
philartis
swr85
9 participants
Page 1 sur 2
Page 1 sur 2 • 1, 2
Tracker GPS, sur base ESP32
Bonjour,
Je me suis lancé dans la fabrication d'un tracker GPS pour moto sur une base d'un ESP32 (pico ordinateur) et 2 modules, le premier GPS et le second pour communiquer avec une carte Sim et un abonnement à 2€/mois serait suffisant.
L'idée de s'inspirer de ce tuto
https://www.youtube.com/watch?v=Lrwbu9oA3Do
J'ai commandé
Module GPS NEO6M
Module GRPS SIM800L GSM
et, j'avais déjà
ESP32 Development Board
d'autres ont ils déjà entrepris ce type de projet?
Je me suis lancé dans la fabrication d'un tracker GPS pour moto sur une base d'un ESP32 (pico ordinateur) et 2 modules, le premier GPS et le second pour communiquer avec une carte Sim et un abonnement à 2€/mois serait suffisant.
L'idée de s'inspirer de ce tuto
https://www.youtube.com/watch?v=Lrwbu9oA3Do
J'ai commandé
Module GPS NEO6M
Module GRPS SIM800L GSM
et, j'avais déjà
ESP32 Development Board
d'autres ont ils déjà entrepris ce type de projet?
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
Non, mais je vais suivre ton projet.
J'avais acheté un module GPS (GY-GPS6MV - mais je pense que c'est le même que le tien) afin de faire un ensemble compteur évolué sur base Arduino, mais je n'ai jamais pris le temps..
J'avais acheté un module GPS (GY-GPS6MV - mais je pense que c'est le même que le tien) afin de faire un ensemble compteur évolué sur base Arduino, mais je n'ai jamais pris le temps..
_________________
Roulez prudemment mais amusez-vous !
Il faut toujours terminer ce que l'on a co
https://hornet750.com/forum
Re: Tracker GPS, sur base ESP32
Oui, ce sont les mêmes modules, juste une évolution sur le néo.
C'est du Ali, donc réception dans env 1 mois.
C'est du Ali, donc réception dans env 1 mois.
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
c'est une excellente idée...
après, pourquoi s’embêter alors qu'on trouve des systèmes complets vraiment pas cher: https://www.ebay.fr/itm/363086279102 ... et il y a encore bien moins cher sur les sites Chinois.
après, pourquoi s’embêter alors qu'on trouve des systèmes complets vraiment pas cher: https://www.ebay.fr/itm/363086279102 ... et il y a encore bien moins cher sur les sites Chinois.
_________________
FONDATEUR 125 ATTITUDE
Re: Tracker GPS, sur base ESP32
C'est plus fun de faire soi même
C'est pas cher env 9eur
On ne dépend pas d'une app chinoise
C'est plus polyvalent : possibilité d'ajouter une sirène et c'est une alarme
C'est plus complexe !
C'est pas cher env 9eur
On ne dépend pas d'une app chinoise
C'est plus polyvalent : possibilité d'ajouter une sirène et c'est une alarme
C'est plus complexe !
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
Que de bons arguments
_________________
Roulez prudemment mais amusez-vous !
Il faut toujours terminer ce que l'on a co
https://hornet750.com/forum
Re: Tracker GPS, sur base ESP32
idée pas bête , vu tous les vols de bécanes , pas cher , et 2 e par mois , franchement , un bon investissement ,
bruno1963- Membre VIP, spécialiste custom
- Moto : honda shadow , suzuki smx ,kymco
Localisation : nord
Re: Tracker GPS, sur base ESP32
bruno1963 a écrit: idée pas bête , vu tous les vols de bécanes , pas cher , et 2 e par mois , franchement , un bon investissement ,
pas une bonne idée... Mme va te tracker... si tu t’arrêtes au bistrot t'es grillé
_________________
FONDATEUR 125 ATTITUDE
Re: Tracker GPS, sur base ESP32
je suis pas bistrot , sauf avec madame pour les balades , je sais qu elle est blonde mais serais conne
BALDO a écrit:bruno1963 a écrit: idée pas bête , vu tous les vols de bécanes , pas cher , et 2 e par mois , franchement , un bon investissement ,
pas une bonne idée... Mme va te tracker... si tu t’arrêtes au bistrot t'es grillé
bruno1963- Membre VIP, spécialiste custom
- Moto : honda shadow , suzuki smx ,kymco
Localisation : nord
Re: Tracker GPS, sur base ESP32
J'ai reçu les modules. J'arrive à faire fonctionner le module GPS. Mais le module GSM ne se connecte pas au réseau GRPS.
Je suis un peu bloqué
Je suis un peu bloqué
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
j y connais mais pas possible autre réseauswr85 a écrit:J'ai reçu les modules. J'arrive à faire fonctionner le module GPS. Mais le module GSM ne se connecte pas au réseau GRPS.
Je suis un peu bloqué
bruno1963- Membre VIP, spécialiste custom
- Moto : honda shadow , suzuki smx ,kymco
Localisation : nord
Re: Tracker GPS, sur base ESP32
J'ai tenté orange et SFR. Avec les chinoiseries, pas impossible un défaut, j'ai commandé un nouveau module Esp32 et sim800L intégré
http://www.lilygo.cn/prod_view.aspx?TypeId=50044&Id=1127&FId=t3:50044:3
http://www.lilygo.cn/prod_view.aspx?TypeId=50044&Id=1127&FId=t3:50044:3
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
Pour le coup ça augmente sensiblement ton prix de revient.
_________________
Roulez prudemment mais amusez-vous !
Il faut toujours terminer ce que l'on a co
https://hornet750.com/forum
Re: Tracker GPS, sur base ESP32
Oui ça augmente le coût, ça reste raisonnable
17eur module lilygo Esp32+sim800l
3eur module gps
Env 20eur
17eur module lilygo Esp32+sim800l
3eur module gps
Env 20eur
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
Ça avance !!
_________________
Roulez prudemment mais amusez-vous !
Il faut toujours terminer ce que l'on a co
https://hornet750.com/forum
Re: Tracker GPS, sur base ESP32
Pas mal tout ça :)
Personnellement je tenterais de faire une application ou un site web pour récupérer encore plus facilement la position, et qui montrerais même le trajet quand la moto est en mouvement ! Bon après ça demande un peu plus de savoir-faire ..
Fait aussi attention à ce que ton module ne décharge pas la batterie de la moto en se rechargeant (à moins que ton module soit totalement indépendant ?)
Personnellement je tenterais de faire une application ou un site web pour récupérer encore plus facilement la position, et qui montrerais même le trajet quand la moto est en mouvement ! Bon après ça demande un peu plus de savoir-faire ..
Fait aussi attention à ce que ton module ne décharge pas la batterie de la moto en se rechargeant (à moins que ton module soit totalement indépendant ?)
LDami- Amateur
- Moto : Honda CM 125 Custom
Localisation : Calvados (14) FRANCE
Re: Tracker GPS, sur base ESP32
sympa le projet. Tu en es où avec lui?
shinra- Amateur
- Moto : coréenne
Localisation : Cantal
Re: Tracker GPS, sur base ESP32
j'ai un proto fonctionnel sur la base de L'ESP32 lilygo, je n'ai pas testé sur la moto. Car problème de santé et garage pour l'instant.shinra a écrit:sympa le projet. Tu en es où avec lui?
Je peux partage le code
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
pour l'alimentation tu as prévu quoi? sur la batterie? en autonomie?
je vais regarder mais oui, pourquoi pas. Ça me changerait des projets arduino actuels… ou plus exactement ça me permettrait de me remettre dans le bain ^^
je vais regarder mais oui, pourquoi pas. Ça me changerait des projets arduino actuels… ou plus exactement ça me permettrait de me remettre dans le bain ^^
shinra- Amateur
- Moto : coréenne
Localisation : Cantal
Re: Tracker GPS, sur base ESP32
shinra a écrit:pour l'alimentation tu as prévu quoi? sur la batterie? en autonomie?
je vais regarder mais oui, pourquoi pas. Ça me changerait des projets arduino actuels… ou plus exactement ça me permettrait de me remettre dans le bain ^^
Voici le code [mette ton tel à la place de ]
#define SMS_TARGET "+336xxxxxx"
#define CALL_TARGET "+336xxxxxx"
- Code:
// Please select the corresponding model
// #define SIM800L_IP5306_VERSION_20190610
#define SIM800L_AXP192_VERSION_20200327
// #define SIM800C_AXP192_VERSION_20200609
// #define SIM800L_IP5306_VERSION_20200811
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
#include <TinyGPS++.h>
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 21, 22); //18=SDK 19=SCK As per labeling on ESP32 DevKit
// Define the serial console for debug prints, if needed
#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG SerialMon
#include "utilities.h"
#include <SoftwareSerial.h>
// Set serial for debug console (to the Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to the module)
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#include <TinyGsmClient.h>
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
static const int RXPin = 3, TXPin = 1;
static const uint32_t GPSBaud = 9600;
char gpsLong[] = "Hello World";
char gpsLong_full[] = "Hello World";
char gpsLat[] = "Hello World";
char gpsLat_full[] = "Hello World";
char gpsAlt[] = "9999";
char gpsSpeed[] = "999";
char gpsSat[] = "99";
char gpsHour[] = "Hr";
char gpsMinute[] = "Mn";
String myString;
byte compteur = 0 ;
byte GPS_config = 1;
byte SMS_config = 1;
byte Display_config = 1;
byte Full_config = 0;
byte track_minute = 0 ;
byte track_minute_old = 0 ;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
// Set phone numbers, if you want to test SMS and Calls
#define SMS_TARGET "+336xxxxxx"
#define CALL_TARGET "+336xxxxxx"
String SMS_TARGET_SET;
void setup()
{
// Set console baud rate
SerialMon.begin(115200);
delay(1000);
if (Display_config == 1)
{
Display_init();
}
if (Display_config == 1)
{
mainconfig();
}
if (GPS_config == 1)
{
GPS_init();
}
if (SMS_config == 1)
{
SMS_init();
}
}
void loop()
{
if (GPS_config == 1)
{
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printDateTime(gps.date, gps.time);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);
//printlong(gps.time.hour());
// printlong(gps.time.minute());
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
dtostrf(gps.location.lat(), 4, 3, gpsLat);
dtostrf(gps.location.lat(), 4, 8, gpsLat_full);
display.drawString(0, 15, gpsLat);
display.setFont(ArialMT_Plain_10);
display.drawString(50, 19, "°N");
display.setFont(ArialMT_Plain_16);
dtostrf(gps.location.lng(), 4, 3, gpsLong);
dtostrf(gps.location.lng(), 4, 8, gpsLong_full);
display.drawString(64, 15, gpsLong);
display.setFont(ArialMT_Plain_10);
display.drawString(110, 19, "°E");
display.setFont(ArialMT_Plain_10);
dtostrf(gps.altitude.meters(), 4, 0, gpsAlt);
display.drawString(0, 30, gpsAlt);
display.drawString(50, 30, "m");
display.setFont(ArialMT_Plain_10);
dtostrf(gps.speed.kmph(), 4, 0, gpsSpeed);
display.drawString(64, 30, gpsSpeed);
display.drawString(100, 30, "km/h");
dtostrf(gps.time.hour(), 2, 0, gpsHour);
dtostrf(gps.time.minute(), 2, 0, gpsMinute);
track_minute = gps.time.minute();
display.drawString(95, 0, gpsHour);
display.drawString(106, 0, ":");
display.drawString(110, 0, gpsMinute);
if ( gps.satellites.value() != 0) {
for (int compteur = 0 ; compteur < gps.satellites.value() ; compteur++)
{
display.fillCircle(compteur * 10, 5, 3);
}
} else {
display.drawCircle(random(1, 120), 5, 3);
}
// write the buffer to the display
display.display();
unsigned long distanceKmToLondon =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON);
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
Serial.println();
smartDelay(1000);
if (millis() > 5000 && gps.charsProcessed() < 10)
Serial.println(F("No GPS data received: check wiring"));
}
readAllSMSs();
// Do nothing forevermore
// while (true) {
http://modem.maintain();
// }
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartDelay(0);
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i = strlen(sz); i < len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len - 1] = ' ';
Serial.print(sz);
smartDelay(0);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
Serial.print(F("********** "));
}
else
{
char sz[32];
sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
Serial.print(sz);
}
if (!t.isValid())
{
Serial.print(F("******** "));
}
else
{
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(0);
}
static void printStr(const char *str, int len)
{
int slen = strlen(str);
for (int i = 0; i < len; ++i)
Serial.print(i < slen ? str[i] : ' ');
smartDelay(0);
}
void GPS_init() {
ss.begin(GPSBaud);
Serial.println();
Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
// Start power management
if (setupPMU() == false) {
Serial.println("Setting power error");
}
}
void SMS_init() {
// Some start operations
setupModem();
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(6000);
// Restart takes quite some time
// To skip it, call init() instead of restart()
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Initializing modem...");
display.display();
modem.restart();
delay(10000);
String imei = modem.getIMEI();
DBG("IMEI:", imei);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "Start " + imei);
display.display();
//delay(1000);
bool res = modem.sendSMS(SMS_TARGET, String("Welcome to GPS tracker ") + imei);
DBG("SMS:", res ? "OK" : "fail");
display.setFont(ArialMT_Plain_24);
display.drawString(0, 26, "=>" + res ? "OK" : "fail");
display.display();
// delay(1000);
}
void readAllSMSs()
{
http://modem.sendAT(GF("+CMGF=1"));
http://modem.waitResponse();
http://modem.sendAT(GF("+CPMS=\"SM\""));
http://modem.waitResponse();
modem.sendAT(GF("+CNMI=1,2,2,0,0"));
modem.waitResponse();
// modem.sendAT(GF("+CMGL"));
// modem.waitResponse();
// modem.sendAT(GF("+CMGL=\"ALL\""));
// modem.waitResponse();
if (Full_config == 1 and track_minute != track_minute_old) {
//bool res = modem.sendSMS(SMS_TARGET_SET, String("Tracking : ")+gpsHour+":"+gpsMinute+" "+gpsLat_full + "N," + gpsLong_full + "E " + gpsAlt + "m " + gpsSpeed + "Km/h ");
bool res = modem.sendSMS(SMS_TARGET_SET, String("http://maps.google.com/maps?q=") + gpsLat_full + "," + gpsLong_full);
DBG("SMS:", res ? "OK" : "fail");
track_minute_old = track_minute;
}
http://modem.sendAT(GF("+CMGL=\"REC UNREAD\""));
while (true)
{
if (modem.waitResponse(10000L, GF(GSM_NL "+CMT:"), GFP(GSM_OK), GFP(GSM_ERROR)))
{
String data = modem.stream.readStringUntil('\n');
data.trim();
if (data.length() == 0)
break;
Serial.println("Data: " + data);
SMS_TARGET_SET = data.substring(1, 13);
Serial.println("From: " + SMS_TARGET_SET);
String msg = modem.stream.readStringUntil('\n');
Serial.println("Message: " + msg);
msg.toLowerCase();
if (msg.indexOf("config") >= 0)
{
mainconfig();
}
if (msg.indexOf("help") >= 0)
{
helpmenu();
}
if (msg.indexOf("alt") >= 0)
{
bool res = modem.sendSMS(SMS_TARGET_SET, String("Altitude ")+gpsAlt+"m");
DBG("SMS:", res ? "OK" : "fail");
}
if (msg.indexOf("speed") >= 0)
{
bool res = modem.sendSMS(SMS_TARGET_SET, String("Speed ")+gpsSpeed+"Km/h");
DBG("SMS:", res ? "OK" : "fail");
}
if (msg.indexOf("track") >= 0)
{
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 50, "" + SMS_TARGET_SET);
display.drawString(100, 50, "" + msg);
display.display();
//bool res = modem.sendSMS(SMS_TARGET_SET, String("Tracking : ") + gpsLat_full + "N," + gpsLong_full + "E " + gpsAlt + "m " + gpsSpeed + "Km/h ");
bool res = modem.sendSMS(SMS_TARGET_SET, String("http://maps.google.com/maps?q=") + gpsLat_full + "," + gpsLong_full);
DBG("SMS:", res ? "OK" : "fail");
}
if (msg.indexOf("full") >= 0)
{
if (Full_config == 1) {
Full_config = 0;
bool res = modem.sendSMS(SMS_TARGET_SET, String("Full : ") + Full_config);
DBG("SMS:", res ? "OK" : "fail");
} else {
Full_config = 1;
bool res = modem.sendSMS(SMS_TARGET_SET, String("Full : ") + Full_config);
DBG("SMS:", res ? "OK" : "fail");
}
}
}
else
{
break;
}
}
http://modem.sendAT(GF("+CMGD=1,4"));
http://modem.waitResponse();
}
void mainconfig() {
display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Setup...");
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "GPS : " + String(GPS_config));
display.drawString(0, 30, "SMS " + String(SMS_config));
display.drawString(64, 15, "Oled :" + String(Display_config));
display.drawString(64, 30, "Full :" + String(Full_config));
bool res = modem.sendSMS(SMS_TARGET_SET, "Full :" + String(Full_config));
DBG("SMS:", res ? "OK" : "fail");
display.display();
delay(1000);
}
void Display_init() {
// Init display
display.init();
display.flipScreenVertically();
delay(10);
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Tracker GPS");
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "Tracker GPS");
display.setFont(ArialMT_Plain_24);
display.drawString(0, 35, "Tracker GPS");
display.display();
delay(1000);
}
void helpmenu() {
display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Help...");
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.drawString(0, 15, "Track: track by SMS");
display.drawString(0, 25, "Full : turn follow me on/off");
http://display.drawString(0, 25, "SMS : turn display on/off");
http://display.drawString(0, 35, "GPS: turn display on/off");
http://display.drawString(64, 25, "Disp : turn display on/off");
display.display();
bool res = modem.sendSMS(SMS_TARGET_SET, String("track|alt|speed or full"));
DBG("SMS:", res ? "OK" : "fail");
delay(10000);
}
Utilites.h
- Code:
#include <axp20x.h>
#include <Wire.h>
#if defined(SIM800L_IP5306_VERSION_20190610)
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
// setPowerBoostKeepOn
bool setupPMU()
{
bool en = true;
Wire.begin(I2C_SDA, I2C_SCL);
Wire.beginTransmission(IP5306_ADDR);
Wire.write(IP5306_REG_SYS_CTL0);
if (en) {
Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else {
Wire.write(0x35); // 0x37 is default reg value
}
return Wire.endTransmission() == 0;
}
#elif defined(SIM800L_AXP192_VERSION_20200327)
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_DTR 32
#define MODEM_RI 33
#define I2C_SDA 21
#define I2C_SCL 22
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#elif defined(SIM800C_AXP192_VERSION_20200609)
// pin definitions
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 25
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_DTR 32
#define MODEM_RI 33
#define I2C_SDA 21
#define I2C_SCL 22
#define LED_GPIO 12
#define LED_ON LOW
#define LED_OFF HIGH
#elif defined(SIM800L_IP5306_VERSION_20200811)
#define MODEM_RST 5
#define MODEM_PWRKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define MODEM_DTR 32
#define MODEM_RI 33
#define I2C_SDA 21
#define I2C_SCL 22
#define LED_GPIO 13
#define LED_ON HIGH
#define LED_OFF LOW
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
// setPowerBoostKeepOn
bool setupPMU()
{
bool en = true;
Wire.begin(I2C_SDA, I2C_SCL);
Wire.beginTransmission(IP5306_ADDR);
Wire.write(IP5306_REG_SYS_CTL0);
if (en) {
Wire.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else {
Wire.write(0x35); // 0x37 is default reg value
}
return Wire.endTransmission() == 0;
}
#else
#error "Please select the corresponding model"
#endif
#if defined(SIM800L_AXP192_VERSION_20200327) || defined(SIM800C_AXP192_VERSION_20200609)
#include <axp20x.h> //https://github.com/lewisxhe/AXP202X_Library
AXP20X_Class axp;
bool setupPMU()
{
// For more information about the use of AXP192, please refer to AXP202X_Library https://github.com/lewisxhe/AXP202X_Library
Wire.begin(I2C_SDA, I2C_SCL);
int ret = axp.begin(Wire, AXP192_SLAVE_ADDRESS);
if (ret == AXP_FAIL) {
Serial.println("AXP Power begin failed");
return false;
}
//! Turn off unused power
axp.setPowerOutPut(AXP192_DCDC1, AXP202_OFF);
axp.setPowerOutPut(AXP192_LDO2, AXP202_OFF);
axp.setPowerOutPut(AXP192_LDO3, AXP202_OFF);
axp.setPowerOutPut(AXP192_DCDC2, AXP202_OFF);
axp.setPowerOutPut(AXP192_EXTEN, AXP202_OFF);
//! Do not turn off DC3, it is powered by esp32
// axp.setPowerOutPut(AXP192_DCDC3, AXP202_ON);
// Set the charging indicator to turn off
// Turn it off to save current consumption
// axp.setChgLEDMode(AXP20X_LED_OFF);
// Set the charging indicator to flash once per second
// axp.setChgLEDMode(AXP20X_LED_BLINK_1HZ);
//! Use axp192 adc get voltage info
axp.adc1Enable(AXP202_VBUS_VOL_ADC1 | AXP202_VBUS_CUR_ADC1 | AXP202_BATT_CUR_ADC1 | AXP202_BATT_VOL_ADC1, true);
float vbus_v = axp.getVbusVoltage();
float vbus_c = axp.getVbusCurrent();
float batt_v = axp.getBattVoltage();
// axp.getBattPercentage(); // axp192 is not support percentage
Serial.printf("VBUS:%.2f mV %.2f mA ,BATTERY: %.2f\n", vbus_v, vbus_c, batt_v);
return true;
}
#endif
void setupModem()
{
// Start power management
if (setupPMU() == false) {
Serial.println("Setting power error");
}
#ifdef MODEM_RST
// Keep reset high
pinMode(MODEM_RST, OUTPUT);
digitalWrite(MODEM_RST, HIGH);
#endif
pinMode(MODEM_PWRKEY, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
// Turn on the Modem power first
digitalWrite(MODEM_POWER_ON, HIGH);
// Pull down PWRKEY for more than 1 second according to manual requirements
digitalWrite(MODEM_PWRKEY, HIGH);
delay(100);
digitalWrite(MODEM_PWRKEY, LOW);
delay(1000);
digitalWrite(MODEM_PWRKEY, HIGH);
// Initialize the indicator as an output
pinMode(LED_GPIO, OUTPUT);
digitalWrite(LED_GPIO, LED_OFF);
}
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Re: Tracker GPS, sur base ESP32
LDami a écrit:Pas mal tout ça :)
Personnellement je tenterais de faire une application ou un site web pour récupérer encore plus facilement la position, et qui montrerais même le trajet quand la moto est en mouvement ! Bon après ça demande un peu plus de savoir-faire ..
Fait aussi attention à ce que ton module ne décharge pas la batterie de la moto en se rechargeant (à moins que ton module soit totalement indépendant ?)
- Code:
// Your GPRS credentials (leave empty, if not needed)
const char apn[] = "sl2sfr"; // APN (example: internet.vodafone.pt) use https://wiki.apnchanger.org
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password
// SIM card PIN (leave empty, if not defined)
const char simPIN[] = "";
#define SIM800L_AXP192_VERSION_20200327
#include "utilities.h"
// Define the serial console for debug prints, if needed
#define DUMP_AT_COMMANDS
#define TINY_GSM_DEBUG SerialMon
// Server details
const char server[] = "______________URL__________"; // domain name: example.com, maker.ifttt.com, etc
const char resource[] = "_________CHEMIN__________"; // resource path, for example: /post-data.php
const int port = 80; // server port number HTTP
//const int port = 443; // server port number HTTPS
// Keep this API Key value to be compatible with the PHP code provided in the project page.
String apiKeyValue = "__________API KEY___________";
// TTGO T-Call pins
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
// Define the serial console for debug prints, if needed
//#define DUMP_AT_COMMANDS
#include <Wire.h>
#include <TinyGsmClient.h>
#include <TinyGPS++.h>
#include "SSD1306Wire.h" // legacy include: `#include "SSD1306.h"`
// Initialize the OLED display using Wire library
SSD1306Wire display(0x3c, 21, 22); //18=SDK 19=SCK As per labeling on ESP32 DevKit
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
// TinyGSM Client for Internet connection
TinyGsmClient client(modem);
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
#define uS_TO_S_FACTOR 1000000UL /* Conversion factor for mic aro seconds to seconds */
#define TIME_TO_SLEEP 60 /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
#include <SoftwareSerial.h>
#include <TinyGsmClient.h>
static const double LONDON_LAT = 51.508131, LONDON_LON = -0.128002;
static const int RXPin = 3, TXPin = 1;
static const uint32_t GPSBaud = 9600;
char gpsLong[] = "Hello World";
char gpsLong_full[] = "Hello World";
char gpsLat[] = "Hello World";
char gpsLat_full[] = "Hello World";
char gpsAltitude[] = "Hello World";
char gpsSpeed[] = "Hello World";
char gpsSat[] = "00";
char gpsHour[] = "Hr";
char gpsMinute[] = "Mn";
String myString;
// Config
byte compteur = 0 ;
byte GPS_config = 1;
byte HTTP_config = 1;
byte Display_config = 1;
byte Full_config = 0;
byte track_minute = 0 ;
byte track_minute_old = 0 ;
// The TinyGPS++ object
TinyGPSPlus gps;
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
bool setPowerBoostKeepOn(int en) {
I2CPower.beginTransmission(IP5306_ADDR);
I2CPower.write(IP5306_REG_SYS_CTL0);
if (en) {
I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else {
I2CPower.write(0x35); // 0x37 is default reg value
}
return I2CPower.endTransmission() == 0;
}
void setup() {
// Set serial monitor debugging window baud rate to 115200
SerialMon.begin(115200);
if (Display_config == 1)
{
Display_init();
mainconfig();
}
// Keep power when running from battery
bool isOk = setPowerBoostKeepOn(1);
SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));
if (HTTP_config == 1)
{
HTTP_init();
}
if (GPS_config == 1)
{
GPS_init();
}
// Configure the wake up source as timer wake up
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
}
void loop() {
if (GPS_config == 1)
{
printInt(gps.satellites.value(), gps.satellites.isValid(), 5);
printFloat(gps.hdop.hdop(), gps.hdop.isValid(), 6, 1);
printFloat(gps.location.lat(), gps.location.isValid(), 11, 6);
printFloat(gps.location.lng(), gps.location.isValid(), 12, 6);
printInt(gps.location.age(), gps.location.isValid(), 5);
printDateTime(gps.date, gps.time);
printFloat(gps.altitude.meters(), gps.altitude.isValid(), 7, 2);
printFloat(gps.course.deg(), gps.course.isValid(), 7, 2);
printFloat(gps.speed.kmph(), gps.speed.isValid(), 6, 2);
printStr(gps.course.isValid() ? TinyGPSPlus::cardinal(gps.course.deg()) : "*** ", 6);
//printlong(gps.time.hour());
// printlong(gps.time.minute());
dtostrf(gps.location.lat(), 4, 3, gpsLat);
dtostrf(gps.location.lat(), 4, 8, gpsLat_full);
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, gpsLat);
display.setFont(ArialMT_Plain_10);
display.drawString(50, 19, "°N");
dtostrf(gps.location.lng(), 4, 3, gpsLong);
dtostrf(gps.location.lng(), 4, 8, gpsLong_full);
display.setFont(ArialMT_Plain_16);
display.drawString(64, 15, gpsLong);
display.setFont(ArialMT_Plain_10);
display.drawString(110, 19, "°E");
dtostrf(gps.altitude.meters(), 4, 0, gpsAltitude);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 30, gpsAltitude);
display.drawString(50, 30, "m");
dtostrf(gps.speed.kmph(), 4, 0, gpsSpeed);
display.setFont(ArialMT_Plain_10);
display.drawString(64, 30, gpsSpeed);
display.drawString(100, 30, "km/h");
dtostrf(gps.time.hour(), 2, 0, gpsHour);
dtostrf(gps.time.minute(), 2, 0, gpsMinute);
track_minute = gps.time.minute();
display.drawString(95, 0, gpsHour);
display.drawString(106, 0, ":");
display.drawString(110, 0, gpsMinute);
if ( gps.satellites.value() != 0) {
for (int compteur = 0 ; compteur < gps.satellites.value() ; compteur++)
{
display.fillCircle(compteur * 10, 5, 3);
}
} else {
display.drawCircle(random(1, 100), 5, 3);
}
// write the buffer to the display
display.display();
unsigned long distanceKmToLondon =
(unsigned long)TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON) / 1000;
printInt(distanceKmToLondon, gps.location.isValid(), 9);
double courseToLondon =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
LONDON_LAT,
LONDON_LON);
printFloat(courseToLondon, gps.location.isValid(), 7, 2);
const char *cardinalToLondon = TinyGPSPlus::cardinal(courseToLondon);
printStr(gps.location.isValid() ? cardinalToLondon : "*** ", 6);
printInt(gps.charsProcessed(), true, 6);
printInt(gps.sentencesWithFix(), true, 10);
printInt(gps.failedChecksum(), true, 9);
Serial.println();
smartDelay(1000);
if (millis() > 5000 && gps.charsProcessed() < 10) {
Serial.println(F("No GPS data received: check wiring"));
display.setFont(ArialMT_Plain_10);
display.drawString(0, 45, "GPS");
display.drawLine(0, 50, 22, 50);
display.display();
} else {
display.setFont(ArialMT_Plain_10);
display.drawString(0, 45, "GPS");
display.display();
}
}
if (HTTP_config == 1)
{
if (gps.satellites.value() != 0) {
display.setFont(ArialMT_Plain_10);
display.drawString(30, 45, "SAT");
display.display();
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass)) {
SerialMon.println(" fail");
//display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(60, 45, "HTTP");
display.drawLine(60, 50, 80, 50);
display.display();
}
else {
SerialMon.println(" OK");
//display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(60, 45, "HTTP");
display.display();
SerialMon.print("Connecting to ");
SerialMon.print(server);
if (!client.connect(server, port)) {
SerialMon.println(" fail");
display.setFont(ArialMT_Plain_10);
display.drawString(90, 45, "PORT");
display.drawLine(90, 50, 110, 50);
display.display();
}
else {
SerialMon.println(" OK");
display.setFont(ArialMT_Plain_10);
display.drawString(90, 45, "PORT");
display.display();
// Making an HTTP POST request
SerialMon.println("Performing HTTP POST request...");
// Prepare your HTTP POST request data (Temperature in Celsius degrees)
String httpRequestData = "apikey=" + apiKeyValue + "&type=cmd&id=13420&slider=" + gpsLat_full + "," + gpsLong_full + "," + gpsSpeed + "," + gpsAltitude;
//String httpRequestData = "apikey=" + apiKeyValue + "&type=cmd&id=13422&slider=" + gpsLong_full;
SerialMon.println("httpRequestData :" + httpRequestData);
client.print(String("POST ") + resource + " HTTP/1.1\r\n");
client.print(String("Host: ") + server + "\r\n");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(httpRequestData.length());
client.println();
client.println(httpRequestData);
unsigned long timeout = millis();
while (client.connected() && millis() - timeout < 10000L) {
// Print available data (HTTP response from server)
while (client.available()) {
char c = client.read();
SerialMon.print(c);
timeout = millis();
}
}
SerialMon.println();
// Close client and disconnect
client.stop();
SerialMon.println(F("Server disconnected"));
modem.gprsDisconnect();
SerialMon.println(F("GPRS disconnected"));
}
}
} else {
display.setFont(ArialMT_Plain_10);
display.drawString(30, 45, "SAT");
display.drawLine(30, 50, 50, 50);
display.display();
}
}
delay (TIME_TO_SLEEP * 1000);
// Put ESP32 into deep sleep mode (with timer wake up)
//esp_deep_sleep_start();
}
// This custom version of delay() ensures that the gps object
// is being "fed".
static void smartDelay(unsigned long ms)
{
unsigned long start = millis();
do
{
while (ss.available())
gps.encode(ss.read());
} while (millis() - start < ms);
}
static void printFloat(float val, bool valid, int len, int prec)
{
if (!valid)
{
while (len-- > 1)
Serial.print('*');
Serial.print(' ');
}
else
{
Serial.print(val, prec);
int vi = abs((int)val);
int flen = prec + (val < 0.0 ? 2 : 1); // . and -
flen += vi >= 1000 ? 4 : vi >= 100 ? 3 : vi >= 10 ? 2 : 1;
for (int i = flen; i < len; ++i)
Serial.print(' ');
}
smartDelay(100);
}
static void printInt(unsigned long val, bool valid, int len)
{
char sz[32] = "*****************";
if (valid)
sprintf(sz, "%ld", val);
sz[len] = 0;
for (int i = strlen(sz); i < len; ++i)
sz[i] = ' ';
if (len > 0)
sz[len - 1] = ' ';
Serial.print(sz);
smartDelay(100);
}
static void printDateTime(TinyGPSDate &d, TinyGPSTime &t)
{
if (!d.isValid())
{
Serial.print(F("********** "));
}
else
{
char sz[32];
sprintf(sz, "%02d/%02d/%02d ", d.month(), d.day(), d.year());
Serial.print(sz);
}
if (!t.isValid())
{
Serial.print(F("******** "));
}
else
{
char sz[32];
sprintf(sz, "%02d:%02d:%02d ", t.hour(), t.minute(), t.second());
Serial.print(sz);
}
printInt(d.age(), d.isValid(), 5);
smartDelay(100);
}
static void printStr(const char *str, int len)
{
int slen = strlen(str);
for (int i = 0; i < len; ++i)
Serial.print(i < slen ? str[i] : ' ');
smartDelay(100);
}
void Display_init() {
// Init display
display.init();
display.flipScreenVertically();
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "GPS Tracker");
display.display();
delay(1000);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "START");
display.display();
delay(1000);
display.setFont(ArialMT_Plain_24);
display.drawString(0, 35, "V0.1");
display.display();
delay(1000);
}
void mainconfig() {
display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Display config...");
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "GPS : " + String(GPS_config));
display.drawString(0, 30, "HTTP : " + String(HTTP_config));
display.drawString(64, 15, "Oled :" + String(Display_config));
display.drawString(64, 30, "Full :" + String(Full_config));
//bool res = modem.sendSMS(SMS_TARGET_SET, "Full :" + String(Full_config));
//DBG("SMS:", res ? "OK" : "fail");
display.display();
delay(3000);
}
void GPS_init() {
ss.begin(GPSBaud);
Serial.println();
Serial.println(F("----------------------------------------------------------------------------------------------------------------------------------------"));
Serial.println(F("Sats HDOP Latitude Longitude Fix Date Time Date Alt Course Speed Card Distance Course Card Chars Sentences Checksum"));
Serial.println(F(" (deg) (deg) Age Age (m) --- from GPS ---- ---- to London ---- RX RX Fail"));
// Start power management
if (setupPMU() == false) {
Serial.println("Setting power error");
display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Setup GPS");
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "Setting power error");
display.display();
delay(1000);
}
}
void HTTP_init() {
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
display.clear();
display.setFont(ArialMT_Plain_10);
display.drawString(0, 0, "Setup Http");
display.setTextAlignment(TEXT_ALIGN_LEFT);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 15, "Initializing modem... : ");
display.display();
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Restart SIM800 module, it takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// use modem.init() if you don't need the complete restart
display.setFont(ArialMT_Plain_16);
display.drawString(0, 30, "Restart");
display.display();
if (strlen(simPIN) && modem.getSimStatus() != 3 ) {
modem.simUnlock(simPIN);
display.setFont(ArialMT_Plain_16);
display.drawString(0, 45, "Unlock");
display.display();
}
}
Latitude, longitude, vitesse, altitude
47.25____,-1.55___, 0___, 44____
Ceci sans abonnement, les données sont transmises en GRPS (équivalent 2G)
C'est une version Beta fonctionnelle
swr85- Habitué
- Moto : à définir
Localisation : Nantes
j'ai un problème de connection au réseau
Bonjour @swr85,swr85 a écrit:Bonsoir,
Cela commence a ressembler à quelque chose
Voici le montage
Message "Welcome..." lorsque la Sim se connecte au réseau GSM, il suffit d'envoyer track pour recevoir un SMS en retour avec la position
Bravo pour ce beau projet !
j'ai exactement le même matériel, module GPS NEO + module ESP32 SIM800, j'utilise aussi APN de SFR =sl2sfr; mais je n'arrive pas à me connecter au réseau GSM
-Je travaille sous PlatformIO et mon 1er test est pour envoyer simplement un sms https://randomnerdtutorials.com/esp32-sim800l-send-text-messages-sms/
Je lisais qu'il fallait alimenter le module ESP+sim800 sous 5V 2A avec une batterie, car via le port USB-C ça ne fonctionnerait pas, pourtant sur votre photo je crois bien voir un cable USB ?
Je ne sais si c'est un problème de programme ou de captage du réseau : même en posant le module sur la terrasse la connexion ne se fait pas.
Pourriez-vous m'aider svp ?
laRob- En rodage
- Moto : ---
Localisation : laroque
Re: Tracker GPS, sur base ESP32
Bonsoir,
Tu peux résoudre le problème d'appel de courant par un condenseur à l'entrée du module sim800l.
Autrement, j'utilise le petit écran oled lorsque les appels de courant sont trop importants.
En alternative la carte lilygo est plus optimisé et gère mieux l'appel de courant.
Actuellement, j'ai une version OTA qui m'évite de le connecter au port USB.
Je peux la partager si tu veux
Tu peux résoudre le problème d'appel de courant par un condenseur à l'entrée du module sim800l.
Autrement, j'utilise le petit écran oled lorsque les appels de courant sont trop importants.
En alternative la carte lilygo est plus optimisé et gère mieux l'appel de courant.
Actuellement, j'ai une version OTA qui m'évite de le connecter au port USB.
Je peux la partager si tu veux
swr85- Habitué
- Moto : à définir
Localisation : Nantes
Page 1 sur 2 • 1, 2
Sujets similaires
» Tracker GPS Invoxia
» Kawasaki D-Tracker
» Une MT façon tracker
» Bluroc tracker 125
» Honda CLR en Street Tracker
» Kawasaki D-Tracker
» Une MT façon tracker
» Bluroc tracker 125
» Honda CLR en Street Tracker
Page 1 sur 2
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum