zs6buj / AntTracker

Antenna Tracker for tracking a moving model aircraft or drone with a small high-gain UHF or SHF antenna
GNU General Public License v3.0
155 stars 42 forks source link

Support for ELRS Backpack ESP-NOW protocol #80

Open axljackass opened 4 months ago

axljackass commented 4 months ago

Any plans to have SPI input connection?

Edit: Support for ESP-Now protocol

zs6buj commented 4 months ago

Can you share specifications with me. Not SPI, but the backpack?

axljackass commented 4 months ago

All the detailed info from here

https://www.expresslrs.org/software/backpack-telemetry/

HKR1987 commented 4 months ago

it will be cool! but why SPI? it working wireless via espnow protocol

axljackass commented 4 months ago

Apology, got confused between Backpack Telemetry and Backpack for VRX https://www.expresslrs.org/hardware/backpack/esp-backpack/

I also checked the Sentinel AAT procedure, it does not mention for ELRS RX, so its only using esp-now protocol.

If you can manage to implement the esp-now protocol it would be perfect.

zs6buj commented 4 months ago

Ah, ok, we can do this. But give me a bit of time. I have some other things in the queue :)

axljackass commented 4 months ago

Here we go....... Very excited with this.

Thank you so much....

zs6buj commented 3 months ago

v2.22.02 ESP_NOW backpack is coded but not tested. Testers would be much appreciated and likely to speed up delivery of the final version.

HKR1987 commented 3 months ago

Ok, i have happymodel es24tx pro. Already flashed backpack, but how i can bind my tx with esp? There is only option to tun on telemetry. How this will work?

zs6buj commented 3 months ago

Like you I'm learning as we move forward. ESP_NOW works on MAC addresses for point-to-point, but it can also broadcast. Since you have a backpack, can you shed some more light on the interface?

HKR1987 commented 3 months ago

I think we need get one more esp. Like sentinel antenna tracker has additional esp12 bacpack which need to flash with elrs backpack firmware. Or buy compatible rx like happymodel ep82. Or (best solution) implement something like expresselrs has in backpack to bind with TX backpack. when flashing backpack there is option to write bind phrase but no place for write mac address

Source: https://www.expresslrs.org/software/backpack-telemetry

HKR1987 commented 3 months ago

Maybe this PR will be helpful - its add firmware for MFD crossbow tracker backpack.

https://github.com/ExpressLRS/Backpack/pull/150

HKR1987 commented 3 months ago

This is what they do :)

Screenshot_20240825-154828_Discord_1.png

HKR1987 commented 3 months ago

Im not developer but it must be this function: SetSoftMACAddress() In https://github.com/ExpressLRS/Backpack/blob/master/src/Vrx_main.cpp

zs6buj commented 3 months ago

This is great feedback, thank you. I understand that they hash the MAC with your binding phrase to create a pseudo MAC. I can't look right now, but tomorrow for sure

zs6buj commented 3 months ago

The important parts of this function appear to be:

memcpy(firmwareOptions.uid, config.GetGroupAddress(), 6);

  // MAC address can only be set with unicast, so first byte must be even, not odd
  firmwareOptions.uid[0] = firmwareOptions.uid[0] & ~0x01;

esp_wifi_set_mac(WIFI_IF_STA, firmwareOptions.uid);

Six bytes from GroupAddress, stored in EEPROM, are moved to firmwareOptions.uid. (uid == unique identifier). Then the first byte is AND with 0x01, and those 6 bytes are used to set the wifi custom mac.

So I assume the hashed mac is already sitting in non-volatile memory, in config / GroupAddress

zs6buj commented 3 months ago

GroupAddress is set during binding, with this line in the code snippet below:

config.SetGroupAddress(packet->payload);

