HELP - Arduino + GPRS Shield SAGEM Hilo

Ho acquistato una Shield GPRS collegata ad Arduino sia in modalità StandAlone che in modalità Gateway e funziona tutto alla perfezione , SMS , Chiamata ecc...

Vorrei però poter leggere il numero dell'ultima chiamata persa cosa che riesco a fare perfettamente in modalità gateway con il seguente comando:


Comando inviato:
AT+CPBR=1;

Risposta:
+CPBR: 1,"+39335xxxxxxx",145,"Cesco"

OK


Quello che voglio fare è confrontare la stringa di risposta per confrontare se il numero che ha chiamato è abilitato. Per fare questo ho messo Arduino+Shield in modalità standalone e i dati li leggo tramite un'altra Arduino (senza ATMega) collegata con 2 pin all'altra come indicato qui:

http://www.libelium.com/squidbee/index.php?title=New_GPRS_module_for_Arduino_(Hilo_-_Sagem)#Connecting_Arduino_to_Internet

Poi sul Mac tramite "CoolTerm" leggo i dati in risposta.

Il software caricato nella Arduino+Shield fa questa operazione nel loop :


Serial.println("AT+CPBR=1;"); // invio comando per leggere l'ultimo numero perso

if(Serial.available()) {
while(Serial.available() > 0 && Serial.read() != 13 ){
test+=(char)Serial.read(); // test è una variabile String - String test="";
}
}


La seriale è settata a 19200

Purtroppo la variabile "test" non contiene la risposta corretta ma una serie di caratteri presi un po' a caso dalla risposta.

Grazie in anticipo.

Utilizza un controllo di questo tipo:

