invio dati a pagina php non costante

Ciao a tutti,

utilizzo Arduino Mega2560, lo shield GSM/GPRS/GPS SHIELDV2 comprato da futura elettronica ed il SIM908.

Ho implementato il seguente sketch che, ogni 22 secondi (tempo di ciclo), riceve vari dati dal GPS e invia le coordinate (latitudine e longitudine) tramite richiesta post ad una pagina php:

#include "SIM900.h"
#include <SoftwareSerial.h>
#include "inetGSM.h"
#include "stdlib.h"
#include "gps.h"

InetGSM inet;
GPSGSM gps;

char lon[15];
float lon_db;
char lat[15];
float lat_db;
char lat_conv[15];
char lon_conv[15];
char variab[70];
char alt[15];
char time[20];
char vel[15];

char stat;
char inSerial[20];
char inSerial2[20];
int i=0;
boolean started=false;

void setup() 
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println(F("GSM Shield testing."));
  //Start configuration of shield with baudrate.
  if (gsm.begin(4800)){
    Serial.println(F("\nstatus=GSM READY"));

  }
  else Serial.println(F("\nstatus=IDLE"));
  
  if(started){
    //GPS attach
    if (gps.attachGPS())
      Serial.println(F("status=GPS READY"));
    else Serial.println(F("status=ERROR"));
    delay(20000);	//Time for fixing
    stat=gps.getStat();
	if(stat==1)
		Serial.println(F("NOT FIXED"));
	else if(stat==0)
		Serial.println(F("GPS OFF"));
	else if(stat==2)
		Serial.println(F("2D FIXED"));
	else if(stat==3)
		Serial.println(F("3D FIXED"));
	delay(5000);
        if (inet.attachGPRS("internet.wind", "", ""))
      Serial.println(F("status=ATTACHED"));
    else Serial.println(F("status=ERROR"));
    delay(1000);
    
    //Read IP address.
    gsm.SimpleWriteln("AT+CIFSR");
    delay(5000);
    //Read until serial buffer is empty.
    gsm.WhileSimpleRead();
  }
};

void loop() 
{
  Serial.println(F("inizio loop"));
  serialhwread();
};

void serialhwread(){
  i=0;
   
    while (Serial1.available() > 0) {
      inSerial[i]=Serial1.read();
      Serial.print(inSerial[i]);
      i++;
      delay(10);
    }
      
    inSerial[i]='\0';

        stat=gps.getStat();
	if(stat==1)
		Serial.println(F("NOT FIXED"));
	else if(stat==0)
		Serial.println(F("GPS OFF"));
	else if(stat==2)
		Serial.println(F("2D FIXED"));
	else if(stat==3)
		Serial.println(F("3D FIXED"));
   // }
   if(stat==2 || stat==3)  {
    //Get data from GPS
    gps.getPar(lon,lat,alt,time,vel);

    lon_db=convert(lon);
    lat_db=convert(lat);
    Serial.print(F("LON: "));
    Serial.println(lon_db,4);
    Serial.print(F("LAT: "));
    Serial.println(lat_db,4);
    
    dtostrf(lat_db, 2, 4, lat_conv);
    dtostrf(lon_db, 2, 4, lon_conv);

    variab[0]='\0';
    strcat(variab,"lat=");
    strcat(variab,lat_conv);
    strcat(variab,"&long=");
    strcat(variab,lon_conv);
    Serial.print(F("variab:"));
    Serial.println(variab);
    Serial.println("richesta post");
    inet.httpPOST("www.miodominio.com", 80, "/betonaggio/tracking_route_arduino/insert_data.php", variab, "read message", 0);
    delay(15000);
  }
  inSerial[0]='\0';
}

int strpos(char *str, char *target) {
char *res=0;
res = strstr(str, target);
if (res == NULL) return false;
else return res - str;
}