void ProcessMSPPacket(mspPacket_t *packet)
{
  if (connectionState == binding)
  {
    DBGLN("Processing Binding Packet...");
    if (packet->function == MSP_ELRS_BIND)
    {
      config.SetGroupAddress(packet->payload);
      DBGLN("MSP_ELRS_BIND MAC = ");
      for (int i = 0; i < 6; i++)
      {
        DBG("%x", packet->payload[i]); // Debug prints
        DBG(",");
      }
      DBG(""); // Extra line for serial output readability
      resetBootCounter();
      connectionState = running;
      rebootTime = millis() + 200; // Add 200ms to allow for any response message(s) to be sent back to device
    }
    return;
  }
zs6buj commented 3 months ago

The ESP_Now callback function is this one, I think:

void OnDataRecv(uint8_t * mac_addr, uint8_t *data, uint8_t data_len)
#elif defined(PLATFORM_ESP32)
void OnDataRecv(const uint8_t * mac_addr, const uint8_t *data, int data_len)
#endif
{
  DBGVLN("ESP NOW DATA:");
  for(int i = 0; i < data_len; i++)
  {
    DBGV("%x,", data[i]); // Debug prints

    if (msp.processReceivedByte(data[i]))
    {
      DBGVLN(""); // Extra line for serial output readability
      // Finished processing a complete packet
      // Only process packets from a bound MAC address
      if (connectionState == binding ||
            (
            firmwareOptions.uid[0] == mac_addr[0] &&
            firmwareOptions.uid[1] == mac_addr[1] &&
            firmwareOptions.uid[2] == mac_addr[2] &&
            firmwareOptions.uid[3] == mac_addr[3] &&
            firmwareOptions.uid[4] == mac_addr[4] &&
            firmwareOptions.uid[5] == mac_addr[5]
            )
          )
      {
        gotInitialPacket = true;
        #if defined(PLATFORM_ESP8266)
          ProcessMSPPacket(msp.getReceivedPacket());
        #elif defined(PLATFORM_ESP32)
          xQueueSend(rxqueue, msp.getReceivedPacket(), (TickType_t)1024);
        #endif
      }
      else
      {
        DBGLN("Failed MAC add check and not in bindingMode.");
      }
      msp.markPacketReceived();
    }
  }
  blinkLED();
}
zs6buj commented 3 months ago

So during the binding phase, the first ESP_NOW packet seems to have the spoofed MAC, and it is stored in NVM.

Maybe I can write a some code for you to flash that will print out all ESP_Now packets. Or you could flash backpack with DBG enabled.

HKR1987 commented 3 months ago

i dont know how to flash backpack with DBG and how read it, but if you point me i can do it

zs6buj commented 3 months ago

You need to install VS_Code, and then the ESP-IDE extension from inside VS_Code.

https://code.visualstudio.com/docs/setup/setup-overview

https://docs.espressif.com/projects/esp-idf/en/v4.2.3/esp32/get-started/vscode-setup.html

Assuming you have cloned https://github.com/ExpressLRS/Backpack/tree/master to your local drive, then open the whole "Backpack" folder from VSC (File/Open folder), then click the tick to build, and the right arrow to flash.

image

on the bottom line

image

It might take a while to download and build all the dependencies.

There is a fairly steep learning curve, but if you are interested in learning to code it is a good step forward.

zs6buj commented 3 months ago

The above might be a bit too much to start with. Maybe I can give you a binary to flash with the ESP Flash Tool.

HKR1987 commented 3 months ago

uid is generated from passphrase https://www.expresslrs.org/hardware/spi-receivers/#uid-byte-generator we can make it manual from this generator. UID is using as mac.... right?

HKR1987 commented 3 months ago

i found in betafligh repo nice function to calculate uid from passphrase part used for testing (passpharse: test123): obraz first we need md5 from this sentence: -DMY_BINDING_PHRASE="test123" obraz than this function: obraz

const hash = "80fe61c57179a1a472e1c0c83fe13bea";
const bytes = hash.match(/.{1,2}/g).map(byte => parseInt(byte, 16));
const view = new DataView(new ArrayBuffer(6));
            for (let i = 0; i < 6; i++) {
                view.setUint8(i, bytes[i]);
            }
            uidBytes = Array.from(new Uint8Array(view.buffer));
alert(uidBytes);

and we get the UID :) Function from BF configurator https://github.com/betaflight/betaflight-configurator/blob/master/src/js/tabs/receiver.js elrsBindingPhraseToBytes(text)

HKR1987 commented 3 months ago

You need to install VS_Code, and then the ESP-IDE extension from inside VS_Code.

https://code.visualstudio.com/docs/setup/setup-overview

https://docs.espressif.com/projects/esp-idf/en/v4.2.3/esp32/get-started/vscode-setup.html

Assuming you have cloned https://github.com/ExpressLRS/Backpack/tree/master to your local drive, then open the whole "Backpack" folder from VSC (File/Open folder), then click the tick to build, and the right arrow to flash.

image

on the bottom line

image

It might take a while to download and build all the dependencies.

There is a fairly steep learning curve, but if you are interested in learning to code it is a good step forward.

what we need to obtain from it?

zs6buj commented 3 months ago

Nice. I will look at this.

zs6buj commented 3 months ago

