/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Used with ESP32 + BN220, modified by Julien Launay 14/09/2020 Using https://github.com/khancyr/TTGO_T_BEAM/tree/master/src. Thanks to Pierre Khancyr the original author of this project. With https://github.com/f5soh/balise_esp32/blob/droneID_FR_testing/droneID_FR.h Connect ESP32 Pin16 (Rx)-> BN220 white wire (Tx) Connect ESP32 Pin17 (Tx)-> BN220 green wire (Rx) */ #include #include //#include #include #include "droneID_FR.h" extern "C" { #include "esp_wifi.h" esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len, bool en_sys_seq); } #define UBLOX_GPS_OBJECT() TinyGPSPlus gps #define GPS_BANUD_RATE 9600 #define GPS_RX_PIN 16 #define GPS_TX_PIN 17 #define PMU_IRQ 35 #define GPS_POWER_CTRL_CH 3 UBLOX_GPS_OBJECT(); droneIDFR drone_idfr; /******************************************************************************************************************** * MODIFIEZ LES VALEURS ICI ********************************************************************************************************************/ // Set these to your desired credentials. /** * Le nom du point d'acces wifi CHANGEZ LE par ce que vous voulez !!! */ const char ssid[] = "JLA_BALISE"; // Mot de pass du wifi const char *password = "123456789"; /** * CHANGEZ l'ID du drone par celui que Alphatango vous a fourni (Trigramme + Modèle + numéro série) ! */ const char drone_id[] = "JLAMOT000000PLANEUR4000-250000"; /********************************************************************************************************************/ // NE PAS TOUCHEZ A PARTIR D'ICI !!! // Le wifi est sur le channel 6 conformement à la spécification static constexpr uint8_t wifi_channel = 6; // Ensure the drone_id is max 30 letters static_assert((sizeof(ssid)/sizeof(*ssid))<=32, "AP SSID should be less than 32 letters"); // Ensure the drone_id is max 30 letters static_assert((sizeof(drone_id)/sizeof(*drone_id))<=31, "Drone ID should be less that 30 letters !"); // 30 lettres + null termination // beacon frame definition static constexpr uint16_t MAX_BEACON_SIZE = 40 + 32 + droneIDFR::FRAME_PAYLOAD_LEN_MAX; // default beaconPacket size + max ssid size + max drone id frame size uint8_t beaconPacket[MAX_BEACON_SIZE] = { 0x80, 0x00, // 0-1: Frame Control 0x00, 0x00, // 2-3: Duration 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 4-9: Destination address (broadcast) 0x24, 0x62, 0xab, 0xdd, 0xb0, 0xbd, // 10-15: Source address FAKE // TODO should bet set manually 0x24, 0x62, 0xab, 0xdd, 0xb0, 0xbd, // 16-21: Source address FAKE 0x00, 0x00, // 22-23: Sequence / fragment number (done by the SDK) 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 24-31: Timestamp (GETS OVERWRITTEN TO 0 BY HARDWARE) 0xB8, 0x0B, // 32-33: Beacon interval: set to 3s == 3000TU== BB8, bytes in reverse order // TODO: manually set it 0x21, 0x04, // 34-35: Capability info 0x03, 0x01, 0x06, // 36-38: DS Parameter set, current channel 6 (= 0x06), // TODO: manually set it 0x00, 0x20, // 39-40: SSID parameter set, 0x20:maxlength:content // 41-XX: SSID (max 32) }; bool has_set_home = false; double home_alt = 0.0; uint8_t program = 0; uint64_t dispMap = 0; String dispInfo; char buff[5][256]; uint64_t gpsSec = 0; bool pmu_irq = false; #define ARRARY_SIZE(a) (sizeof(a) / sizeof(a[0])) String baChStatus = "No charging"; String recv = ""; int8_t P1; uint64_t beaconSec = 0; const byte led_gpio = 2; //port number of the LED on the ESP32 GPIO2 bool stat_led = false; /** * Phase de configuration. */ void setup() { Serial.begin(115200); delay(1000); //initialisation du BN220. Bien penser à croiser Rx et Tx entre ESP32 et le BN220! Serial2.begin(GPS_BANUD_RATE, SERIAL_8N1, GPS_RX_PIN, GPS_TX_PIN); pinMode(led_gpio, OUTPUT); /******************************************************************************************************************** * ICI ON INITIALISE LE WIFI */ /** * Pour mon exemple, je crée un point d'accés. Il fait rien par defaut. */ Serial.println("Starting AP"); WiFi.softAP(ssid, nullptr, wifi_channel); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); Serial.print("AP mac address: "); Serial.println(WiFi.macAddress()); wifi_config_t conf_current; esp_wifi_get_config(WIFI_IF_AP, &conf_current); // Change WIFI AP default beacon interval sending to 1s. conf_current.ap.beacon_interval = 1000; drone_idfr.set_drone_id(drone_id); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &conf_current)); delay(2000); esp_err_t r = esp_wifi_get_max_tx_power(&P1); Serial.print("Tx power Value (dBm)="); Serial.println(P1*0.25); //check if Tansmit power is at his max (20 dBm -> 100mW) if (P1>77) { byte i; for(i=0;i<10;i++){ digitalWrite(led_gpio, HIGH); delay(50); digitalWrite(led_gpio, LOW); delay(50); } } } /** * Début du code principal. C'est une boucle infinie. */ void loop() { static uint64_t gpsMap = 0; switch (program) { case 0: // Ici on lit les données qui arrive du GPS et on les passes à la librairie TinyGPS++ pour les traiter while (Serial2.available()) gps.encode(Serial2.read()); // On traite le case ou le GPS a un probleme if (millis() > 5000 && gps.charsProcessed() < 10) { snprintf(buff[0], sizeof(buff[0]), "T-Beam GPS"); snprintf(buff[1], sizeof(buff[1]), "No GPS detected"); Serial.println(buff[1]); digitalWrite(led_gpio, HIGH); return; } // On traite le cas si la position GPS n'est pas valide if (!gps.location.isValid()) { if (millis() - gpsMap > 1000) { snprintf(buff[0], sizeof(buff[0]), "T-Beam GPS"); snprintf(buff[1], sizeof(buff[1]), "Positioning(%llu)", gpsSec++); Serial.println(buff[1]); digitalWrite(led_gpio, HIGH); gpsMap = millis(); delay(10); digitalWrite(led_gpio, LOW); } } else { // On traite le case si la position GPS est valide. // On renseigne le point de démarrage quand la précision est satisfaisante if (!has_set_home && gps.satellites.value() > 6 && gps.hdop.hdop() < 2.0) { Serial.println("Setting Home Position"); //drone_idfr.set_home_lat_lon(gps.location.lat(), gps.location.lng()); has_set_home = true; home_alt = gps.altitude.meters(); Serial.println("Altitude de départ="+String(home_alt)); drone_idfr.set_home_position(gps.location.lat(), gps.location.lng(), gps.altitude.meters()); digitalWrite(led_gpio, HIGH); //Blue Led onbord ON fixe, all is ok! } // On envoie les données a la librairie d'identification drone pour le formattage. drone_idfr.set_current_position(gps.location.lat(), gps.location.lng(), gps.altitude.meters()); drone_idfr.set_heading(gps.course.deg()); drone_idfr.set_ground_speed(gps.speed.mps()); drone_idfr.set_heigth(gps.altitude.meters() - home_alt); // Ici on ecrit sur le port USB les données GPS pour visualisation seulement. if (millis() - gpsMap > 1000) { snprintf(buff[0], sizeof(buff[0]), "UTC:%d:%d:%d", gps.time.hour(), gps.time.minute(), gps.time.second()); snprintf(buff[1], sizeof(buff[1]), "LNG:%.4f", gps.location.lng()); snprintf(buff[2], sizeof(buff[2]), "LAT:%.4f", gps.location.lat()); snprintf(buff[3], sizeof(buff[3]), "satellites:%u", gps.satellites.value()); Serial.println(buff[0]); Serial.println(buff[1]); Serial.println(buff[2]); Serial.println(buff[3]); gpsMap = millis(); } } break; } /** * On regarde s'il temps d'envoyer la trame d'identification drone: soit toutes les 3s soit si le drones s'est déplacé de 30m en moins de 3s. * - soit toutes les 3s, * - soit si le drone s'est déplacé de 30m en moins de 30s soit 10m/s ou 36km/h, * - uniquement si la position Home est déjà définie, * - et dans le cas où les données GPS sont nouvelles. */ if (drone_idfr.has_home_set() && drone_idfr.time_to_send()) { Serial.println("Send beacon"); // toggle the LED to see beacon sended if (stat_led) { digitalWrite(led_gpio, LOW); stat_led = false; } else { digitalWrite(led_gpio, HIGH); stat_led = true; } float time_elapsed = (float(millis() - beaconSec) / 1000); beaconSec = millis(); Serial.print(time_elapsed,1); Serial.print("s Send beacon: "); Serial.print(drone_idfr.has_pass_distance() ? "Distance" : "Time"); Serial.print(" with "); Serial.print(drone_idfr.get_distance_from_last_position_sent()); Serial.print("m Speed="); Serial.println(drone_idfr.get_ground_speed_kmh()); /** * On commence par renseigner le ssid du wifi dans la trame */ // write new SSID into beacon frame const size_t ssid_size = (sizeof(ssid)/sizeof(*ssid)) - 1; // remove trailling null termination beaconPacket[40] = ssid_size; // set size memcpy(&beaconPacket[41], ssid, ssid_size); // set ssid const uint8_t header_size = 41 + ssid_size; //TODO: remove 41 for a marker /** * On génère la trame wifi avec l'identfication */ const uint8_t to_send = drone_idfr.generate_beacon_frame(beaconPacket, header_size); // override the null termination // Décommenter ce block pour voir la trame entière sur le port usb /* Serial.println("beaconPacket : "); for (auto i=0; i