Sam Hetchler
Published © GPL3+

Creating the Tweeting Viking Hat

I made a tweeting viking hat to show off that anyone could hear iBeacons.

IntermediateFull instructions provided1 hour1,788
Creating the Tweeting Viking Hat

Things used in this project

Hardware components

Hologram Global IoT SIM Card
Hologram Global IoT SIM Card
×1
Plastic Viking Hat
×1

Software apps and online services

Maker service
IFTTT Maker service
Twitter service
IFTTT Twitter service

Story

Read more

Code

LinkIt ONE Bluetooth 4.0 counter to IFTTT Maker Channel

Arduino
This is the complete code for the LinkIt ONE to scan BT 4.0 devices and send the count to IFTTT to trigger a tweet.
#include <LBT.h>
#include <LBTClient.h>

#include <LGATT.h>
#include <LGATTClient.h>
#include <LGATTServer.h>

#include <LDateTime.h>
#include <LGPS.h>

#include <LStorage.h>
#include <LFlash.h>

#include <LWiFi.h>
#include <LWiFiClient.h>

#define WIFI_AP "Kscope16"
#define WIFI_PASSWORD "your_password"
#define WIFI_AUTH LWIFI_OPEN  // choose from LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP according to your WiFi AP configuration

char MakerIFTTT_Key[] = "MakerIFTTTKeyGoesHere";
char MakerIFTTT_Event[] = "BT4ScanMax";

datetimeInfo t;
unsigned int rtc;

static LBTDeviceInfo info = {0};
#define ard_log Serial.printf

int i = 0;
int j = 0;

int counter = 0;
int counterMaxIds = 0;

// create a uuid for app, this uuid id is to identify a client
static LGATTUUID test_uuid("B4B4B4B4-B4B4-B4B4-B4B4-B4B4B4B4B4B4");

// specified / prefered service uuid
// 128bit format for your cared service uuid  
LGATTUUID uuidService("E20A39F4-73F5-4BC4-A12F-17D1AD07A961");

// 16bit format for your cared service uuid
// LGATTUUID uuidService = 0x180F; // battery service

LGATTClient c;
void setup() {
    delay(5000);
    Serial.begin(115200);  
//    LGPS.powerOn();
}

void loop() 
{
  checkBTFour();
}

void checkBTFour()
{
  counter++;
  c.begin(test_uuid);

  int num = 0;
  LGATTDeviceInfo info = {0};
  num = c.scan(1);
  LDateTime.getTime(&t);
  LDateTime.getRtc(&rtc);
  
  c.end();
  
  if(counterMaxIds < num)
  {
    counterMaxIds = num;
  }

//  Serial.print("Objects found ");
//  Serial.println(num);

  if(counter > 60)
  {
    Serial.print("Max Objects found ");
    Serial.println(counterMaxIds);
    tweet_event();
    counter = 0;
    counterMaxIds = 0;
  }

  delay(100);

}

char *append_str(char *here, char *s) {
    while (*here++ = *s++)
	;
    return here-1;
}

char *append_ul(char *here, unsigned long u) {
    char buf[20];       // we "just know" this is big enough

    return append_str(here, ultoa(u, buf, 10));
}

