Tom Minnich
Published © GPL3+

DRONE with AT&T and PubNub IoT Connectivity

IoT connection will be used to provide telemetry from the drone. IoT also acts as a backup for the radio control improving safety.

AdvancedWork in progressOver 3 days2,662

Things used in this project

Hardware components

AT&T IoT Starter Kit
×1

Software apps and online services

PubNub Publish/Subscribe API
PubNub Publish/Subscribe API

Story

Read more

Schematics

K64 Schematic

Here is the schematic for the K64 board, for a very nice controller for an IoT enabled drone.

Code

Flow Project

XML
Import this to AT&T Flow to recreate the IoT Drone Flow project
[{"id":"823aeb67.6f4b08","type":"pubnub-keys","z":"1bab0ca1.453f33","pub_key":"demo","sub_key":"demo"},{"id":"b05e98ca.380a48","type":"function","z":"1bab0ca1.453f33","name":"check_telemetry","func":"\nreturn msg;","outputs":1,"noerr":0,"dependencies":[],"x":349.390625,"y":127,"wires":[["5f52635f.eca95c"]]},{"id":"cf3a32a6.85a71","type":"pubnub in","z":"1bab0ca1.453f33","keys":"823aeb67.6f4b08","channel":"drone-telemetry","x":150.390625,"y":123,"wires":[["799f4277.afbd9c","b05e98ca.380a48"]]},{"id":"5f52635f.eca95c","type":"pubnub out","z":"1bab0ca1.453f33","keys":"823aeb67.6f4b08","channel":"drone-command","x":597.390625,"y":124,"wires":[]},{"id":"799f4277.afbd9c","type":"debug","z":"1bab0ca1.453f33","name":"","active":true,"console":"false","complete":"false","x":353.390625,"y":52,"wires":[]}]

IoT Drone Flow Code with Data Inject

XML
Copy to clipboard and Import into Flow to clone the Flow project
[{"id":"c6abaaec.80d4e8","type":"pubnub-keys","z":"d8ed806f.ce5ac","pub_key":"demo","sub_key":"demo"},{"id":"1b1ef041.59b38","type":"inject","z":"d8ed806f.ce5ac","name":"","topic":"","payload":"\" temp : 50 \"","payloadType":"str","repeat":"","crontab":"","once":false,"x":110.671875,"y":283,"wires":[["3fe7dac5.2b02c6"]]},{"id":"3fe7dac5.2b02c6","type":"function","z":"d8ed806f.ce5ac","name":"check_telemetry","func":"\nreturn msg;","outputs":1,"noerr":0,"dependencies":[],"x":320.09375,"y":187,"wires":[["2960c321.a9546c"]]},{"id":"2960c321.a9546c","type":"pubnub out","z":"d8ed806f.ce5ac","keys":"c6abaaec.80d4e8","channel":"drone-command","x":568.09375,"y":184,"wires":[]},{"id":"d8d25e48.eb093","type":"pubnub in","z":"d8ed806f.ce5ac","keys":"c6abaaec.80d4e8","channel":"drone-telemetry","x":121.09375,"y":183,"wires":[["52e29801.23b488","3fe7dac5.2b02c6"]]},{"id":"52e29801.23b488","type":"debug","z":"d8ed806f.ce5ac","name":"","active":true,"console":"false","complete":"false","x":324.09375,"y":112,"wires":[]}]

Overtemp Detection Flow Program

XML
Copy this and import it into Flow
[{"id":"50e96c4a.594974","type":"function","z":"b2479d74.77eae","name":"check_telemetry","func":"var tempValue = parseFloat(msg.payload[8]);//msg.payload[0]\nvar safe1 = \"SAFETY! 39.961433 -86.127472 290,\";\nvar safe2 = \" 39.961436 -86.127388 280,\";\nvar safe3 = \" 39.961440 -86.127304 270,\";\nvar safe4 = \" 39.961442 -86.127220 260,\";\nvar safe5 = \" 39.961444 -86.127136 250,\";\nvar safe6 = \" 39.961446 -86.127052 240,\";\nvar safe7 = \" 39.961448 -86.127014 230,\";\nvar safe8 = \" 39.961450 -86.126970 220,\";\nvar safe9 = \" 39.961450 -86.126970 198,\";\nvar safe10 = \" 39.961450 -86.126970 197,\";\n\n\nif (tempValue >= 1) { //assume something was found\n        msg = {}; //Create blank object\n        msg.payload = (tempValue >= 8) ? safe1+safe2+safe3+safe4+safe5+safe6+safe7+safe8+safe9+safe10 : \"ALL SYS GO!\";\n        \n\t}\n\nreturn msg;","outputs":1,"noerr":0,"dependencies":[],"x":318.515625,"y":175,"wires":[["49ff6315.ee0d1c","2de39234.9cf9ae"]]}]