I've been reading here, and think my next step is to setup backpack here for myself. I have a Happymodel ES24TX, so if I flash it with the latest firmware I should be able to do some live testing.

pki791 commented 2 months ago

Hi. I have used the u360gts tracker. Its not in active development, but worked quite ok. Now after i switched to ExpressLRS i can see backpack functionallity. I was able to get the data from the backpack by installing the MFD Crossbow into an ESP32 C3. Link: https://www.expresslrs.org/software/mfd-crossbow/

Now that outputs all data in MavLink v2 protocol, i think that data can be used to get the location by Your tracker. Also the source code should be in github, requires version 3.5.0 and backpack 1.5. Maybe this can help You to integrate the reciever?

I can help in testing if wanted as my backpack setup is ready and working (on bench).

I use the old FLIP32 board (NAZE32) to control by tracker. I think its time to update it with an ESP32, just interesting if the C3 Super Mini can be enough to drive it? 2 pins for I2C (LCD and compass) 2 pins for servos 2 pins for GPS

zs6buj commented 2 months ago

Family obligations have kept my occupied this last week, but yesterday I separated out the RX5808 backpack code into a free standing project, built and flashed. I also updated my Happymodel ES24TX Pro firmware to v 3.4.3. So now I have something to work with, and I can see what is required, and can test a solution.

pki791 Thank you very much for this steer. It should also be very helpful. It sounds like a nice project, and I understand outputs the mavlink gps messages, and perhaps some others.

To reiterate: By including the esp_now backpack "receiver" into the tracker, we want to eliminate having an outboard piggyback/backpack board in between to supply gps, barometric and compass data. Our esp_now receiver must be bound to the backpack in back of the transmitter bay to provide security and eliminate cross-talk with other equipment on site.

zs6buj commented 2 months ago

I got onto this again today, only to find that my Happymodel ES24TX Pro is an early model and does not have the ESP8285 backpack chip! I'll see if I can get a newer one.

pki791 commented 2 months ago

I got onto this again today, only to find that my Happymodel ES24TX Pro is an early model and does not have the ESP8285 backpack chip! I'll see if I can get a newer one.

Thats shit, if You have something what i can load into ESP32 C3 (i can share You some demo bind code) then i can test if it works getting the ESPNOW messages.

zs6buj commented 2 months ago

Ok, please share your demo code and I will do an esp_now version for esp32 c3

pki791 commented 2 months ago

Ok, please share your demo code and I will do an esp_now version for esp32 c3

i send it to Your email

zs6buj commented 2 months ago

I should get this done today.

zs6buj commented 2 months ago

Whoo Hoo! Progress..

12:03:51.333 -> 12:03:51.333 -> Starting ESP_NOW Receiver 12:03:51.333 -> EEPROM initialised 12:03:51.333 -> macToEeprom() 12:03:51.333 -> eeprom[0]:fd 12:03:51.333 -> 1:208,2:200,3:225,4:230,5:184,6:24, 12:03:51.333 -> eepromToMac() 12:03:51.333 -> eeprom soft_mac found 12:03:51.333 -> 1:208,2:200,3:225,4:230,5:184,6:24, 12:03:51.413 -> [ 2632][W][WiFiGeneric.cpp:639] setTxPower(): Neither AP or STA has been started 12:03:51.470 -> [ 2643][W][STA.cpp:537] disconnect(): STA already disconnected. 12:03:51.470 -> Soft-set the MAC address to the passphrase UID for binding 12:03:51.470 -> =========== After Setup Start ============ 12:03:51.470 -> INTERNAL Memory Info: 12:03:51.470 -> ------------------------------------------ 12:03:51.470 -> Total Size : 328164 B ( 320.5 KB) 12:03:51.470 -> Free Bytes : 249996 B ( 244.1 KB) 12:03:51.470 -> Allocated Bytes : 68376 B ( 66.8 KB) 12:03:51.470 -> Minimum Free Bytes: 249488 B ( 243.6 KB) 12:03:51.484 -> Largest Free Block: 110580 B ( 108.0 KB) 12:03:51.484 -> ------------------------------------------ 12:03:51.484 -> GPIO Info: 12:03:51.484 -> ------------------------------------------ 12:03:51.484 -> GPIO : BUS_TYPE[bus/unit][chan] 12:03:51.484 -> --------------------------------------
12:03:51.484 -> 1 : UART_TX[0] 12:03:51.484 -> 3 : UART_RX[0] 12:03:51.484 -> 17 : GPIO 12:03:51.484 -> ============ After Setup End ============= 12:03:51.618 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E2 00 64 0C 00 07 02 E7 64 0C 4D 81 12:03:51.869 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E1 00 64 0B 00 07 02 E6 64 0C BB 81 12:03:52.117 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E1 00 64 0B 00 07 02 E4 64 0D BD 81 12:03:52.333 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E1 00 64 0C 00 07 02 E7 64 0C 7E 81 12:03:52.413 -> ESP_Now bytes len:19 24 58 3C 00 11 00 0A 00 EA 08 1E 01 5D 79 D5 CF BC E3 9F 12:03:52.583 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E1 00 64 0C 00 07 02 E4 64 0C 2E 81 12:03:52.831 -> ESP_Now bytes len:23 24 58 3C 00 11 00 0E 00 EA 0C 14 E2 00 64 0C 00 07 02 E4 64 0C 1D 81

