JaniceJordan TakayamaVictoria Zheng
Published © GPL3+

BPM Biker

Select songs to bike or run to based on current speed

EasyWork in progress725
BPM Biker

Things used in this project

Hardware components

LinkIt ONE
MediaTek Labs LinkIt ONE
×1
Grove Starter Kit for LinkIt ONE
Seeed Grove Starter Kit for LinkIt ONE
×1

Software apps and online services

Microsoft Azure
Microsoft Azure

Story

Read more

Schematics

LinkItONE with GPS and WiFi attachments

Linkitone

Code

GPSSpeed for LinkItONE

C/C++
Log and upload GPS and speed data from your LinkItONE to an Azure Mobile Service over WiFi
#include <LWiFi.h>
#include <LWiFiClient.h>
#include <LWiFiServer.h>
#include <SPI.h>
#include <LGPS.h>

gpsSentenceInfoStruct info;
char buff[256];
double lat;
double lon;
double spd;
String dataString;

const char *server = "your-service.azure-mobile.net";
const char *table_name = "your-table-name";
const char *ams_key = "your-application-key";
#define WIFI_AP "your-SSID"
#define WIFI_PASSWORD "your-wifi-password"
#define WIFI_AUTH LWIFI_WPA  // choose from LWIFI_OPEN, LWIFI_WPA, or LWIFI_WEP.


LWiFiClient client;

char buffer[64];

void send_request()
{
  Serial.println("\nconnecting...");
  
  if(client.connect(server, 80)){
    Serial.print("sending");
    
    // POST URI
    sprintf(buffer, "POST /tables/%s HTTP/1.1", table_name);
    client.println(buffer);

    // Host header
    sprintf(buffer, "Host: %s", server);
    client.println(buffer);

    // Azure Mobile Services application key
    sprintf(buffer, "X-ZUMO-APPLICATION: %s", ams_key);
    client.println(buffer);

    // JSON content type
    client.println("Content-Type: application/json");

    // POST body
    sprintf(buffer, "{\"latitude\": %f, \"longitude\": %f, \"speed\": %f}", lat, lon, spd);
    Serial.println(buffer);

    // Content length
    client.print("Content-Length: ");
    client.println(strlen(buffer));

    // End of headers
    client.println();

    // Request body
    Serial.println(buffer);
    client.println(buffer);
    
  } else{
    Serial.println("connection failed");
  }
}

void wait_response()
{
  while(!client.available()){
    if (!client.connected()) {
      return;
    }
  }
}

void read_response()
{
  bool print = true;
  
  while (client.available()){
    char c = client.read();
    if (c=='\n')
      print = false;
    if (print)
      Serial.print(c);
  }
}

void end_request()
{
  client.stop();
}

static unsigned char getComma(unsigned char num,const char *str)
{
  unsigned char i,j = 0;
  int len=strlen(str);
  for(i = 0;i < len;i ++)
  {
     if(str[i] == ',')
      j++;
     if(j == num)
      return i + 1; 
  }
  return 0; 
}

static double getDoubleNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atof(buf);
  return rev; 
}

static double getIntNumber(const char *s)
{
  char buf[10];
  unsigned char i;
  double rev;
  
  i=getComma(1, s);
  i = i - 1;
  strncpy(buf, s, i);
  buf[i] = 0;
  rev=atoi(buf);
  return rev; 
}

void parseGPRMC(const char* GPRMCstr)
{
  /* Refer to http://www.gpsinformation.org/dale/nmea.htm#RMC
   * Sample data: $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A

Where:
     RMC          Recommended Minimum sentence C
     123519       Fix taken at 12:35:19 UTC
     A            Status A=active or V=Void.
     4807.038,N   Latitude 48 deg 07.038' N
     01131.000,E  Longitude 11 deg 31.000' E
     022.4        Speed over the ground in knots
     084.4        Track angle in degrees True
     230394       Date - 23rd of March 1994
     003.1,W      Magnetic Variation
     *6A          The checksum data, always begins with *
   */

  int tmp, hour, minute, second, date, num ;
  if(GPRMCstr[0] == '$')
  {
    tmp = getComma(1, GPRMCstr);
    hour     = (GPRMCstr[tmp + 0] - '0') * 10 + (GPRMCstr[tmp + 1] - '0');
    minute   = (GPRMCstr[tmp + 2] - '0') * 10 + (GPRMCstr[tmp + 3] - '0');
    second    = (GPRMCstr[tmp + 4] - '0') * 10 + (GPRMCstr[tmp + 5] - '0');
    
    sprintf(buff, "UTC timer %2d-%2d-%2d", hour, minute, second);
    Serial.println(buff);
    
    tmp = getComma(3, GPRMCstr);
    lat = getDoubleNumber(&GPRMCstr[tmp]);
    tmp = getComma(5, GPRMCstr);
    lon = getDoubleNumber(&GPRMCstr[tmp]);
    sprintf(buff, "latitude = %10.4f, longitude = %10.4f", lat, lon);
    Serial.println(buff); 
    
    tmp = getComma(7, GPRMCstr);
    spd = getDoubleNumber(&GPRMCstr[tmp]);    
    sprintf(buff, "speed = %f", spd);
    Serial.println(buff); 
  }
  else
  {
    Serial.println("Not get data"); 
  }
}


void setup() {
  // put your setup code here, to run once:
  LWiFi.begin();
  Serial.begin(115200);
  while(!Serial);
  Serial.println("Wifi Power on...");
  while (0 == LWiFi.connect(WIFI_AP, LWiFiLoginInfo(WIFI_AUTH, WIFI_PASSWORD)))
  {
    Serial.println("wifi failed");
    delay(1000);
  }
  LGPS.powerOn();
  Serial.println("LGPS Power on, and waiting ..."); 
  delay(3000);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("LGPS loop"); 
  LGPS.getData(&info);
  Serial.println((char*)info.GPRMC); 
  parseGPRMC((const char*)info.GPRMC);
   
  send_request();
  wait_response();
  read_response();
  end_request();
  
  delay(2000);
  
}

Credits

Janice

Janice

1 project • 1 follower
Jordan Takayama

Jordan Takayama

1 project • 0 followers
Victoria Zheng

Victoria Zheng

1 project • 0 followers

Comments

Add projectSign up / Login