float convert(char* str){
float mmmmmm;
float dd;
int pos;
pos=strpos(str,".");
char dd_str[pos-1];
dd_str[0]='\0';
char mmmmmm_str[7];
mmmmmm_str[0]='\0';
for (int i=0; i<pos-2; i++){
dd_str[i]=str[i];
}
dd_str[pos-2]='\0';
dd=atof(dd_str);
mmmmmm_str[0]=str[pos-2];
mmmmmm_str[1]=str[pos-1];
mmmmmm_str[2]=str[pos];
mmmmmm_str[3]=str[pos+1];
mmmmmm_str[4]=str[pos+2];
mmmmmm_str[5]=str[pos+3];
mmmmmm_str[6]='\0';
mmmmmm=atof(mmmmmm_str);
float result;
result=dd+mmmmmm/60;
return result;
}

Il programma gira correttamente come sopra descritto ma in alcuni loop la richiesta post non va a buon fine e sul serial monitor ottengo il seguente messaggio:

SEND FAIL

CLOSED

Solo nel loop successivo verranno inviate le coordinate alla pagina php.
In altre parole, quando si verifica ciò, devo attendere due loop o al max tre per visualizzare le coordinate nella pagina.
Questo malfunzionamento non mi permette di avere online i dati di mio interesse ad intervalli di tempo costanti.

Da cosa può dipendere questo malfunzionamento?

  • Dal server che non riesce a ricevere la richiesta (utilizzo "topweb" come host provider)
  • Dalla connessione GSM
  • Dal buffer seriale (lo svuoto ad ogni ciclo)

Ciao,

David

inet.httpPOST("www.miodominio.com", 80, "/betonaggio/tracking_route_arduino/insert_data.php", variab, "read message", 0);
    delay(15000);

tu invii un POST verso un server e poi gli dici di aspettare 15 secondi per una risposta ...
A parte che quei delay così lunghi in un programma sono una cosa inguardabile :), Il sever potrebbe andare in timeout, perchè aspetti 15 sec?

Se proprio devi aspettare fallo prima di aprire la comunucazione, non nel bel mezzo del dialogo tra server e client.

Ho fatto le seguenti prove:

  • variato il delay da 15000 a 10000 (non cambia nulla)
  • eliminato il delay in questione (in questo modo la situazione peggiora perchè alcune volte la getPar non riesce ad acquisire le coordinate. Infatti il valore delle coordinate è pari a 0)
  • spostato il delay prima della richiesta post. In particolare, mettendo un delay(10000) prima della richiesta post, quando quest'ultima non va a buon fine, a monitor viene stampato

ATT: SEND OK
RIC:
CLOSED

mentre prima stampava anche

SEND FAIL.

Quando invece la richiesta va a buon fine, a monitor stampa:

ATT: SEND OK
RIC:
SEND OK

DB:SENT
Starting read..
Waiting for Data..
Done..

Avendo il dubbio che potesse dipendere dalla ricezione dei dati GPS, ho eliminato la relativa parte e ho aggiunto allo sketch l'acquisizione del valore di un potenziometro. Ho eliminato del tutto il delay nel loop.
Il problema persiste, ovvero nel mio database visualizzo sempre intervalli di tempo non costanti tra i valori ricevuti; in particolare, il periodo varia da 17 a 34 secondi.
A questo punto credo sia un problema di server. Se così fosse, potrebbe dipendere dal fatto che il server è di tipo condiviso e quindi con un server dedicato risolverei il problema? Oppure avete qualche altro indizio?

Ciao,

David

Ciao ragazzi,

per quanto riguarda la connessione GPRS ho navigato qua e la deducendo che non è molto affidabile. A questo punto, invece di inviare singolarmente i dati ed averli disponibili on line in tempo reale, ho pensato di definire un tempo di acquisizione finito, durante il quale memorizzare i dati in un file di testo presente in una sd card, e di inviarlo alla fine del tempo d'acquisizione: proverei l'invio più volte fino all'avvenuta ricezione da parte del server.
In questo modo sono indipendente dai problemi del GPRS.

Domande:

  • cosa ne pensate di questa soluzione?
  • ho cercato in vari post come poter inviare un file txt on line tramite scheda SIM, ma tutti restano senza risposta e irrisolti, avete qualche idea su come fare?

Ciao
David

Nessuno ha qualche idea?