These are the CRSF data frames: EA 0C 14 E2 00 64 0C 00 07 02 E7 64 0C 4D 81

zs6buj commented 2 months ago

ESPNow_Backpack_Decode_01.zip

You can try the above, but just change line 27 to include your (hashed) binding phrase

uint8_t piotrs_soft_mac[6] = {};
uint8_t erics_soft_mac[6] = {208,200,225,230,184,24}; // testing only

and line 150

macToEeprom(erics_soft_mac);

change to

macToEeprom(piotrs_soft_mac);

Results look like this:

Starting ESP_NOW Receiver EEPROM initialised macToEeprom() eeprom[0]:fd 1:208,2:200,3:225,4:230,5:184,6:24, eepromToMac() eeprom soft_mac found 1:208,2:200,3:225,4:230,5:184,6:24, MAC address soft-set to the passphrase UID

FLIGHT_MODE id:21 lth:5 WAIT motArmed:0 CRSF_GPS:02 lat:0.0000000 lon:0.0000000 ground_spd:0.0km/hr hdg:0.00deg alt:0m sats:0 gpsfixGood:0 BATTERY id:08 volts:0.0 amps:0.0 Ah_drawn:0.0 remaining: 0% ATTITUDE id:1E pitch:0.7deg roll:177.2deg yaw:332.0deg FLIGHT_MODE id:21 lth:5 WAIT motArmed:0 CRSF_GPS:02 lat:0.0000000 lon:0.0000000 ground_spd:0.0km/hr hdg:0.00deg alt:0m sats:0 gpsfixGood:0 BATTERY id:08 volts:0.0 amps:0.0 Ah_drawn:0.0 remaining: 0% ATTITUDE id:1E pitch:0.7deg roll:177.2deg yaw:332.0deg

zs6buj commented 2 months ago

My GPS is indoors, so lat/lon is 0

pki791 commented 2 months ago

Seems missing terseCRSF.h: No such file or directory

zs6buj commented 2 months ago

Please install terseCRSF library in your Arduino IDE. It is in zs6buj github

pki791 commented 2 months ago

Please install terseCRSF library in your Arduino IDE. It is in zs6buj github

Yep, dont know how to install that lib in the arduino 2.3.2 ide, but i copied the files from github and it compiles. Now that ESP32-C3 seems to be in bootloop, maybe i have some settings from the board wrong, need to figure it out. Do we have any other channel of communication to not spam here soo much? I send You email yesterday.

pki791 commented 2 months ago

OK, got it working.

I needed to change the LED pin:

const uint8_t ledPin = LED_BUILTIN;

Works like it should.