void tweet_event()
{
  LWiFi.begin();

  // keep retrying until connected to AP
  Serial.println("Connecting to AP");
  while (0 == LWiFi.connect(WIFI_AP, LWiFiLoginInfo(WIFI_AUTH, WIFI_PASSWORD)))
  {
    delay(1000);
  }

  LWiFiClient c;

  // keep retrying until connected to website
  // connect to the Maker event server
  Serial.println("Connecting to WebSite");
  while (0 == c.connect("www.maker.ifttt.com", 80))
  {
    Serial.println("Re-Connecting to WebSite");
    delay(1000);
  }

    // construct the POST request
    char post_rqst[256];    // hand-calculated to be big enough

    char *p = post_rqst;
    p = append_str(p, "POST /trigger/");
    p = append_str(p, MakerIFTTT_Event);
    p = append_str(p, "/with/key/");
    p = append_str(p, MakerIFTTT_Key);
    p = append_str(p, " HTTP/1.1\r\n");
    p = append_str(p, "Host: maker.ifttt.com\r\n");
    p = append_str(p, "Content-Type: application/json\r\n");
    p = append_str(p, "Content-Length: ");

    // we need to remember where the content length will go, which is:
    char *content_length_here = p;

    // it's always two digits, so reserve space for them (the NN)
    p = append_str(p, "NN\r\n");

    // end of headers
    p = append_str(p, "\r\n");

    // construct the JSON; remember where we started so we will know len
    char *json_start = p;

    p = append_str(p, "{\"value1\":\"");
    p = append_ul(p, counterMaxIds);
    p = append_str(p, "\"}");

    // go back and fill in the JSON length
    // we just know this is at most 2 digits (and need to fill in both)
    int i = strlen(json_start);
    content_length_here[0] = '0' + (i/10);
    content_length_here[1] = '0' + (i%10);

    // finally we are ready to send the POST to the server!
    c.print(post_rqst);

    c.stop();

    Serial.println(post_rqst);
    LWiFi.end();
}

LinkIt ONE Bluetooth 4.0 Scanner

Arduino
This is the code that I modified to "wardrive" bluetooth 4.0 devices.
#include <LBT.h>
#include <LBTClient.h>

#include <LGATT.h>
#include <LGATTClient.h>
#include <LGATTServer.h>

#include <LDateTime.h>
#include <LGPS.h>

datetimeInfo t;
unsigned int rtc;

static LBTDeviceInfo info = {0};
#define ard_log Serial.printf

int i = 0;
int j = 0;

// create a uuid for app, this uuid id is to identify a client
static LGATTUUID test_uuid("B4B4B4B4-B4B4-B4B4-B4B4-B4B4B4B4B4B4");

// specified / prefered service uuid
// 128bit format for your cared service uuid  
LGATTUUID uuidService("E20A39F4-73F5-4BC4-A12F-17D1AD07A961");

// 16bit format for your cared service uuid
// LGATTUUID uuidService = 0x180F; // battery service

LGATTClient c;
void setup() {
    delay(5000);
    Serial.begin(115200);     
    LGPS.powerOn();
    c.begin(test_uuid);
}

void loop() 
{
//  checkBTTwo();
  checkBTFour();
}

void checkBTFour()
{
  // GATT central begin to start
  int num = 0;
  LGATTDeviceInfo info = {0};
  num = c.scan(1);
  LDateTime.getTime(&t);
  LDateTime.getRtc(&rtc);
  
  // polling all found devices
  for (i = 0; i < num; i++)
  {
    c.getScanResult(i, info);
    Serial.printf("BT4,%d,%d,[%x:%x:%x:%x:%x:%x]", 
      rtc, info.rssi,
      info.bd_addr.addr[5], info.bd_addr.addr[4], info.bd_addr.addr[3], info.bd_addr.addr[2], info.bd_addr.addr[1], info.bd_addr.addr[0]
    );
    Serial.println();
  }
}

void checkBTTwo()
{
  ard_log("LBT start\n");
  // begin BT
  bool success = LBTClient.begin();
  if( !success )
  {
      ard_log("Cannot begin Bluetooth Client successfully\n");
  }
  else
  {
      ard_log("Bluetooth Client begin successfully\n");
      // scan the devices around
      int num = LBTClient.scan(1);
//      ard_log("scanned device number [%d]\n", num);
      for (int i = 0; i < num; i++)
      {
        memset(&info, 0, sizeof(info));
        LBTClient.getDeviceInfo(i, &info);
        ard_log("BT2, [%02x:%02x:%02x:%02x:%02x:%02x],[%s]\n", 
            info.address.nap[1], info.address.nap[0], info.address.uap, info.address.lap[2], info.address.lap[1], info.address.lap[0],
            info.name);
      }
  }
}

Credits

Sam Hetchler

Sam Hetchler

10 projects • 35 followers
I am a tinkerer, developer, and concept hacker. I find it fun to push the boundaries of what's possible.

Comments