time=millis();
while(millis()<time+timeout){
      if(Serial.available()>0){
        data_recieve.concat((byte)Serial.read());  
        if(data_recieve.endsWith('\n')){
          break;
        }
    }

timeout lo imposti te.

Grazie per la risposta...

Ho provato ma niente ancora...

Ho trovato questa funzione

#define LINEBUF_SIZE 129
char databuffer[LINEBUF_SIZE];
byte last_read_timed_out=0;
 
unsigned int read_line(unsigned long timeout_ms=2000) {
    //Reads a line of text from the 'duino Serial library's buffer (128 bytes unless changed). 
    //Reads until 
    // - a newline   (which then makes it to the buffer - can make some string tests easier)
    // - the buffer is full (hardcoded length)
    // - reading a next character times out
    // ...whichever comes first.
    // 
    // Writes the a null-terminated string into databuffer, 
    //  (so reads at most (LINEBUF_SIZE-1) useful characters)
    // Returns the amount of bytes we read (==strlen(databuffer))
    //
    // On timeout:
    // - Waits no longer than 'timeout_ms' milliseconds for each next character.
    // - On timeout, sets last_read_timed_out=1
    // - Note that currently function only returns 0 when it timed out reading 
    //   anything at all, so that can also be a simple test for timeout
    // - Timeout values of <30ms can be too short
    // 
    // On newlines:
    // - was written with the idea that you may get only CR or LF
    //    (not sure if that's ever true) 
    // - will not emit empty lines
    // - which combines to mean that it will leave \n in the Serial buffer
    //   and only ignores it on the next call of read_line(). This is significant
    //   when you're doing data exchange, because that byte will mess things up.
    char *tptr=databuffer;
    unsigned long last_byte_time;
 
    last_read_timed_out=0;   
    databuffer[0]=0x00;      // (make sure empty string on timeout is null terminated)
    last_byte_time=millis(); // used in a 'last byte was read this long ago' test
 
    while (true) { //(not and endless loop, broken off by timeout if not by end-of-line)
      //If the buffer is full, break off.
      if ((tptr-databuffer) > (LINEBUF_SIZE-2)) { //verify for off-by-one error. 
        // -2 so that the last position can safely be set to the null terminator.
        tptr[1]=0x00;
        break;
      }
 
      // Read a byte, if it's there
      if (Serial.available()>0) { // If there's a byte to be read,
        tptr[0]=Serial.read();    // read it in
        tptr[1]=0x00; //(could be postponed until we know we're done, actually)
        tptr++;
        last_byte_time=millis();  // update 'last byte read came at' time
 
        // Terminate reading on a newline, deal with empty lines by ignoring them
        if (   ((tptr[-1]=='\n') || (tptr[-1]=='\r'))  &&  ( ((int)(tptr-databuffer)) == 1 )   )
        { //empty line or crlf? Pretend this line didn't exist, start over with next character.
          tptr=databuffer;
          databuffer[0]=0x00;
          continue;
        }
        if (tptr[-1]=='\r') { // CR, \r, but not at start of line - assume this is a complete response, return it
          break;
        } //note that this leaves the \n from a CRLF in the Serial buffer. This function deals with it, your manual Serial code may not.
 
        continue; //we read a byte, skip timeout check this round
      } else { //no byte available yet
         //delay(1); //probably unnecessary. 
      }
 
      // Time out? 
      if (millis()-last_byte_time > timeout_ms) { //TODO: check behaviour at millis overflow
        tptr[1]='\0';
        last_read_timed_out=1; //signal that we timed out
        break;
      }
    }
 
    // I use software-serial for debug to print out the time of receive,
    // the just-read line's length, string representation, and hex representation
    // (omitted here for relative brevity)
 
    return (int)(tptr-databuffer); // amount of bytes we read into databuffer (TODO: check)
}

int get_signal_strength() {  
    //returns dBm. Returns 0 on error/unknown.
    module_write("AT+CSQ\r");
    char ret=0;
    for (int i=0;i<2;i++) { //should be +CSQ and OK
      read_line(300); //Probably takes 200ms or less, but hey
      if (startswith(databuffer,"+CSQ")) {  //should look like "+CSQ: 15,99"
        ret = atol(&databuffer[5]);
        if (ret==99) 
          ret=0;
        else
          ret = -113+2*ret;
      }
    }
    return ret;
}


inline byte startswith(char *str, char *start, int n=-1) {
    //Returns whether str stats with start. 
    //Example use:    if (startswith(read_buffer, "+CSQ"))
    //The n parameter lets you check only the first n characters 
    // instead of all of the length of start 
    // (and, in theory, lets you hardcode to avoid a strlen). 
    // I haven't used this but I figured it could be useful. 
    if (n==-1)
      n=strlen(start);
    return ((strncmp(str,start,n))==0);
}

Mettendo un:

if (get_signal_strenght()>0)
{
// codice per fare una chiamata persa
}

Non succede niente. =(

Non capisco perché a volte facendo un semplice print di una stringa (esempio: Serial.print("test") ) vedo il comando sull'output, altre volte no. Volevo vedere se la variabile databuffer avevo qualcosa ... ma sembra niente...

Può essere che sbaglio qualcosa, nessuno ha mai provato qualcosa del genere ?

Nessuno mi può aiutare ? =(

Sapendo che il modulo usa i pin 0,1 per la seriale di conseguenza l'usb diventa inutilizzabile, c'è la possibiltà di leggere da PC i dati su una seriale software ? o in un'altro modo, non con una seconda arduino senza Atmega come sto facendo adesso ?

Ho anche una Arduino Mega in alternativa...

Help!!! :stuck_out_tongue:

ho lo stesso hardware e devo fare la stessa cosa, ma sono preso da altri lavori e mi sono fermato, quindi non posso aiutarti più di tanto. Però mi chiedevo: vuoi leggere i dati passati in standalone mode da PC per verificare a video la risposta del Sagem, giusto? Io per semplicità ho messo un led che mi indica, con alcuni lampeggi, l'output letto dal Sagem. Ovviamente per debug, ed ovviamente solo per situazioni "semplici" (ha letto "OK"? Blink 1 volta. Ha letto "altro"? blink 2 volte, ecc)

Ciao Neutrino

grazie per la risposta, uno dei miei problemi era quello di vedere l'output del sagem (messo in una variabile) a video per verificare se venivano letti i dati. Ho scoperto comunque che facendo un semplice Serial.println(varbuffer) non viene stampato niente neanche ERROR perché bisogna mettere all'inizio dell'output in AT+ ... così facendo attivando l'echo dell'input sul sagem ( ATE1 ) sono riuscito a vedere il contenuto della variabile. Poi ho attivato come hai fatto tu un semplice output sul pin13 (led della scheda) per avere un feedback del funzionamento.

Ora ci sono quasi. Ho utilizzato la funzione readline che ho postato qui sopra e poi ho usato questa funzione

  void get_imei(char *target) { // (device identity)
    //writes the IMEI to a given string (which should have space for 17 characters, counting the null terminator)
    Serial.println("AT+CGSN");
    delay(100);
    read_line(200); //this value is alone on its line
    int len = min(16, strcspn(databuffer,"\r\n"));
    memcpy(target,databuffer,len);
    target[len]='\0';
    read_line(200); //OK
}

e sul loop ho messo

get_imei(imei); // imei è dichiarata così : char *imei="";
   rec=imei;  // rec è una var di tipo String
  
 
 if(rec.indexOf("351xxxxxxxxxxxx")>=0)
{ 
      digitalWrite(13,HIGH);
      delay(5000);
       digitalWrite(13,LOW);
      
      
}

Devo dire che al primo passaggio funziona tutto correttamente :% ... ora però non riesco a capire per quale motivo la funzione get_imei() viene eseguita solo una volta. =( Qualcosa sulla dichiarazione delle variabili ?

Sono una frana con il C e spero che qualcuno possa illuminarmi ...

vi prego!! :slight_smile:

Comunque dopo mille tentativi almeno qualcosa sembra funzionare e questo mi riempie di goia :stuck_out_tongue: