Arduino + GPS + WiFI da 50-70 euro
Articolo velocissimo.
Sarò ermetico: Arduino + ESP8266 WiFi + Sensore Temperatura/umidità DHT11 (potete mettere qualsiasi cosa) + GPS NEO-6M della UBOX + SparkFun Database remoto + mappa Umap realtime + HotSpot (fisso o usando smartphone). Su ebay ho preso tutto con meno di 50 euro: arduino + alimentatore 10 euro, esp8266 5 euro + dht11 4 euro + gps 20 euro + minuterie breadboard ect
Si può usare da allarme: se le coordinate di base, esempio di casa, distano più di 10 metri, fa scattare l’allarme e scrive nel DB remoto. In tal caso ho inserito un modem Umts (bastava edge) di quelli economici che fanno da hotspot WiFi (20 euro su ebay).
oppure usando come hotspot il proprio smartphone, si potrebbe mettere la centralina in una scatola installata in una bicicletta e cosi girando per la città si mappano spostamenti, differenze di temperature e umidità o Co2 ect…
Tutte le coordinate scritte sul sito data.sparkfun.com vengono interfacciate con Umap per avere una mappa realtime (basta mettere il link “CSV” nel campo “Dati remoti” presente nel layer di Umap).
In cosa vi ho inserito un video dimostrativo. Per i collegamenti:
1) ESP8266 VCC e CH_D vanno ai 3.3V (io ho usato un convertitore da 5v a 3.3v attenti).
2) ESP8266 RX al Pin 8 e il TX al 9 dei digitali di Arduino
3) DHT11 collegando i VCC e GND e il pin centrale Data al 2 digitale di Arduino
4) il GPS ha 4 pin. a parte VCC e GND poi l’RX al 6 e il TX al 7 di Arduino.
Parte complessa: l’ESP8266 deve avere il firmware almeno 950 FW21.
Cercate in rete come fare l’upgrade del FW. Ve ne accorgete perchè durante l’esecuzione parte la richiesta di visualizzare il fw installato nella scheda.
Nel file ESP8266.h va decommentato: //#define ESP8266_USE_SOFTWARE_SERIAL e messo VERSION_22
Attenzione il BaudRate del monitor seriale di Arduino è 115200.
Eccovi il codice commentato e da personalizzare :
1) public e private key di SparkFun.com oppure se si usa il sistema ThingSpeak.com bisogna decommentare la sezione indicata e mettere nel Char = la propria API.
2) coordinate del punto iniziale/da monitorare. Tipo quelle di casa propria o del parcheggio dov’è il Camper/Barca ect. Formato 40.123456 (come esempio Latitudine).
3) SSID e Password del proprio hotspot WiFi. Nel caso usate il vostro smartphone/iPhone abilitate il tethering-hotspot e copiate nel codice la password che vi genera il cellulare.
includere le librerie ESP8266.h SoftwareSerial.h TinyGPS++.h e il file “DHT.h”
#include < ESP8266.h >
#include < SoftwareSerial.h >
#include < TinyGPS++.h >
#include "DHT.h"
#define DHTPIN 2 // GPIO 0 pin of ESP8266
float h;
float t;
float f;
String Lat;
String Lng;
bool invio=0;
#define SSID "" // inserire qui SSID
#define PASS "" // inserire qui Password WiFi
#define IP "184.106.153.149" // thingspeak.com
#define HOST_PORT (80)
#define ESP8266_LED 13
const char* host = "54.86.132.254";
String hoststring = "54.86.132.254"; //serve anche come String per uso nell'API
String publicKey = ""; //publicKey di Sparkfun. Sarebbe il link per lo stream
String privateKey = ""; //privateKey di Sparkfun per scrivere nel DB
unsigned long last = 0UL;
int httpPort = 80;
static const int RXPin = 6, TXPin = 7;
static const uint32_t GPSBaud = 9600;
// The TinyGPS++ object
TinyGPSPlus gps;
DHT dht(DHTPIN, DHT11,20);
// The serial connection to the GPS device
SoftwareSerial ss(RXPin, TXPin);
SoftwareSerial seriale(8,9); // RX, TX
ESP8266 wifi(seriale);
void(* resetFunc) (void) = 0;
void setup()
{
wifi.restart();
Serial.begin(115200);
seriale.begin(115200);
delay(4000);
if (wifi.setOprToStationSoftAP()) {
Serial.print("to station + softap ok\r\n");
} else {
Serial.print("to station + softap err\r\n");
}
if (wifi.disableMUX()) {
Serial.print("single ok\r\n");
} else {
Serial.print("single err\r\n");
}
delay(1000);
ss.begin(GPSBaud);
dht.begin();
for (int t=0;t<5000;t ++){ //loop abbastanza lungo per avere un fix GPS
gps.encode(ss.read());
if (gps.location.isUpdated())
{
//ss.end();
/*
Serial.print(F("LOCATION Fix Age="));
Serial.print(gps.location.age());
Serial.print(F("ms Raw Lat="));
Serial.print(gps.location.rawLat().negative ? "-" : "+");
Serial.print(gps.location.rawLat().deg);
Serial.print("[+");
Serial.print(gps.location.rawLat().billionths);
Serial.print(F(" billionths], Raw Long="));
Serial.print(gps.location.rawLng().negative ? "-" : "+");
Serial.print(gps.location.rawLng().deg);
Serial.print("[+");
Serial.print(gps.location.rawLng().billionths);
Serial.print(F(" billionths], Lat="));
Serial.print(gps.location.lat(), 6);
Serial.print(F(" Long="));
Serial.println(gps.location.lng(), 6);
*/
// break;
if (gps.location.isValid())
{
//inserire le coordinate del punto di riferimento. esempio casa propria nel formato 40.123456
static const double CASA_LAT = INSERIRE LATITUDINE, CASA_LON = INSERIRE Longitudine;
double distanceToL =
TinyGPSPlus::distanceBetween(
gps.location.lat(),
gps.location.lng(),
CASA_LAT,
CASA_LON);
double courseToL =
TinyGPSPlus::courseTo(
gps.location.lat(),
gps.location.lng(),
CASA_LAT,
CASA_LON);
Serial.print(F("CASA Distance="));
Serial.print(distanceToL/1000, 6);
Serial.print(F(" km Course-to="));
Serial.print(courseToL, 6);
Serial.print(F(" degrees ["));
Serial.print(TinyGPSPlus::cardinal(courseToL));
Serial.println(F("]"));
float distance =distanceToL/1000;
if (distance > .01) {
Serial.println(F("ALLARME!!"));
break; //senza questo break non funziona la trasmissione Wifi
}
}
}
else{
if (gps.charsProcessed() < 10)
Serial.println(F("Attenzione non ci sono dati GPS. Controlla i collegamenti"));
last = millis();
Serial.println(t);
}
}
Lat=String(gps.location.lat(),6);
Lng=String(gps.location.lng(),6);
delay(1000);
if (wifi.kick() == 0){ //controllo se la ESP8266 è bloccata e la riavvio. Avendo un'unica seriale spesso si blocca alternando con GPS e DHT11
Serial.print("Lat:");
Serial.println(Lat);
Serial.print("Long:");
Serial.print(Lng);
Serial.println();
seriale.begin(115200);
wifi.restart();
Serial.println(wifi.kick());
}
Serial.print("FW Version:");
Serial.println(wifi.getVersion().c_str());
if (wifi.joinAP(SSID, PASS)) {
Serial.print("Join AP success\r\n");
Serial.print("IP:");
Serial.println( wifi.getLocalIP().c_str());
} else {
Serial.print("Join AP failure\r\n");
}
Temp();
delay(1000);
uint8_t buffer[128] = {0};
//per Thingspeak:
// if (wifi.createTCP(IP, HOST_PORT)) {
//per Sparkfun:
if (wifi.createTCP(host, HOST_PORT)) {
Serial.print("create tcp ok\r\n");
String Temp=String(t,0);
Temp.replace(".",",");
String Hum=String(h,0);
Hum.replace(".",",");
String Latit=String(Lat);
String Longit=String(Lng);
// prestare molta attenzione.
/*
//sezione se si vuole usare ThingSpeak API. Non si usa la variabile definita API ma si inserisce direttamente nella Char
char *prefix = "GET /update?key=inserirechiaveprivatathinkspeak&field1=";
//char *postfix =" HTTP/1.1\r\nHost: 184.106.153.149\r\nConnection: close\r\n\r\n";
char *postfix ="&field2=";
char *postfix1 ="&field3=";
char *postfix2 ="&field4=";
char *postfix3 =" HTTP/1.1\r\nHost: 184.106.153.149\r\n\r\n";
String uffa = prefix+Latit+postfix+Longit+postfix1+Temp+postfix2+Hum+postfix3;
*/
// sezione se si vuole usare https://data.sparkfun.com
//creare uno stream data sul sito https://data.sparkfun.com e mettere come campi hum,temp,lat,lng
String uffa="GET /input/";
uffa += publicKey;
uffa +="?private_key=";
uffa += privateKey;
uffa +="&hum=";
uffa +=Hum;
uffa +="&temp=";
uffa +=Temp;
uffa +="&lat=";
uffa +=Latit;
uffa +="&lng=";
uffa +=Longit;
uffa +=" HTTP/1.1\r\nHost: ";
uffa +=hoststring;
uffa +="\r\n\r\n";
const char *hello = uffa.c_str();
wifi.send((const uint8_t*)hello, strlen(hello));
uint32_t len1 = wifi.recv(buffer, sizeof(buffer), 10000);
if (len1 > 0) {
Serial.print("Received:[");
for(uint32_t i = 0; i < len1; i++) {
Serial.print((char)buffer[i]);
}
Serial.print("]\r\n");
}
delay(5000);
} else {
Serial.print("create tcp err\r\n");
delay(10000);
resetFunc();
}
Serial.print("setup Wifi end\r\n");
delay(5*60000);
setup();
}
void loop(){
}
void Temp(){
dht.begin();
t=0;
h=0;
h = dht.readHumidity();
// Read temperature as Celsius
t = dht.readTemperature();
// Read temperature as Fahrenheit
f = dht.readTemperature(true);
// Compute heat index
// Must send in temp in Fahrenheit!
float hi = dht.computeHeatIndex(f, h);
float hic=(hi-32)/1.8000; // Converto in Celsius
// Check if any reads failed and exit early (to try again).
if (isnan(h) || isnan(t) || isnan(f)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.println(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
Serial.print(f);
Serial.println(" *F\t");
Serial.print("Heat index: ");
Serial.print(hic);
Serial.println(" *C");
}
Ecco il video:
Arduino con GPS e Wifi - antifurto o stazione meteo mobile from Piersoft Paolicelli on Vimeo.