Micro Radar Flight Tracker with CYD

 

For this project I have updated and modified the code by Anthony Sturdy for ESP32 based flight tracker. Thanks to Anthony Sturdy for this open-source project. His github repository here.

I've modified the source code to directly upload to the  ESP32 CYD module and also you don't need any soldering for this project.

Core Hardware Specs of the module:

      ·         Microcontroller: ESP32-WROOM-32 (Dual-core 240 MHz, 520 KB SRAM, 4 MB Flash).
·         Connectivity: Built-in Wi-Fi and Bluetooth.
·         Display: 2.8-inch resistive touchscreen with 320 × 240 px resolution (ILI9341 display       driver, XPT2046 touch controller).
·         Expansion: MicroSD card slot for external storage, plus a few breakout headers for sensors   (e.g., DHT11) and extra GPIO pins.
·         Power: 5V operating voltage via micro-USB or type-C



Note: There are many clones of this board, you may buy the same model "ESP32-2432S028R" as I've used here to avoid setup error.

Source file:

Checkout my drive link here
Note: Two micro-radar-CYD files are given, v2 has some bugs fixed and rotating plane icon.

Setup guideline:

I have made a pdf guideline step by step so you do not have to go through troubles.
Checkout the guideline pdf drive link here

Troubleshooting: Screen orientation fix for some CYD boards

If your screen appears flipped or mirrored, open include/LGFX.h and find these three lines in the panel config block

Change their value to :

cfg.panel_width = 320;
cfg.panel_height = 240;
cfg.offset_rotation  = 7;
And reupload .

If you face any other error please feel free to send email with a subject "Micro Radar CYD" to abid.business01@gmail.com

Visit my YouTube channel 
Facebook page 