CRSF_BUF:EA 07 21 57 41 49 54 00 AD 6A 00 00 00 DD 60 5B 5E 45 
FLIGHT_MODE id:21 lth:4 WAIT motArmed:0
CRSF_BUF:EA 04 07 00 04 DD 60 00 00 6A 00 00 00 DD 60 
CF_VARIO:EA 04 07 00 04 DD 60 00 00 6A 00 00 00 DD 60 
CRSF_BUF:EA 0C 14 CB 00 64 0D 00 05 02 BE 60 0D F4 81 00 00 45 87 7E 8A F8 EC 
CRSF_BUF:EA 11 02 20 40 B6 A8 0A B3 AC ED 00 00 4E 48 03 E8 00 0F CC 00 F8 EC 2A 17 75 AB 39 
CRSF_GPS:02 lat:**.1111984  lon:**.9547367  ground_spd:0.0km/hr  hdg:200.40deg  alt:0m  sats:0  gpsfixGood:0
CRSF_BUF:EA 0A 08 00 00 00 00 00 00 00 00 6D 1F 4E 48 03 E8 00 0F CC 00 
BATTERY id:08 volts:0.0  amps:0.0  Ah_drawn:0.0  remaining:  0%
CRSF_BUF:EA 08 1E 10 D6 00 8B 40 B3 A9 9F 00 00 4E 48 03 E8 00 0F 
ATTITUDE id:1E pitch:24.7deg  roll:0.8deg  yaw:94.0deg
CRSF_BUF:EA 07 21 57 41 49 54 00 AD 6A 00 00 00 4E 48 03 E8 00 
FLIGHT_MODE id:21 lth:4 WAIT motArmed:0
CRSF_BUF:EA 0C 14 CB 00 64 0D 00 05 02 BA 64 0C 7E 81 00 00 00 0F CC 00 F8 EC 
CRSF_BUF:EA 04 07 00 05 08 60 00 00 02 BA 64 0C 7E 81 
CF_VARIO:EA 04 07 00 05 08 60 00 00 02 BA 64 0C 7E 81 
CRSF_BUF:EA 11 02 20 40 B5 23 0A B3 AC 54 00 00 4E 48 03 E8 00 80 CC 00 F8 EC 2A 17 75 AB 39 
CRSF_GPS:02 lat:**.1111603  lon:**.9547215  ground_spd:0.0km/hr  hdg:200.40deg  alt:0m  sats:0  gpsfixGood:0
CRSF_BUF:EA 0A 08 00 00 00 00 00 00 00 00 6D 1F 4E 48 03 E8 00 80 CC 00 
BATTERY id:08 volts:0.0  amps:0.0  Ah_drawn:0.0  remaining:  0%
CRSF_BUF:EA 0C 14 CB 00 64 0D 00 05 02 C3 64 0D 81 81 00 00 00 80 CC 00 F8 EC 
CRSF_BUF:EA 08 1E 10 D6 00 8B 40 A1 84 9F 00 00 81 81 00 00 00 80 
ATTITUDE id:1E pitch:24.7deg  roll:0.8deg  yaw:94.0deg
CRSF_BUF:EA 07 21 57 41 49 54 00 AD 6A 00 00 00 81 81 00 00 00 
FLIGHT_MODE id:21 lth:4 WAIT motArmed:0
CRSF_BUF:EA 04 07 00 04 DD 60 00 00 6A 00 00 00 81 81 
CF_VARIO:EA 04 07 00 04 DD 60 00 00 6A 00 00 00 81 81 
CRSF_BUF:EA 0C 14 CB 00 64 0D 00 05 02 C1 60 0C AB 81 00 00 00 80 CC 00 F8 EC 
CRSF_BUF:EA 11 02 20 40 B3 EB 0A B3 AB E6 00 00 4E 48 03 E8 00 C2 CC 00 F8 EC 2A 17 75 AB 39 
CRSF_GPS:02 lat:**.1111259  lon:**.9547119  ground_spd:0.0km/hr  hdg:200.40deg  alt:0m  sats:0  gpsfixGood:0
zs6buj commented 2 months ago

Good to see. So here we are manually coding the soft mac. I will move this code into the Tracker next. After that, I will work on binding, so we automatically get the soft mac from the backpack tx.

Yes, by all means use my email.

pki791 commented 2 months ago

I think it is okay to enter the hash in the config, there can be many trackers and backpacks on one field, that we do on meetings so autodetecting would be a bad idea, beside it detects the bind once and then saves. Also i see the location looks fine, but sats should not be "0".

zs6buj commented 2 months ago

Ok, I'll look at SATs. Noted on the binding issue. You would normally bind at home, one time.

zs6buj commented 2 months ago

v2.22.03 on GitHub. Added support for hashed binding phase soft_mac

HKR1987 commented 2 months ago

I test it and something wrong. My backpack wont bind with tracker. What im need to write in my_hashed_ma? This is raw bind phrase from configurator or need some calculation?

zs6buj commented 2 months ago

Go into configurator, then pretend you want to flash backpack, look for MAC

HKR1987 commented 2 months ago

You mean UID? As is or need some calculation? Mac address can be three digits? Screenshot_20240905-192223_Firefox.png

zs6buj commented 2 months ago

6 bytes represented by these 6 numbers between commas

Screenshot_20240905_205411_Edge.jpg

zs6buj commented 2 months ago

Yes, UID

zs6buj commented 2 months ago

I just pushed v2.22.03c which prevents mac of 0:0:0:0:0:0.

Please clone and rather use it.