perchè dici che il GPRS non è molto affidabile? e affidabile quanto il servizio telefonico del gestore, in ogni caso l'assenzadi internet o di linea è un problema reale, e un buffer su disco è la soluzione ideale.

Per affidabilità intendo proprio quello che hai detto tu, lesto, ovvero che arduino può trovarsi in luoghi in cui il segnale GPRS è out. Sto già lavorando per realizzare il tutto usando la sd card, in particolare ho dedotto che il vero problema consiste nel far capire ad arduino che il server remoto ha ricevuto correttamente i dati.
Mi spiego meglio ricapitolando le fasi di lavoro:

  • memorizzo i dati acquisiti in un file di testo presente nella sd card;
  • invio, uno alla volta, un record al server remoto tramite la funzione inetHTTP post;
  • arduino rileva in qualche modo che il server ha ricevuto correttamente il dato e quindi può continuare l'invio dei successivi records; se un record non viene ricevuto dal server, arduino deve riprovare l'invio.
    Esiste qualche funzione che mi permette di effettuare il controllo della corretta ricezione dati da parte del server remoto?

Grazie
David

quello che vuoi fare si chima hash, il CRC è un esempio usato spesso, ma se riesci appoggiati a qualcosa di più "sicuro" come l'md5; in partica ogni messaggio è seguito dal suo MD5 (che ha una lunghezza in byte fissa), e se il check non passa i dati sono danneggiati.

Io lo applicherei anche sui dati su SD, così giusto per andarci coi piedi di piombo.

l'md5 su arduino credo possa risultare pesante, in tal caso usa il calssico CRC, hai più probabilità di collisione ma nulla di grave

lesto:
l'md5 su arduino credo possa risultare pesante, in tal caso usa il calssico CRC, hai più probabilità di collisione ma nulla di grave

Sì, l'MD5 è pesantuccio su una MCU che sta facendo girare già un software complesso come la gestione dei dati GPS e l'invio su GPRS. Forse un CRC32 basta.
Spippolando in rete ho trovato questo, SipHash:
http://www.forward.com.au/pfod/SipHashLibrary/index.html
Promette una sicurezza pari a quella dell'MD5 ma al costo di un limitato consumo di risorse, 1200 byte di Flash e 42 byte di RAM:
http://www.forward.com.au/pfod/SipHashLibrary/index.html

Ciao a tutti, mi intrometto nella discussione perché di mio interesse :wink:
@lesto e @leo72 perché David dovrebbe usare i codici di ridondanza ciclica o l'hash se utilizza la funzione inetHTTP? Mi spiego meglio: i dati da inviare vengono gestiti dal protocollo HTTP che si appoggia al protocollo di trasporto TCP, il quale prevede tra l'altro un campo di 16 bit (se non ricordo male) per il checksum del pacchetto. Non sarebbe ridondante calcolare hash, CRC, ecc?
Penso che comunque il dubbio di David non fosse questo quanto quello di capire se può implementare un meccanismo di "acknowledgment manuale" con il server per frammentare i dati che deve inviare a causa del peso eccessivo dei file in cui questi sono contenuti.

Saluti,
Salvo

Se è per questo quasi tutti i livelli dello stack ISO/OSI hanno un checksum. ma il problema ti è passatto sottoil naso senza vederlo: sono PICCOLI, 16 bit o giù di llì, il che lascia tantissime possibilità di collision.

nella vita reale sono stimati da 1 su 16.000.000 a 1 su 10.000.000.000 pacchetti errati (circa 1byte ogni 4 tera).
Davero non ti è mai capitato di scaricare un file, magari zip, trovarlo danneggiato, riscaricarlo e trovarlo ok? bhe a me sì (e sempre dalla stessa fonte!)

ora, se noi immaginiamo che questi dati sono una immagine, o un film in streaming, ovviamnte l'errore è quancosa di cui possiamo fregarcene. Ma se parliamo di un sistema che salva dati su DB... potrebbe persino voler dire corrompere il DB, se non ci sono sufficianti validazioni dell'input.

questa attenzione per i particolari, in ambito professionale, è ciò che distingue un lavoro fatto BENE da uno che "funziona"