K64 MBED project e179a3f4079c.zip

C/C++
An MBED project for NXP K64 board
No preview (download only).

GPS enforced boundaries

XML
Copy the code and import into AT&T Flow
[{"id":"e6e7f5c.9b3cc08","type":"pubnub-keys","z":"c23caff3.9920d","pub_key":"demo","sub_key":"demo"},{"id":"a6fca9bd.c69c78","type":"pubnub in","z":"c23caff3.9920d","keys":"e6e7f5c.9b3cc08","channel":"drone-telemetry","x":139.09375,"y":161,"wires":[["11311f09.7eb921","4f325ac5.a7c444"]]},{"id":"11311f09.7eb921","type":"debug","z":"c23caff3.9920d","name":"","active":true,"console":"false","complete":"false","x":342.09375,"y":90,"wires":[]},{"id":"4f325ac5.a7c444","type":"function","z":"c23caff3.9920d","name":"check_telemetry","func":"var tempValue = parseFloat(msg.payload.substring(8,11));\nvar lat_delta = 0.005;\nvar lon_delta = 0.005;\nvar ceiling = 100; // 100 meters over the ground\nvar ground = 258;\nvar ref_lat = 39.961282;\nvar ref_lon = -86.127067\nvar safe1 = \"SAFETY! 39.961433 -86.127472 290,\";\nvar safe2 = \" 39.961436 -86.127388 280,\";\nvar safe3 = \" 39.961440 -86.127304 270,\";\nvar safe4 = \" 39.961442 -86.127220 260,\";\nvar safe5 = \" 39.961444 -86.127136 250,\";\nvar safe6 = \" 39.961446 -86.127052 240,\";\nvar safe7 = \" 39.961448 -86.127014 230,\";\nvar safe8 = \" 39.961450 -86.126970 220,\";\nvar safe9 = \" 39.961450 -86.126970 198,\";\nvar safe10 = \" 39.961450 -86.126970 197,\";\nmsg2 = {};\n// assume that there will be a fault found\nmsg2.payload = safe1+safe2+safe3+safe4+safe5+safe6+safe7+safe8+safe9+safe10; \n\n\nif (tempValue >= 1) { //assume something was found\n        if (tempValue >= 80){\n  \n        }else{\n            tempValue = parseFloat(msg.payload.substring(15,26));\n            if(  (ref_lat - lat_delta) < tempValue ){\n                if(tempValue < (ref_lat + lat_delta)){\n                    tempValue = parseFloat(msg.payload.substring(27,38));\n                    if(  (ref_lon - lon_delta) < tempValue ){\n                        if(tempValue < (ref_lon + lon_delta)){\n                            tempValue = parseFloat(msg.payload.substring(39,47));\n                            if(ground >= tempValue){\n                                if( tempValue < (ground + ceiling)){    \n                                    msg2.payload = \"ALL SYS GO!\";\n                                }\n                            }\n                        }\n                    }\n\n\n                }\n\n            }\n        }\n \n      \n\t}\n\nreturn msg2;","outputs":1,"noerr":0,"dependencies":[],"x":338.09375,"y":165,"wires":[["ae663c95.3e7ee","eeb9c5fd.89e278"]]},{"id":"ae663c95.3e7ee","type":"pubnub out","z":"c23caff3.9920d","keys":"e6e7f5c.9b3cc08","channel":"drone-command","x":586.09375,"y":162,"wires":[]},{"id":"eeb9c5fd.89e278","type":"debug","z":"c23caff3.9920d","name":"","active":true,"console":"false","complete":"false","x":563.25,"y":88,"wires":[]},{"id":"7c1f487f.84ba48","type":"inject","z":"c23caff3.9920d","name":"","topic":"","payload":" temp : 50 gps +039.961282,-086.127067,+00258.00 ","payloadType":"str","repeat":"","crontab":"","once":false,"x":128.671875,"y":261,"wires":[["4f325ac5.a7c444"]]},{"id":"9fe19c34.35136","type":"inject","z":"c23caff3.9920d","name":"Temp Spike!","topic":"","payload":" temp : 90 gps +039.961282,-086.127067,+00258.00","payloadType":"str","repeat":"","crontab":"","once":false,"x":128,"y":323,"wires":[["4f325ac5.a7c444"]]},{"id":"eb2d8259.df608","type":"inject","z":"c23caff3.9920d","name":"Inbound GPS coord","topic":"","payload":" temp : 50 gps +039.961282,-086.127067,+00258.00","payloadType":"str","repeat":"","crontab":"","once":false,"x":124.671875,"y":393,"wires":[["4f325ac5.a7c444"]]},{"id":"a611b004.13131","type":"inject","z":"c23caff3.9920d","name":"Out of Bounds","topic":"","payload":" temp : 50 gps +049.961282,-086.127067,+00258.00","payloadType":"str","repeat":"","crontab":"","once":false,"x":126.671875,"y":458,"wires":[["4f325ac5.a7c444"]]}]