Comments

  1. Is that code correct as such...graphics look corrupted on 320x240 resolution?

    ReplyDelete
    Replies
    1. Code is correct, many of the viewers have made it work.

      Delete
    2. Ok, I see that the LGFX.h has correct width, height...I can see on Amazon that the board that I bought is said to have; Touch screen: ESP32-2432S028R and Driver Chip: ILI9341 . So these should work....but it justdoes not seem to get correct way on screen???

      Delete
    3. ok, managed to get it...but what ever reason, this seemed to work
      - swapping widt/height
      - rotation = 5
      - not sure if offset_x / y has any meaning

      LGFX.h
      ...
      cfg.panel_width = 320;
      cfg.panel_height = 240;
      cfg.offset_x = 0;
      cfg.offset_y = 0;
      cfg.offset_rotation = 5;
      ...

      I also comment out "tft.setRotation" on main.cpp, is that actually needed if the value is already set on LGFX.h ?

      Delete
    4. This comment has been removed by the author.

      Delete
    5. I can see small difference on your board pictures, one of them seems to have perhaps micro-usb power, and that usb is slightly side, but some are with usb-c and more middle...on my board is usb-c and usb is quite on middle also.

      Delete
    6. Thanks MarkoK, this fixed it for me as well, although it leaves the usb-c power at the top. I tried use rotation=7 to get the usb-c on the bottom but that messes up the graphics for whatever reason.

      Delete
    7. Yes, I have tried many combinations, but have not been able to find one that would flip the display 180 degrees, so that USB port would be down without messing the screen completely...

      Delete
  2. I'm having these two error come up when running the program: ** [.pio/build/esp32dev/libfd3/LovyanGFX/lgfx/utility/._lgfx_miniz.c.o] Error 1
    *** [.pio/build/esp32dev/libfd3/LovyanGFX/lgfx/Fonts/efont/._lgfx_efont_cn.c.o] Error 1

    ReplyDelete
    Replies
    1. Are you using Mac? Gemini was quessing following reason.

      "If you are working on a Mac (or using a project folder that was zipped/copied on a Mac), macOS automatically creates hidden metadata files called AppleDouble files that start with ._. PlatformIO sees these ghost files, thinks they are actual C source files, and tries to compile them. Because they just contain file metadata and not actual C code, the compiler panics and crashes."

      Delete
  3. Yes I was. I will switch to windows and run from that and see if it works. Thanks

    ReplyDelete
    Replies
    1. Got it! Works perfectly now. Thanks I did not know that about mac's making those ghost files.

      Delete
    2. You can use Mac also

      Step 1: Clean out the Mac ghost files
      ​You need to purge those hidden ._ files from your project directory.
      ​Open your terminal.
      ​Navigate (cd) into your project folder.
      ​ find and destroy all ._ files in your project directory

      Step 2: Nuke the build cache
      ​PlatformIO has already cached the bad build files, so you need to force it to start fresh.
      ​In VS Code: Click the PlatformIO icon (the alien head) on the left sidebar, expand your project env, and click Clean.
      ​Alternatively: Just manually delete the entire hidden .pio folder inside your project directory.

      Delete
  4. To change the units from meters to feet and meters/second to knots, you need to modify the DrawAircraftInfo function within the AircraftManager.cpp
    The current code displays the values directly from the OpenSky data, which is provided in meters and m/s. You just need to apply the math conversions and update the label strings.
    The Code Change

    Locate the DrawAircraftInfo function at the bottom of your file and replace it with this version:

    void AircraftManager::DrawAircraftInfo(LGFX_Sprite& backbuffer, int x, int y, const TrackedAircraft& tracked) const
    {
    const int lineHeight = tft.fontHeight() + 1;

    // Convert values
    // velocity is in m/s, convert to knots by multiplying by 1.94384
    float speedKnots = tracked.state.velocity * 1.94384f;

    // baroAltitude is in meters, convert to feet by multiplying by 3.28084
    float altitudeFt = tracked.state.baroAltitude * 3.28084f;

    backbuffer.setTextSize(1);
    backbuffer.setTextColor(lgfx::color888(0, 128, 0));

    backbuffer.drawString(tracked.state.callsign, x + 5, y + 5);

    // Display Speed in Knots
    backbuffer.drawString(String(speedKnots, 0) + "kts", x + 5, y + 5 + lineHeight);

    // Display Altitude in Feet
    backbuffer.drawString(String(altitudeFt, 0) + "ft", x + 5, y + 5 + lineHeight * 2);
    }

    ReplyDelete
    Replies
    1. Thank you so much for contributing this code. I'm not a coder but was able to do a copy and paste and recompile and it worked! My only problem now is that even after making the changes to the display specifications referenced up above my display is 180 degrees with the USB port on top and not the bottom. If you have any recomendations I sure would appreciate it.

      Delete
    2. This seems to be an issue, perhaps not all boards, but surprisingly many. I tried many combinations, but have not managed to flip screen 180 degrees.
      To my understanding that offset_rotation=7 should work...but some reason it doesn't...

      Delete
  5. I did some calculations to change the knots to mph but for whatever reason I dont think the aircraft listed on the radar is actually correct in mph. I show a Boeing flying at 450 kots and yet the radar is showing 267 MPH.. calculation is multipling by 1.151

    ReplyDelete
  6. Here is some direct replacement code for DrawAircraftIcon which will rotate the plane icon to the proper heading as opposed to the 4 cardinal directions. (if I knew how to use github I'd put in some sort of request there, but I don't so I didn't, but someone else feel free to).


    void AircraftManager::DrawAircraftIcon(LGFX_Sprite& backbuffer, int x, int y, const TrackedAircraft& tracked) const
    {
    // normalise heading into [0, 360)
    float heading = fmodf(tracked.state.trueTrack, 360.0f);
    if (heading < 0) heading += 360.0f;

    // Create a temporary sprite for the rotated image
    LGFX_Sprite rotated;
    rotated.setColorDepth(16);
    rotated.createSprite(PLANE_ICON_SIZE, PLANE_ICON_SIZE);

    // Set swap bytes on the temporary sprite before pushing the image
    rotated.setSwapBytes(true);
    rotated.pushImage(0, 0, PLANE_ICON_SIZE, PLANE_ICON_SIZE, planeUp, PLANE_ICON_TRANSPARENT);
    rotated.setSwapBytes(false);

    // Push the rotated sprite to the backbuffer
    rotated.pushRotateZoom(&backbuffer, x, y, heading, 1.0, 1.0);

    rotated.deleteSprite();
    }

    ReplyDelete
    Replies
    1. Thank you so much for contributing this code. I'm 78 and not a coder but was able to successfully copy and paste and recompile the code and it works great. Your code really adds to the look of the display!

      Delete
    2. Is it possible to use a larger display (4” or larger) and does the code need to be changed?

      Delete
    3. I cannot test, but on easiest just modifying display width/height values might be enough... assuming any calculations is based on those.

      Delete
    4. Hi all.The bigger screens use different interface chips, so it would not be an easy task.. Did anyone try?? thanks..

      Delete
    5. Probably not, with code that can't even be configured to successfully do a 180° orientation switch I can't imagine getting it to work on a larger display without a complete rewrite.

      Delete
  7. Brilliant Work!
    I have got it working.
    I altered the orientation - Thank You MarkoK
    I altered the speed and Altitude to Knots and Feet - Thank You Xraydelta101
    I altered the Aircraft Logo to face the direction of travel - Thank You Tom
    My only issue is that my display has the USB C Port at the top instead of the bottom, but I haven't settled on a case yet....

    ReplyDelete
  8. I've added a swipe down from the top menu screen along with. incorporating the directional plane icons and also a flight details screen (when you click on a plane on the sweep scan screen) and also an option to display the nearest aircraft instead of the sweeps scan screen (also available from the swipe down menu). Used a little bit of Codex / ChatGPT to assist with the additions (don't hate me for it). Also added toggles for metric to imperial, whether to display the sweep, dots or plane icons and refresh interval. Here is a link to my google drive with the project in https://drive.google.com/drive/folders/1upk8_A_npe07qjsYHJDs64Gp99C9OXmE?usp=sharing

    ReplyDelete
  9. Made some more changes this morning :

    DO NOT INSTALL THIS IF YOU WANT TO CONTINUE USING THE ORIGINAL OPENSKY DATA SOURCE , THIS VERSION CHANGES FROM USING THE DATA SOURCE TO ADS-B AND IT'S ASSOCIATED ENHANCEMENT DATA SOURCES.

    This newer build keeps the original CYD touchscreen flight-radar idea, but changes the aircraft data source, expands the detail screen, and makes the radar sweep behave more like a real scanning display.

    ## Headline Changes

    - Replaced the OpenSky aircraft feed with an ADS-B live position feed.
    - OpenSky API credentials are no longer needed.
    - Removed the OpenSky client ID and secret fields from the web configuration page.
    - Added enrichment lookups for extra aircraft and route information where available.
    - Added airline/private display, aircraft make/model, and origin/destination airports to the detail view.
    - Added a more realistic scan sweep mode where aircraft only appear or move when the sweep line reaches them.
    - Increased the radar sweep speed to one full rotation every 10 seconds.
    - Added Hybrid mode and a configurable nearby-aircraft range.
    - Added portrait/landscape orientation support.

    https://drive.google.com/file/d/1gFVVJwBkIeJ2Bcx6sevQAaCIA5nHfCEB/view?usp=share_link

    ReplyDelete
    Replies
    1. Hi and thanks. I will stick to the opensky version, much easier than ads-b, Just wordering if it would be possible to pass some of the improvements (for example the realistic sweep mode and the increased sweep speed) to the opensky version. If not no problem, it works well enough. Thanks!!

      Delete
    2. No reason why not. The move to the ads-b source was that it seems to include more aircraft, has the enhanced information source and doesn't require you to setup an API key. Also OpenSky gives a normal authenticated user 4,000 credits per day. For a small local limited scan radius, which is what this project uses (unless you set the degrees very high!), each aircraft-position refresh costs 1 credit. So that means roughly 4,000 data refreshes per day.
      That sounds like a lot, but a device running all day burns through it quickly, here are the relative refresh rates, vs number of daily calls :

      1 second 86,400 Way over limit
      5 seconds 17,280 Way over limit
      10 seconds 8,640 Over limit
      20 seconds 4,320 Slightly over
      30 seconds 2,880 Safe
      60 seconds 1,440 Safe

      So with 4,000 credits/day, the fastest sustainable refresh rate is about one refresh every 21.6 seconds, assuming every request only costs 1 credit.

      I felt that this creates a problem for this project because it is meant to feel like a live radar. At 30-60 second refreshes, the aircraft positions can feel stale, especially for planes close overhead. At 5-10 seconds, which feels much better visually, OpenSky credits would run out partway through the day.
      There’s also a second issue: OpenSky’s own docs say authenticated users have 5-second time resolution, and anonymous users have 10-second resolution, so requesting faster than that would not really give fresher data anyway. It would mostly just waste credits.

      The other big reason for moving away is usage terms: OpenSky says operational REST API use in a live product/service/automated system needs a written agreement, even aside from the technical credit limit.

      Delete
    3. Thanks for the infos. I use it to show local airport traffic with 0.3 degrees radius, and had no problem with credits. It's OK, and it is a very nice gadget. Thanks again!!

      Delete
    4. I've backed out the provider changes and gone back to OpenSky for you, but left in the other enhancements also added the ability to set the orientation of the device so if you sit facing east etc you can set the orientation of the device accordingly. It also uses silhouettes to represent different classes of aircraft (I live near a glider club so have even included gliders!). https://drive.google.com/file/d/1R7lfSOGt_ro8EcngM6TAq0SS6GumSvTu/view?usp=share_link

      Delete
    5. The version with the latest changes and using ADS-B is here https://drive.google.com/file/d/1iesOrCsRJe6SslonlEkUD65kTpeSE2M4/view?usp=sharing

      Delete
    6. Really thanks a lot: the opensky version works perfectly now tith the improvements. Thanks again!!!

      Delete
    7. Cool project, Mr Keep!

      I bought this: https://www.aliexpress.com/item/1005008176009397.html

      Besides backlight pin cfg.pin_bl=27 these settings are needed in LGFX.h to get touch to work

      private:
      lgfx::Panel_ST7789 _panel;
      lgfx::Bus_SPI _bus;
      lgfx::Light_PWM _light;
      lgfx::Touch_XPT2046 _touch;

      {
      auto cfg = _touch.config();

      cfg.x_min = 300;
      cfg.x_max = 3900;
      cfg.y_min = 200;
      cfg.y_max = 3700;

      cfg.pin_int = 36;

      // Same SPI bus pins as display
      cfg.bus_shared = true;
      cfg.spi_host = HSPI_HOST;

      cfg.freq = 1000000;

      cfg.pin_sclk = 14;
      cfg.pin_mosi = 13;
      cfg.pin_miso = 12;

      // Separate CS selects the XPT2046
      cfg.pin_cs = 33;
      cfg.offset_rotation = 3;
      _touch.config(cfg);
      _panel.setTouch(&_touch);
      }

      Delete
  10. I'm trying to get Mr Keep's ADS-B version to show aircraft. I have an ADS-B receiver outputting data on Port 30003 that is currently feeding AVR or Beast Raw data to Virtual Radar Server from a Raspberry Pi running Dump1090 on address 192.168.1.222:30003

    I can't workout how to configure this source, assuming that it is actually compatible with this ADS-B code.

    Would appreciate any advice, thanks.
    Andy

    ReplyDelete
  11. Great project, thanks!!

    Backlight pin was different for me:
    pin_bl = 27
    https://www.aliexpress.com/item/1005008176009397.html

    ReplyDelete

Post a Comment