Components and supplies
Grove Mega Shield
Arduino Mega 2560
Adafruit SMA to uFL/u.FL/IPX/IPEX RF Adapter Cable
Seeed Grove Blue Wrapper Pack 1-2
Adafruit GPS Antenna
Grove-GPS
Apps and platforms
Aquabots Client
Project description
Code
WebClient.h
c_cpp
Header file of the communication with the Aquabots Client
1#ifndef WebClient_h 2#define WebClient_h 3 4#include <SPI.h> 5#include <Ethernet.h> 6 7#define AQUABOTS_REGISTRATION_CONTEXT F("/arnac/registration/") 8#define AQUABOTS_VESSEL_CONTEXT F("/arnac/rest/") 9#define CONDAST_URL F("www.condast.com") 10 11const unsigned long HTTP_TIMEOUT = 5000;// max respone time from server 12 13/* 14 Web client 15 16 This sketch connects to a website 17 using an Arduino Wiznet Ethernet shield. 18 19 Circuit: 20 Ethernet shield attached to pins 10, 11, 12, 13 21 22 created 18 Dec 2009 23 by David A. Mellis 24 modified 9 Apr 2012 25 by Tom Igoe, based on work by Adrian McEwen 26 27*/ 28 29//Condast SERVER 30// Set the static IP address to use if the DHCP fails to assign 31//const char server[] = "www.condast.com"; 32//IPAddress ip(79, 170, 90, 5); 33//const int PORT = 8080; 34 35//LOCALHOST 36// Set the static IP address to use if the DHCP fails to assign 37IPAddress server(192, 168, 178, 41); 38IPAddress ip(192, 168, 178, 41); 39const int PORT = 10080; 40 41//Huawei 42//IPAddress server(192,168,8,100); 43//IPAddress ip(192,168,8,100); 44//const int PORT = 10081; 45 46//Havenlab 47//IPAddress server(192,168,10,110); 48//IPAddress ip(192,168,10,110); 49//const int PORT = 10080; 50 51// Enter a MAC address for your controller below. 52// Newer Ethernet shields have a MAC address printed on a sticker on the shield 53const byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 54 55class WebClient { 56 57 public: WebClient(); 58 enum request { 59 UNKNOWN = 0, 60 REGISTER_VESSEL = 1, 61 VESSEL_CONFIG = 2, 62 DEBUG = 3, 63 FIELD = 4, 64 UPDATE = 5, 65 WAYPOINTS = 6, 66 DATA = 7, 67 NMEA = 8, 68 OPTIONS = 9, 69 LOG = 10, 70 WAYPOINT = 11 71 }; 72 73 const unsigned long HTTP_TIMEOUT = 5000;// max respone time from server 74 75 EthernetClient client; 76 void setup(); 77 bool connect(); 78 void disconnect(); 79 void setAuthentication( long id, String token ); 80 void setContext( String context ); 81 bool requestLog(); 82 bool logMessage( String message ); 83 bool getWaypoint(); 84 bool sendUpdate( String url ); 85 bool sendHttp( int request, String msg ); 86 bool sendHttp( int request, boolean post, String attrs ); 87 String urlencode(String str); 88 String printResponse( int request ); 89 void logRequest( int request, boolean post, String attrs );//for debugging 90 void logRequestStr( int request ); //dito 91 void loop(); 92 93 private: 94 String host; 95 int port; 96 bool connected; 97 String context; 98 long id; 99 String token; 100 101 // Initialize the Ethernet client library 102 // with the IP address and port of the server 103 // that you want to connect to (port 80 is default for HTTP): 104 void requestService( int request ); 105 bool processResponse( int request ); 106 boolean update( JsonObject& root ); 107 String urldecode(String str); 108 unsigned char h2int(char c); 109}; 110 111#endif
Vessels
c_cpp
Main Arduino Code
1#include <ArduinoJson.h> 2 3#include "WebClient.h" 4#include "Registration.h" 5#include "TinyGPS.h" 6#include "Vessel.h" 7 8#define VESSEL F("MyBoatName") 9#define PASSPHRASE F("MyPassPhrase") 10#define TIME_OUT 3000 //msec 11 12static WebClient webClient; 13static Registration registration; 14static TinyGPS gps; 15static Vessel vessel; 16 17long vesselId; 18 19void setup() { 20 Serial.begin(9600); 21 Serial.print(F("Setup Vessel: ")); Serial.println( VESSEL ); 22 vesselId = -1; 23 webClient.setup(); 24 registration.setup(); 25 gps.setup(); 26 vessel.setup(); 27} 28 29void loop() { 30 gps.loop(); 31 if ( vesselId < 0 ) { 32 vesselId = registration.registerVessel( VESSEL, PASSPHRASE, gps.getLatitude(), gps.getLongitude() ); 33 if ( vesselId > 0 ) { 34 Serial.print(F("REGISTERED VESSEL: ")); Serial.println( vesselId ); 35 webClient.setAuthentication( vesselId, PASSPHRASE ); 36 } else 37 Serial.print(F("REGISTRATION FAILED: ")); Serial.println( vesselId ); 38 } else { 39 Serial.print(F("VESSEL: ")); Serial.println( vesselId ); 40 //vessel.loop( gps.getBearing()); 41 } 42 43 delay(1000); 44}
Vessel
c_cpp
Implementation of the Vessel
1//Constructor 2Vessel::Vessel() {}; 3 4void Vessel::setup() { 5 Serial.println(F("SETUP VESSEL" )); 6 enable = true; 7 Serial.print(F("VESSEL ENABLED: ")); Serial.println( enable ); 8 if (!enable ) 9 return; 10 speed = 0; 11 12 bool init = false; 13 Serial.print(F("INITIALISING VESSEL: ")); Serial.println( !init ); 14 Serial.print(F("VESSEL READY ")); Serial.println( init ); 15 delay( 1000); 16} 17 18 19void Vessel::setCourse( double heading, double thrst ) { 20 // Serial.print(F("Bearing: ")); Serial.print( bearing ); Serial.print(F(", Thrust: ")); Serial.println( thrst ); 21 bearing = heading; 22 Serial.print(F("\ 23Course updated (")); Serial.print( bearing); Serial.print(F(", ")); 24 Serial.print( thrst ); Serial.println(F(")\ 25")); 26} 27 28/** 29 Send the current location and get a stack with the next steps to take. 30 The first latlnh should be entered last, so that the can be popped 31*/ 32bool Vessel::update( double latitde, double longitde, double bearing, double speed, bool updated ) { 33 if ( ! webClient.connect() ) 34 return false; 35 webClient.setContext( AQUABOTS_VESSEL_CONTEXT ); 36 data.latitude = latitde; 37 data.longitude = longitde; 38 String url = F("&lo="); 39 url += String( data.longitude, 8 ); 40 url += F("&la="); 41 url += String( data.latitude, 8); 42 url += F("&b="); 43 url += bearing; 44 url += F("&s="); 45 url += speed; 46 url += F("&u="); 47 url += updated; 48 //Serial.print(F("UPDATE VESSEL: ")); 49 //Serial.println( url); 50 51 boolean result = webClient.sendHttp( WebClient::UPDATE, false, url); 52 if (!result ) { 53 webClient.disconnect(); 54 return false; 55 } 56 57 //String response = webClient.printResponse( WebClient::UPDATE ); 58 //Serial.print(F("\ 59\ 60HEADING: \ 61")); Serial.println( response); 62 63 size_t capacity = JSON_OBJECT_SIZE(11) + 79; 64 DynamicJsonDocument doc(capacity); 65 DeserializationError error = deserializeJson(doc, webClient.client); 66 if (error) { 67 Serial.println(F("Parsing update failed!")); 68 webClient.disconnect(); 69 return false; 70 } 71 JsonObject root = doc.as<JsonObject>(); 72 data.heading = root["h"]; 73 data.thrust = root["t"]; 74 data.time = root["tm"]; 75 data.manual = root["mn"]; 76 webClient.disconnect(); 77 setCourse( data.heading, data.thrust); 78 return true; 79} 80 81void Vessel::stop() { 82 Serial.println("\ 83\ 84STOPPING!!!"); 85 bearing = 0; 86 speed = 0; 87} 88 89void Vessel::loop( double heading) { 90 if ( !enable ) 91 return; 92}
Registration.h
c_cpp
Header file to register your vessel
1#ifndef Registration_h 2#define Registration_h 3 4#define REGISTRATION "Registration" 5#define REGISTRATION_ID "registration" 6 7class Registration { 8 9 private: 10 bool enabled; //general purpose flag 11 long vesselId; 12 13 public: Registration(void); 14 void setup(); 15 long registerVessel( String name, String passphrase, double latitude, double longitude); 16 bool getConfig(); 17}; 18 19#endif
TinyGPS
c_cpp
Implementation of the GPS unit
1#include "TinyGPS.h" 2 3TinyGPS::TinyGPS() {}; 4 5//Repeatedly feed it characters from your 6void TinyGPS::setup( ) { 7 Serial1.begin(9600); 8 Serial.println(F("GPS INITIALISED")); 9} 10 11double TinyGPS::getLatitude() { 12 return latitude; 13} 14 15double TinyGPS::getLongitude() { 16 return longitude; 17} 18 19double TinyGPS::getBearing( double latFrom, double lonFrom, double latTo, double lonTo ) { 20 return gps.courseTo( latFrom, lonFrom, latTo, lonTo ); 21} 22 23double TinyGPS::getDistance( double latFrom, double lonFrom, double latTo, double lonTo ) { 24 return gps.distanceBetween( latFrom, lonFrom, latTo, lonTo ); 25} 26 27void TinyGPS::loop() { 28 Serial.println(F("CHECKING GPS")); 29 bool updated = false; 30 unsigned long current = millis(); 31 double speed = 0; 32 double bearing = 0; 33 while (Serial1.available() && ( millis() < ( current + TIME_OUT ))) { 34 char chr = Serial1.read(); 35 Serial.print(chr ); 36 gps.encode( chr ); 37 updated = gps.location.isUpdated(); 38 if ( updated ) { 39 40 latitude = gps.location.lat(); 41 longitude = gps.location.lng(); 42 bearing = gps.course.deg(); 43 speed = gps.speed.mps(); 44 Serial.print(F("\ 45\ 46GPS Location Updated: ")); 47 Serial.print( latitude, 6 ); Serial.print("E "); 48 Serial.print( longitude, 6 ), Serial.println("N\ 49\ 50 "); // bearing, speed ); 51 break; 52 } 53 54 } 55 56 if (( latitude >= 0 ) && ( longitude >= 0 )) 57 vessel.update( latitude, longitude, bearing, speed, updated ); 58}
Registration
c_cpp
Implementation of the Registration Module
1Registration::Registration() {}; 2 3void Registration::setup( ) { 4 enabled = true; 5} 6 7long Registration::registerVessel( String vesselName, String passphrase, double latitude, double longitude ) { 8 if ( !enabled ) 9 return -1; 10 if ( !webClient.connect() ) 11 return -2; 12 13 webClient.setContext( AQUABOTS_REGISTRATION_CONTEXT ); 14 Serial.print(F("Registering Vessel: ")); Serial.println( vesselName ); 15 String url = F("&name="); 16 url += String( vesselName ); 17 url += F("&passphrase="); 18 url += String( passphrase); 19 url += F("&latitude="); 20 url += String( latitude); 21 url += F("&longitude="); 22 url += String( longitude); 23 24 boolean result = webClient.sendHttp( WebClient::REGISTER_VESSEL, false, url); 25 if (!result ) { 26 webClient.disconnect(); 27 return -3; 28 } 29 String retval = ""; 30 while (webClient.client.available()) { 31 char c = webClient.client.read(); 32 retval += c; 33 } 34 Serial.println( retval); 35 vesselId = atol( retval.c_str() ); 36 webClient.disconnect(); 37 Serial.print(F("Vessel Registered: ")); Serial.println( vesselId ); 38 return vesselId; 39} 40 41bool Registration::getConfig() { 42}
Registration.h
c_cpp
Header file to register your vessel
1#ifndef Registration_h 2#define Registration_h 3 4#define REGISTRATION "Registration" 5#define REGISTRATION_ID "registration" 6 7class Registration { 8 9 private: 10 bool enabled; //general purpose flag 11 long vesselId; 12 13 public: Registration(void); 14 void setup(); 15 long registerVessel( String name, String passphrase, double latitude, double longitude); 16 bool getConfig(); 17}; 18 19#endif
TinyGPS
c_cpp
Implementation of the GPS unit
1#include "TinyGPS.h" 2 3TinyGPS::TinyGPS() {}; 4 5//Repeatedly feed it characters from your 6void TinyGPS::setup( ) { 7 Serial1.begin(9600); 8 Serial.println(F("GPS INITIALISED")); 9} 10 11double TinyGPS::getLatitude() { 12 return latitude; 13} 14 15double TinyGPS::getLongitude() { 16 return longitude; 17} 18 19double TinyGPS::getBearing( double latFrom, double lonFrom, double latTo, double lonTo ) { 20 return gps.courseTo( latFrom, lonFrom, latTo, lonTo ); 21} 22 23double TinyGPS::getDistance( double latFrom, double lonFrom, double latTo, double lonTo ) { 24 return gps.distanceBetween( latFrom, lonFrom, latTo, lonTo ); 25} 26 27void TinyGPS::loop() { 28 Serial.println(F("CHECKING GPS")); 29 bool updated = false; 30 unsigned long current = millis(); 31 double speed = 0; 32 double bearing = 0; 33 while (Serial1.available() && ( millis() < ( current + TIME_OUT ))) { 34 char chr = Serial1.read(); 35 Serial.print(chr ); 36 gps.encode( chr ); 37 updated = gps.location.isUpdated(); 38 if ( updated ) { 39 40 latitude = gps.location.lat(); 41 longitude = gps.location.lng(); 42 bearing = gps.course.deg(); 43 speed = gps.speed.mps(); 44 Serial.print(F("\ 45\ 46GPS Location Updated: ")); 47 Serial.print( latitude, 6 ); Serial.print("E "); 48 Serial.print( longitude, 6 ), Serial.println("N\ 49\ 50 "); // bearing, speed ); 51 break; 52 } 53 54 } 55 56 if (( latitude >= 0 ) && ( longitude >= 0 )) 57 vessel.update( latitude, longitude, bearing, speed, updated ); 58}
Vessel
c_cpp
Implementation of the Vessel
1//Constructor 2Vessel::Vessel() {}; 3 4void Vessel::setup() { 5 Serial.println(F("SETUP VESSEL" )); 6 enable = true; 7 Serial.print(F("VESSEL ENABLED: ")); Serial.println( enable ); 8 if (!enable ) 9 return; 10 speed = 0; 11 12 bool init = false; 13 Serial.print(F("INITIALISING VESSEL: ")); Serial.println( !init ); 14 Serial.print(F("VESSEL READY ")); Serial.println( init ); 15 delay( 1000); 16} 17 18 19void Vessel::setCourse( double heading, double thrst ) { 20 // Serial.print(F("Bearing: ")); Serial.print( bearing ); Serial.print(F(", Thrust: ")); Serial.println( thrst ); 21 bearing = heading; 22 Serial.print(F("\ 23Course updated (")); Serial.print( bearing); Serial.print(F(", ")); 24 Serial.print( thrst ); Serial.println(F(")\ 25")); 26} 27 28/** 29 Send the current location and get a stack with the next steps to take. 30 The first latlnh should be entered last, so that the can be popped 31*/ 32bool Vessel::update( double latitde, double longitde, double bearing, double speed, bool updated ) { 33 if ( ! webClient.connect() ) 34 return false; 35 webClient.setContext( AQUABOTS_VESSEL_CONTEXT ); 36 data.latitude = latitde; 37 data.longitude = longitde; 38 String url = F("&lo="); 39 url += String( data.longitude, 8 ); 40 url += F("&la="); 41 url += String( data.latitude, 8); 42 url += F("&b="); 43 url += bearing; 44 url += F("&s="); 45 url += speed; 46 url += F("&u="); 47 url += updated; 48 //Serial.print(F("UPDATE VESSEL: ")); 49 //Serial.println( url); 50 51 boolean result = webClient.sendHttp( WebClient::UPDATE, false, url); 52 if (!result ) { 53 webClient.disconnect(); 54 return false; 55 } 56 57 //String response = webClient.printResponse( WebClient::UPDATE ); 58 //Serial.print(F("\ 59\ 60HEADING: \ 61")); Serial.println( response); 62 63 size_t capacity = JSON_OBJECT_SIZE(11) + 79; 64 DynamicJsonDocument doc(capacity); 65 DeserializationError error = deserializeJson(doc, webClient.client); 66 if (error) { 67 Serial.println(F("Parsing update failed!")); 68 webClient.disconnect(); 69 return false; 70 } 71 JsonObject root = doc.as<JsonObject>(); 72 data.heading = root["h"]; 73 data.thrust = root["t"]; 74 data.time = root["tm"]; 75 data.manual = root["mn"]; 76 webClient.disconnect(); 77 setCourse( data.heading, data.thrust); 78 return true; 79} 80 81void Vessel::stop() { 82 Serial.println("\ 83\ 84STOPPING!!!"); 85 bearing = 0; 86 speed = 0; 87} 88 89void Vessel::loop( double heading) { 90 if ( !enable ) 91 return; 92}
Vessels
c_cpp
Main Arduino Code
1#include <ArduinoJson.h> 2 3#include "WebClient.h" 4#include "Registration.h" 5#include "TinyGPS.h" 6#include "Vessel.h" 7 8#define VESSEL F("MyBoatName") 9#define PASSPHRASE F("MyPassPhrase") 10#define TIME_OUT 3000 //msec 11 12static WebClient webClient; 13static Registration registration; 14static TinyGPS gps; 15static Vessel vessel; 16 17long vesselId; 18 19void setup() { 20 Serial.begin(9600); 21 Serial.print(F("Setup Vessel: ")); Serial.println( VESSEL ); 22 vesselId = -1; 23 webClient.setup(); 24 registration.setup(); 25 gps.setup(); 26 vessel.setup(); 27} 28 29void loop() { 30 gps.loop(); 31 if ( vesselId < 0 ) { 32 vesselId = registration.registerVessel( VESSEL, PASSPHRASE, gps.getLatitude(), gps.getLongitude() ); 33 if ( vesselId > 0 ) { 34 Serial.print(F("REGISTERED VESSEL: ")); Serial.println( vesselId ); 35 webClient.setAuthentication( vesselId, PASSPHRASE ); 36 } else 37 Serial.print(F("REGISTRATION FAILED: ")); Serial.println( vesselId ); 38 } else { 39 Serial.print(F("VESSEL: ")); Serial.println( vesselId ); 40 //vessel.loop( gps.getBearing()); 41 } 42 43 delay(1000); 44}
Vessel.h
c_cpp
The header file for the functionality of the vessel
1#ifndef Vessel_h 2#define Vessel_h 3 4#define DEFAULT_RANGE 12;//12 mtrs 5 6class Vessel { 7 /** 8 Vessel Data object 9 */ 10 struct VesselData { 11 int time; 12 double latitude;//current position 13 double longitude; 14 double heading; 15 double thrust; 16 bool manual; 17 }; 18 19 public: Vessel(); 20 21 void setup(); 22 void setCourse( double bearing, double thrust );//returns true if the course is within the turn angle 23 bool update( double latitude, double longitude, double bearing, double speed, bool updated ); 24 void loop( double bearing); 25 void stop(); 26 27 private: 28 bool enable; 29 double bearing;//0-360 30 double speed; 31 VesselData data; 32 }; 33 34#endif
TinyGPS.h
c_cpp
Header file for the GPS Unit
1#ifndef TinyGPS_h 2#define TinyGPS_h 3 4#define TINY_GPS "TinyGPS" 5#define TINY_GPS_ID "gps.tiny" 6 7#include <SoftwareSerial.h> 8#include <TinyGPS++.h> 9 10class TinyGPS{ 11 12 private: 13 TinyGPSPlus gps; 14 double latitude; 15 double longitude; 16 17 public: TinyGPS(void); 18 void setup(); 19 double getLatitude(); 20 double getLongitude(); 21 double getBearing( double latFrom, double lonFrom, double latTo, double lonTo ); 22 double getDistance( double latFrom, double lonFrom, double latTo, double lonTo ); 23 bool wait();//wait for processing of the nmea sentence 24 void loop(); 25}; 26 27#endif
Registration
c_cpp
Implementation of the Registration Module
1Registration::Registration() {}; 2 3void Registration::setup( ) { 4 5 enabled = true; 6} 7 8long Registration::registerVessel( String vesselName, 9 String passphrase, double latitude, double longitude ) { 10 if ( !enabled ) 11 12 return -1; 13 if ( !webClient.connect() ) 14 return -2; 15 16 webClient.setContext( 17 AQUABOTS_REGISTRATION_CONTEXT ); 18 Serial.print(F("Registering Vessel: ")); 19 Serial.println( vesselName ); 20 String url = F("&name="); 21 url += String( 22 vesselName ); 23 url += F("&passphrase="); 24 url += String( passphrase); 25 26 url += F("&latitude="); 27 url += String( latitude); 28 url += F("&longitude="); 29 30 url += String( longitude); 31 32 boolean result = webClient.sendHttp( WebClient::REGISTER_VESSEL, 33 false, url); 34 if (!result ) { 35 webClient.disconnect(); 36 return -3; 37 38 } 39 String retval = ""; 40 while (webClient.client.available()) { 41 char 42 c = webClient.client.read(); 43 retval += c; 44 } 45 Serial.println( retval); 46 47 vesselId = atol( retval.c_str() ); 48 webClient.disconnect(); 49 Serial.print(F("Vessel 50 Registered: ")); Serial.println( vesselId ); 51 return vesselId; 52} 53 54bool 55 Registration::getConfig() { 56}
Vessel.h
c_cpp
The header file for the functionality of the vessel
1#ifndef Vessel_h 2#define Vessel_h 3 4#define DEFAULT_RANGE 12;//12 mtrs 5 6class Vessel { 7 /** 8 Vessel Data object 9 */ 10 struct VesselData { 11 int time; 12 double latitude;//current position 13 double longitude; 14 double heading; 15 double thrust; 16 bool manual; 17 }; 18 19 public: Vessel(); 20 21 void setup(); 22 void setCourse( double bearing, double thrust );//returns true if the course is within the turn angle 23 bool update( double latitude, double longitude, double bearing, double speed, bool updated ); 24 void loop( double bearing); 25 void stop(); 26 27 private: 28 bool enable; 29 double bearing;//0-360 30 double speed; 31 VesselData data; 32 }; 33 34#endif
WebClient
c_cpp
Implementation of the communication with the Aquabots Client
1WebClient::WebClient() {} 2 3void WebClient::setup() { 4 host = CONDAST_URL; 5 port = PORT; 6 context = AQUABOTS_REGISTRATION_CONTEXT; 7 8 // start the Ethernet connection: 9 Serial.print(F("SETUP WEB CLIENT: ")); Serial.println( ip ); 10 if (Ethernet.begin(mac) == 0) { 11 Serial.println(F("Failed to configure Ethernet using DHCP")); 12 // try to congifure using IP address instead of DHCP: 13 Ethernet.begin(mac, ip); 14 } 15 // give the Ethernet shield a second to initialize: 16 Serial.print(F("WEB CLIENT...")); 17 delay(2000); 18 Serial.println(Ethernet.localIP()); 19 Serial.println(F("connecting...")); 20 connect(); 21} 22 23bool WebClient::connect() { 24 //Serial.print(F("Connecting to: ")); Serial.print( server ); Serial.print(F(":")); Serial.print( port ); Serial.print(F(" ...")); 25 //client.setTimeout(5000); 26 int result = client.connect(server, port); 27 //Serial.print(F("Connected: ")); Serial.println( result ); 28 if ( result) { 29 //Serial.print(F("success! ")); 30 //Serial.println(Ethernet.localIP()); 31 //Serial.println(Ethernet.gatewayIP()); 32 connected = result; 33 return result; 34 } else { 35 //Serial.println(F("failed. ")); 36 client.stop(); 37 } 38} 39 40void WebClient::disconnect() { 41 client.stop(); 42 //if ( connected ) 43 // Serial.println(F("Disconnecting: Complete ")); 44 connected = false; 45} 46 47void WebClient::setAuthentication( long i, String t ){ 48 id = i; 49 token = t; 50} 51 52void WebClient::setContext( String c ){ 53 context = c; 54} 55 56void WebClient::requestService( int request ) { 57 switch ( request ) { 58 case REGISTER_VESSEL: 59 client.print(F("register")); 60 break; 61 case VESSEL_CONFIG: 62 client.print(F("config")); 63 break; 64 case DEBUG: 65 client.print(F("debug")); 66 break; 67 case FIELD: 68 client.print(F("field")); 69 break; 70 case DATA: 71 client.print(F("data")); 72 break; 73 case NMEA: 74 client.print(F("nmea")); 75 break; 76 case OPTIONS: 77 client.print(F("options")); 78 break; 79 case LOG: 80 client.print(F("log")); 81 break; 82 case WAYPOINTS: 83 client.print(F("waypoints")); 84 break; 85 case WAYPOINT: 86 client.print(F("waypoint")); 87 break; 88 case UPDATE: 89 client.print(F("update")); 90 break; 91 default: 92 client.print(F("unknown")); 93 break; 94 } 95} 96 97/** 98 Is used to transform the int to a String 99*/ 100void WebClient::logRequestStr( int request ) { 101 switch ( request ) { 102 case REGISTER_VESSEL: 103 Serial.print(F("register")); 104 break; 105 case VESSEL_CONFIG: 106 Serial.print(F("config")); 107 break; 108 case DEBUG: 109 Serial.print(F("debug")); 110 break; 111 case FIELD: 112 Serial.print(F("field")); 113 break; 114 case DATA: 115 Serial.print(F("data")); 116 break; 117 case NMEA: 118 Serial.print(F("nmea")); 119 break; 120 case LOG: 121 Serial.print(F("log")); 122 break; 123 case WAYPOINTS: 124 Serial.print(F("waypoints")); 125 break; 126 case WAYPOINT: 127 Serial.print(F("waypoint")); 128 break; 129 case UPDATE: 130 Serial.print(F("update")); 131 break; 132 case OPTIONS: 133 Serial.print(F("options")); 134 break; 135 default: 136 Serial.print(F("unknown (")); Serial.print( request ); Serial.print(F(")")); 137 break; 138 } 139} 140 141boolean WebClient::sendHttp( int request, String message ) { 142 String msg = message; 143 if ( msg.length() > 0 ) { 144 msg = F("&msg="); 145 msg += message; 146 } 147 return sendHttp( request, false, msg ); 148} 149 150boolean WebClient::sendHttp( int request, boolean post, String attrs ) { 151 if ( client.connected()) { 152 //if ( request != NMEA ) 153 //Serial.print(F("REQUEST ")); logRequestStr( request ); 154 // Serial.print(F(" ?id")); Serial.print( id ); 155 //Serial.print(F("&token")); Serial.print( token ); 156 //Serial.print(F(" ")); Serial.println(attrs ); 157 //logRequest( request, post, attrs ); 158 159 // Make a HTTP request: 160 client.print( post ? F("POST ") : F("GET ") ); 161 client.print( context ); 162 //Serial.print(F("context: ")); Serial.print( context ); 163 requestService( request ); 164 client.print(F("?id=" )); 165 client.print( id ); 166 client.print(F("&token=")); 167 client.print( token ); 168 if ( !post && ( attrs.length() > 0 )) { 169 client.print( attrs ); 170 } 171 client.println(F(" HTTP/1.1" )); 172 173 client.print(F("Host: ")); 174 client.println( host ); 175 client.println(F("Connection: close\ \ 176")); 177 if ( post && ( attrs.length() > 0 )) { 178 client.println( F("Accept: */*")); 179 client.println( F("Content-Type: application/x-www-form-urlencoded ; charset=UTF-8" )); 180 client.print( F("Content-Length: ")); 181 client.println( attrs.length() ); 182 client.println(); 183 client.println( urlencode( attrs )); 184 } 185 client.println(); 186 return processResponse( request ); 187 } 188 return false; 189} 190 191/** 192 Handle the response, by taking away header info and such 193*/ 194bool WebClient::processResponse( int request ) { 195 // Check HTTP status 196 char status[32] = {"\\0"}; 197 client.setTimeout(HTTP_TIMEOUT); 198 client.readBytesUntil('\r', status, sizeof(status)); 199 char http_ok[32] = {"\\0"}; 200 strcpy( http_ok, "HTTP/1.1 200 OK"); 201 if (strcmp(status, http_ok) != 0) { 202 Serial.print(F( "Unexpected response (" )); logRequestStr( request); Serial.print(F( "):" )); 203 Serial.println(status); 204 return false; 205 } 206 207 // Skip HTTP headers 208 char endOfHeaders[] = "\ \ 209\ \ 210"; 211 if (!client.find(endOfHeaders)) { 212 Serial.println( F( "Invalid response (" )); logRequestStr( request); Serial.print(F( "):" )); 213 return false; 214 } 215 return true; 216} 217 218void WebClient::logRequest( int request, boolean post, String attrs ) { 219 // Make a HTTP request: 220 Serial.print( post ? F("POST ") : F("GET ")); 221 Serial.print( context ); 222 logRequestStr( request ); 223 Serial.print(F( "?id=" )); 224 Serial.print( id ); 225 Serial.print(F( "&token=" )); 226 Serial.print( token ); 227 if ( !post && ( attrs.length() > 0 )) { 228 Serial.print( attrs ); 229 } 230 Serial.print(F( " HTTP/1.1" )); 231 Serial.println(); 232 Serial.print(F( "Host: ")); 233 Serial.println( host ); 234 Serial.println(F( "Connection: close" )); 235 if ( post && ( attrs.length() > 0 )) { 236 Serial.println(F( "Accept: */*" )); 237 Serial.println(F( "Content-Type: application/x-www-form-urlencoded ; charset=UTF-8")); 238 Serial.print(F( "Content-Length: ")); 239 Serial.println( attrs.length() ); 240 Serial.println(); 241 Serial.println( attrs ); 242 } 243} 244 245/** 246 Creates a String request from the client 247*/ 248String WebClient::printResponse( int request ) { 249 Serial.print( F("RESPONSE TO ")); 250 logRequestStr( request ); 251 // Serial.print(" PROCESSING: "); 252 //Serial.print( client.available() ); 253 String retval = ""; 254 255 // Serial.println(); 256 while (client.available()) { 257 char c = client.read(); 258 retval += c; 259 } 260 Serial.print( F( ": ")); Serial.println( retval ); 261} 262 263void WebClient::loop() { 264 // if there are incoming bytes available 265 // from the server, read them and print them: 266 if (!client.connected()) { 267 connect(); 268 } 269} 270 271/* 272 ESP8266 Hello World urlencode by Steve Nelson 273 URLEncoding is used all the time with internet urls. This is how urls handle funny characters 274 in a URL. For example a space is: %20 275 These functions simplify the process of encoding and decoding the urlencoded format. 276 277 It has been tested on an esp12e (NodeMCU development board) 278 This example code is in the public domain, use it however you want. 279 Prerequisite Examples: 280 https://github.com/zenmanenergy/ESP8266-Arduino-Examples/tree/master/helloworld_serial 281*/ 282String WebClient::urldecode(String str) { 283 String encodedString = ""; 284 char c; 285 char code0; 286 char code1; 287 for (int i = 0; i < str.length(); i++) { 288 c = str.charAt(i); 289 if (c == '+') { 290 encodedString += ' '; 291 } else if (c == '%') { 292 i++; 293 code0 = str.charAt(i); 294 i++; 295 code1 = str.charAt(i); 296 c = (h2int(code0) << 4) | h2int(code1); 297 encodedString += c; 298 } else { 299 300 encodedString += c; 301 } 302 yield(); 303 } 304 305 return encodedString; 306} 307 308String WebClient::urlencode(String str) 309{ 310 String encodedString = ""; 311 char c; 312 char code0; 313 char code1; 314 char code2; 315 for (int i = 0; i < str.length(); i++) { 316 c = str.charAt(i); 317 if (c == ' ') { 318 encodedString += '+'; 319 } else if (isalnum(c)) { 320 encodedString += c; 321 } else { 322 code1 = (c & 0xf) + '0'; 323 if ((c & 0xf) > 9) { 324 code1 = (c & 0xf) - 10 + 'A'; 325 } 326 c = (c >> 4) & 0xf; 327 code0 = c + '0'; 328 if (c > 9) { 329 code0 = c - 10 + 'A'; 330 } 331 code2 = '\\0'; 332 encodedString += '%'; 333 encodedString += code0; 334 encodedString += code1; 335 //encodedString+=code2; 336 } 337 yield(); 338 } 339 return encodedString; 340 341} 342 343unsigned char WebClient::h2int(char c) 344{ 345 if (c >= '0' && c <= '9') { 346 return ((unsigned char)c - '0'); 347 } 348 if (c >= 'a' && c <= 'f') { 349 return ((unsigned char)c - 'a' + 10); 350 } 351 if (c >= 'A' && c <= 'F') { 352 return ((unsigned char)c - 'A' + 10); 353 } 354 return (0); 355}
WebClient.h
c_cpp
Header file of the communication with the Aquabots Client
1#ifndef WebClient_h 2#define WebClient_h 3 4#include <SPI.h> 5#include 6 <Ethernet.h> 7 8#define AQUABOTS_REGISTRATION_CONTEXT F("/arnac/registration/") 9#define 10 AQUABOTS_VESSEL_CONTEXT F("/arnac/rest/") 11#define CONDAST_URL F("www.condast.com") 12 13const 14 unsigned long HTTP_TIMEOUT = 5000;// max respone time from server 15 16/* 17 18 Web client 19 20 This sketch connects to a website 21 using an Arduino Wiznet 22 Ethernet shield. 23 24 Circuit: 25 Ethernet shield attached to pins 10, 11, 26 12, 13 27 28 created 18 Dec 2009 29 by David A. Mellis 30 modified 9 Apr 31 2012 32 by Tom Igoe, based on work by Adrian McEwen 33 34*/ 35 36//Condast 37 SERVER 38// Set the static IP address to use if the DHCP fails to assign 39//const 40 char server[] = "www.condast.com"; 41//IPAddress ip(79, 170, 90, 5); 42//const 43 int PORT = 8080; 44 45//LOCALHOST 46// Set the static IP address to use if the 47 DHCP fails to assign 48IPAddress server(192, 168, 178, 41); 49IPAddress ip(192, 50 168, 178, 41); 51const int PORT = 10080; 52 53//Huawei 54//IPAddress server(192,168,8,100); 55//IPAddress 56 ip(192,168,8,100); 57//const int PORT = 10081; 58 59//Havenlab 60//IPAddress 61 server(192,168,10,110); 62//IPAddress ip(192,168,10,110); 63//const int PORT = 64 10080; 65 66// Enter a MAC address for your controller below. 67// Newer Ethernet 68 shields have a MAC address printed on a sticker on the shield 69const byte mac[] 70 = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 71 72class WebClient { 73 74 public: 75 WebClient(); 76 enum request { 77 UNKNOWN = 0, 78 REGISTER_VESSEL 79 = 1, 80 VESSEL_CONFIG = 2, 81 DEBUG = 3, 82 FIELD = 4, 83 UPDATE 84 = 5, 85 WAYPOINTS = 6, 86 DATA = 7, 87 NMEA = 8, 88 OPTIONS 89 = 9, 90 LOG = 10, 91 WAYPOINT = 11 92 }; 93 94 const unsigned 95 long HTTP_TIMEOUT = 5000;// max respone time from server 96 97 EthernetClient 98 client; 99 void setup(); 100 bool connect(); 101 void disconnect(); 102 103 void setAuthentication( long id, String token ); 104 void setContext( String 105 context ); 106 bool requestLog(); 107 bool logMessage( String message ); 108 109 bool getWaypoint(); 110 bool sendUpdate( String url ); 111 bool sendHttp( 112 int request, String msg ); 113 bool sendHttp( int request, boolean post, String 114 attrs ); 115 String urlencode(String str); 116 String printResponse( int request 117 ); 118 void logRequest( int request, boolean post, String attrs );//for debugging 119 120 void logRequestStr( int request ); //dito 121 void loop(); 122 123 private: 124 125 String host; 126 int port; 127 bool connected; 128 String context; 129 130 long id; 131 String token; 132 133 // Initialize the Ethernet client library 134 135 // with the IP address and port of the server 136 // that you want to connect 137 to (port 80 is default for HTTP): 138 void requestService( int request ); 139 140 bool processResponse( int request ); 141 boolean update( JsonObject& root 142 ); 143 String urldecode(String str); 144 unsigned char h2int(char c); 145}; 146 147#endif
TinyGPS.h
c_cpp
Header file for the GPS Unit
1#ifndef TinyGPS_h 2#define TinyGPS_h 3 4#define TINY_GPS "TinyGPS" 5#define 6 TINY_GPS_ID "gps.tiny" 7 8#include <SoftwareSerial.h> 9#include <TinyGPS++.h> 10 11class 12 TinyGPS{ 13 14 private: 15 TinyGPSPlus gps; 16 double latitude; 17 double 18 longitude; 19 20 public: TinyGPS(void); 21 void setup(); 22 double getLatitude(); 23 24 double getLongitude(); 25 double getBearing( double latFrom, double lonFrom, 26 double latTo, double lonTo ); 27 double getDistance( double latFrom, double 28 lonFrom, double latTo, double lonTo ); 29 bool wait();//wait for processing 30 of the nmea sentence 31 void loop(); 32}; 33 34#endif
Comments
Only logged in users can leave comments