Main.cpp from MBED project

C/C++
Sends dummy telemetry for test purposes to Flow program operating in the cloud
#include "mbed.h"
#include "WNCInterface.h"

#include "pubnub_sync.h"
#include "srand_from_pubnub_time.h"
DigitalOut led_green(LED_GREEN);
DigitalOut led_red(LED_RED);
DigitalOut led_blue(LED_BLUE);

#define CRLF "\r\n"

WNCInterface eth;
MODSERIAL pc(USBTX,USBRX,256,256);


static void generate_uuid(pubnub_t *pbp)
{
    char const *uuid_default = "zeka-peka-iz-jendeka";
    struct Pubnub_UUID uuid;
    static struct Pubnub_UUID_String str_uuid;

    if (0 != pubnub_generate_uuid_v4_random(&uuid)) {
        pubnub_set_uuid(pbp, uuid_default);
    }
    else {
        str_uuid = pubnub_uuid_to_string(&uuid);
        pubnub_set_uuid(pbp, str_uuid.uuid);
        pc.printf("Generated UUID: %s\n", str_uuid.uuid);
    }
}


int main()
{
    led_red = 0;
    led_green = 1;
    led_blue = 1;
    pc.baud(115200);
    pc.printf(CRLF CRLF "Pubnub Test starting..." CRLF);
    
    pc.printf("init() returned 0x%04X" CRLF, eth.init(NULL,&pc));
    eth.connect();
    pc.printf("IP Address: %s" CRLF, eth.getIPAddress());
    eth.doDebug(1);

    
    pubnub_t *pbp = pubnub_alloc();
    pubnub_init(pbp, "demo", "demo");  

    srand_from_pubnub_time(pbp);
    generate_uuid(pbp);
    led_red = 1;  
    while (true) {
        pubnub_res rslt = pubnub_publish(pbp, "drone-telemetry", "\" temp: 50 \"");
        if (rslt != PNR_STARTED) {
            pc.printf("Failed to start publishing, rslt=%d"CRLF, rslt);
        }
        else {
            rslt = pubnub_await(pbp);
            if (rslt != PNR_OK) {
                pc.printf("Failed to finished publishing, rslt=%d"CRLF, rslt);
            }
            else {
                pc.printf("Published! Response from Pubnub: %s"CRLF, pubnub_last_publish_result(pbp));
            }
        }
        
        rslt = pubnub_subscribe(pbp, "drone-command", 0);
        if (rslt != PNR_STARTED) {
            pc.printf("Failed to start subscribing, rslt=%d"CRLF, rslt);
        }
        else {
            rslt = pubnub_await(pbp);
            if (rslt != PNR_OK) {
                pc.printf("Failed to finished subscribing, rslt=%d"CRLF, rslt);
            }
            else {
                pc.printf("Subscribed! Received messages follow: %s"CRLF);
                while (char const *msg = pubnub_get(pbp)) {
                    pc.printf("subscribe got: %s"CRLF, msg);
                }
            }
        }
        wait_ms(25000);
        if(led_blue){
            led_blue = 0;
            led_green = 1;
        }else{
            led_blue = 1;
            led_green = 0;
        }
    }
}

Credits

Tom Minnich

Tom Minnich

19 projects • 80 followers
Embedded software guy for a long time

Comments