Close
0%
0%

Turn Any Drone Into a Delivery Drone

I just turned my drone into a delivery drone...

And you can too, just follow the instructions down below.

Public Chat
Similar projects worth following
We're living in a new era where everything is evolving at a rate that humanity has never seen before, and because of this, everyone is chasing the next BIG thing. With companies like Amazon, Zipline, UPS and the like investing heavily on the future of parcel delivery, delivery drones, it makes it seem out of reach for a normal person like you and I to ever get their hands on one 😢.

But, let's say that we change that 💡. Today I'll show you how you can turn any drone into a Delivery Drone 📦

For this project, the only pre-built thing that you should have on hand is a drone which you have access to it's Flight Controller (FC). The entire build of the drone is outside the scope of this project, but there's so many sources online to build a drone that you won't struggle to find the help that you need. Alternatively you could just buy a drone

Here's a list of what you'll need to build your delivery drone :

Software:

  1. Ultimaker Cura (or any other slicer)
  2. Betaflight Configurator
  3. Fusion 360 (eligible students, educators, and qualifying educational institutions should have free access to it) (optional)

Equipment:

Supplies Image

  1. Access to a 3D printer (if you don't have your own, check with your local library, or college. I used one at a makerspace at my University)
  2. PLA Filament (any colour is fine, I chose White)

Supplies:

  1. Soldering Iron
  2. Soldering Wire
  3. Wire Strippers
  4. Electrical Wires (Male - Male)
  5. Multimeter (One that has a continuity tester on it)
  6. Precision Screwdriver Set
  7. Electrical Tape
  8. Pliers
  9. Zip-ties

Components:

  1. Flight Controller (Compatible with betaflight)
  2. DC Gear Motor
  3. ESP32 Firebeetle 2
  4. DC-DC Buck Converter 7-24V to 5V
  5. ELRS-Nano Receiver (any receiver using an ELRS protocol)

Droke.step

step - 7.91 MB - 01/13/2025 at 20:05

Download

Flatch.step

step - 3.66 MB - 01/13/2025 at 20:05

Download

Lever.step

step - 19.88 kB - 01/13/2025 at 20:05

Download

View all 6 components

  • 1
    The Idea

    The plan of execution for this project can be divided into two main categories:

    1. Electronics – How do we communicate with the drone to trigger the drop?
    2. 3D Design and Printing – What components can be used to facilitate the drop mechanism?

    Now, to build the delivery drone, we need to follow a couple of steps, but the key question is what those steps actually are... But with all problem solving, we just need to ask ourselves a couple of questions that will guide us in the quest to turn our drone into a delivery drone⚡️.

    Electronics

    You: "How will the drone know when to drop the package?" 🤔💭

    Me: "We’ll need to tell it when!☝️🤓"

    You: "🧍♂️ Obviously, dude. But how do we actually do that?"

    Me: "Okay, so most standard drone controllers have extra buttons that aren’t used during flight—they're just lying around, doing nothing right?💡"

    You: "Yeah..."

    Me: "Why not assign one of those buttons to trigger the package drop?"

    You: "Hmm, that's kinda smart! But how do we actually do that? 🫡"

    Me: (chuckling) "Alright, here’s the gist. The transmitter sends a signal to the receiver about the state of every channel, basically all the switches and buttons on the controller. The receiver then passes this signal to the flight controller, right?"

    You: "Mm-hmm 🧐"

    Me: "What if we tap into that signal and decode it? By using a powerful microcontroller, like an ESP32, we can read all the transmitter’s channel values. Then, we assign one of the unused channels to trigger the drop. When that button is pressed, the ESP32 sends the command to release the package."

    You: "Bingo! I think we’re onto something!"

    3D Design and Printing

    You: "Okay, but what mechanism should we use to actually drop the package? 🤨"

    Me: "🫡 Good question. We could use a simple string to hold the package, but then we’d have to deal with it swinging mid-air... not ideal."

    You: "Yeah, it’s like we’d need a way to 'stick' the package to the drone until the moment it needs to drop."

    Me: "Exactly. We’ll need a more stable design. I’ve got a few ideas… 🧙♂️🪄" (stares dramatically into the distance)

    Let's continue🏃♂️💨

  • 2
    Setting Up The ESP32

    The ESP32 "listens in" on the communication between the receiver and the flight controller (FC) to extract the transmitter's channel values. By decoding the CRSF protocol used by the ELRS receiver, it translates this data into raw channel values. After several late nights of tinkering, I successfully implemented the decoding process.

    Here’s how it works: The receiver sends data packets to the FC using its TX port. These packets include the transmitter's channel values. Once the ESP32 receives a packet, it gains access to the same data as the FC. Using this information, the ESP32 can be programmed to activate a motor and release the package when a specific, unused channel is triggered by a button press.

    For more technical explanation and more code refer to my GitHub, it has the entire process explained in a lot more detail✨

    Note: In the code below, the designated channel for triggering the package drop is channel 7, as on my controller, it was an auxiliary button that was latent. If you want to use a different channel value, modify it in the code.

    // Code for the ESP32 Firebeetle
    
    #include <HardwareSerial.h>
    #include <ESP32Servo.h>
    
    #define speed_stop 90 // Stop position
    
    #define CRSF_SERIAL_PORT Serial2 // Using Serial2 on the ESP32
    #define CRSF_BAUD_RATE 420000 // CRSF baud rate (400,000 bps)
    #define RX_PIN 17 // Receiver TX connected to ESP32 RX (GPIO17)
    
    #define CRSF_MAX_PACKET_SIZE 64
    #define CRSF_FRAMETYPE_RC_CHANNELS_PACKED 0x16
    
    Servo mymotor; // Servo motor object
    
    uint16_t rcChannels[16]; // Channel data
    
    // Servo control debouncing variables
    const int STABLE_THRESHOLD = 5; // Required consecutive stable readings
    int stableCount = 0; // Counter to track stable readings
    bool motorActive = false; // State of the motor
    
    void processCRSFPacket(uint8_t *packet, uint8_t length) {
    uint8_t packetType = packet[2];
    
    if (packetType == CRSF_FRAMETYPE_RC_CHANNELS_PACKED) {
    // Extract 11-bit channel data
    rcChannels[0] = ((packet[3] | packet[4] << 8) & 0x07FF);
    rcChannels[1] = ((packet[4] >> 3 | packet[5] << 5) & 0x07FF);
    rcChannels[2] = ((packet[5] >> 6 | packet[6] << 2 | packet[7] << 10) & 0x07FF);
    rcChannels[3] = ((packet[7] >> 1 | packet[8] << 7) & 0x07FF);
    rcChannels[4] = ((packet[8] >> 4 | packet[9] << 4) & 0x07FF);
    rcChannels[5] = ((packet[9] >> 7 | packet[10] << 1 | packet[11] << 9) & 0x07FF);
    rcChannels[6] = ((packet[11] >> 2 | packet[12] << 6) & 0x07FF);
    rcChannels[7] = ((packet[12] >> 5 | packet[13] << 3) & 0x07FF);
    
    // Uncomment to print channel values for debugging
    // Serial.print("Channels: ");
    // for (int i = 0; i < 16; i++) {
    // Serial.printf("%2d: %4d ", i, rcChannels[i]);
    // }
    // Serial.println();
    
    // Debounce logic for channel 7 (Anticlockwise only)
    if (rcChannels[7] >= 1000) {
    if (!motorActive) {
    stableCount++;
    if (stableCount >= STABLE_THRESHOLD) {
    mymotor.write(60); // Rotate motor anticlockwise (position 0)
    motorActive = true;
    stableCount = 0; // Reset counter
    }
    }
    } else {
    if (motorActive) {
    stableCount++;
    if (stableCount >= STABLE_THRESHOLD) {
    mymotor.write(90); // Stop motor
    motorActive = false;
    stableCount = 0; // Reset counter
    }
    }
    }
    }
    }
    
    void setup() {
    Serial.begin(115200); // Initialize serial communication
    CRSF_SERIAL_PORT.begin(CRSF_BAUD_RATE, SERIAL_8N1, RX_PIN);
    mymotor.attach(12); // Attach servo to GPIO12
    
    Serial.println("CRSF Receiver Initialized.");
    }
    
    void loop() {
    static uint8_t packet[CRSF_MAX_PACKET_SIZE];
    static uint8_t packetIndex = 0;
    
    while (CRSF_SERIAL_PORT.available()) {
    uint8_t incomingByte = CRSF_SERIAL_PORT.read();
    
    if (packetIndex == 0 && incomingByte != 0xEE && incomingByte != 0xC8) {
    continue; // Skip invalid bytes
    }
    
    packet[packetIndex++] = incomingByte;
    
    if (packetIndex >= 2 && packetIndex == packet[1] + 2) {
    processCRSFPacket(packet, packetIndex);
    packetIndex = 0; // Reset for next packet
    }
    
    if (packetIndex >= CRSF_MAX_PACKET_SIZE) {
    packetIndex = 0; // Prevent buffer overflow
    }
    }
    }
  • 3
    Designing the Drop Mechanism With AI

    Now, let’s dive into the design of the package-dropping components 📦.

    Now stick with me here, because this is where things get exciting 🧐. Designing these components turned out to be both a fun and challenging process, requiring multiple iterations to get just right. The main goal was to create a design that’s easy to assemble, compatible with a wide range of drones, and both robust and practical.

    (a few early sketches ✍️)

    After finalizing a design robust enough to handle multiple drops, we can now take things to the next level by leveraging, wait for it…

    AI

    With the help of AI, we can minimize the material required to produce the parts and optimize flight performance by reducing the component weight to an absolute minimum.

    Using Fusion 360’s generative design feature 🤖, we can tackle the weight optimization challenge efficiently.

    After considering all factors, I developed the final drop mechanism, which consists of two parts:

    1. Droke: The component that attaches to the drone.
    2. Flatch: The part that drops along with the package.

    The Droke

    The Flatch

View all 15 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates