Sim900 GSM Gestore Telefonico

Salve,
stavo provando la ricezione degli sms, sul modulo Sim900, con i vari Operatori, e ho riscontrato che con WIND l'sms sul modulo viene ricevuto correttamente, mentre con TIM vengono ricevuti solo i primi 4 carattari con 1 sim e un solo carattere con un altra sim (sempre TIM).

Questo è il mio codice:

gsmSerial.listen();
if (gsmSerial.available() >0)
 {
   Serial.println(gsmSerial.available());
   while(gsmSerial.available())
   {
     incoming_char=gsmSerial.read(); //Get the character from the cellular serial port.
     Serial.print(incoming_char); //Print the incoming character to the terminal.
   
   }
 }

Oltre a questo codice è presente anche un listen sulla lettura delle coordinate del GPS, quello che faccio è nel loop mettermi in listen prima su una seriale e poi sull'altra.

Sono giorni che sto provando e riprovando ma non trovo nessuna spiegazione, da cosa può dipendere?

Grazie 1000

Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

nid69ita:
Ti invitiamo a presentarti (dicci quali conoscenze hai di elettronica e di programmazione) qui: Presentazioni
e a leggere il regolamento: Regolamento

Il codice devi racchiuderlo nei tag code, vedi sezione 7 del regolamento, spiega bene come fare.
Altrimenti parte del codice può essere visualizzata male o mancare perchè interpretato come attributo del testo stesso.

Fatto
Grazie dei link

... solo per fare una test, prova a modificare il codice così :

while(gsmSerial.available())
  {
    incoming_char=gsmSerial.read(); //Get the character from the cellular serial port.
    Serial.print(incoming_char); //Print the incoming character to the terminal.
    delay(2); // Insert a small delay before reading next char
  }

... e vedi se la situazione migliora ::slight_smile:

Guglielmo

gpb01:
... solo per fare una test, prova a modificare il codice così :

while(gsmSerial.available())

{
    incoming_char=gsmSerial.read(); //Get the character from the cellular serial port.
    Serial.print(incoming_char); //Print the incoming character to the terminal.
    delay(2); // Insert a small delay before reading next char
  }




... e vedi se la situazione migliora ::)

Guglielmo

avevo già provato con un delay, ma uguale a 100, e non cambiava niente, potrei provare con 2, ti faccio sapere, ma la cosa strana, perchè con Wind funziona e Tim no?

Se non funziona con 100 millisec. non funziona neache con 2 millisec. non perderci tempo ...
... te lo avevo suggerito perché (... e a me è già successo più volte) spesso i caratteri arrivano più lentamente di quanto non sia veloce quel ciclo while per cui ... ti trovi con un gsmSerial.available() == 0 anche se in realtà devono ancora arrivare altri caratteri :wink:

Guglielmo

P.S.: Altra cosa ... proprio nella ricezione di SMS, con un SIM808, usando la SoftwareSerial, ho dovuto ampliare il buffer di ricezione perché i 64 char di base NON erano sufficienti e ricevevo SMS troncati ... vale la pena di tentare e portare il buffer a 128 char :wink:

e c'è modo di risolvere il problema?

Io avevo provato anche con questo codice:

while (Serial.available() > 0)
    {
        char recieved = Serial.read();
        inData += recieved; 

        // Process message when new line character is recieved
        if (recieved == '\n')
        {
            Serial.print("Arduino Received: ");
            Serial.print(inData);

            // You can put some if and else here to process the message juste like that:

            if(inData == "+++\n"){ // DON'T forget to add "\n" at the end of the string.
              Serial.println("OK. Press h for help.");
            }   


            inData = ""; // Clear recieved buffer
        }
    }

ma ricevo sempre il primo carattere

... come ti ho scritto, io ho risolto sia inserendo un piccolo delay() nel ciclo di lettura, sia ampliando il buffer di ricezione seriale :wink:

Guglielmo

ok ci provo, al momento il tutto è settato come 9600 provo con 115200?
Attuale:

  GPS.begin(9600);
  gsmSerial.begin(9600);
  Serial.begin(9600);

Secondo te va bene se metto:

  GPS.begin(115200);
  gsmSerial.begin(115200);
  Serial.begin(115200);

oppure alzo solo solo quello del gsm serial? Ma poi come leggo i dati?

Fino a quest sera non posso provarlo, ma intanto cerco di capire come risolvere il problema :wink:

Qual'è di preciso la libreria che stai usando?

Sei sicuro che questa espressione:

while(gsmSerial.available())

non debba essere:

while(gsmSerial.available()>0)

No, perché vuoi alzare il baud rate ? Lascia a 9600 ... e evita l'insorgere di altri problemi :wink:

@em1lio189 : ... se dici a me, per queste cose NON uso alcuna libreria, preferisco avere tutto sotto controllo direttamente :wink:
... e riguardo al tuo dubbio ... in una while() qualsiasi cosa == 0 è false, != 0 è true quindi ... while(gsmSerial.available()) {...} va benissimo ! :slight_smile:

Guglielmo

P.S: @Nid ... hai postato mentre io scrivevo le stesse cose :smiley:

@emilio, le due espressioni while sono equivalenti.
La prima è solo un pò più ostica da leggere, implicitamente per il C con 0 è falso, diverso da 0 è vero.

Ok ragazzi, scusate allora! L'if nella prima parte del codice mi aveva fatto sorgere qualche dubbio.

@em1lio189 La libreria che sto usando è TinyGPS.h.

@Gugliemo: per aumentare il buffer di ricezione devo crearmi un array di char? Una cosa del tipo:

char incomingSms[128] = {'\0'};

for (int i = 0; i < 128; i++)
{
  incomingSms[i] = gsmSerial.read();
}

Ora che mi viene in mente, mettendo un print su gsmSerial.available() questo mi ritorna 1, che è il primo carattare che vedo a video, invece che la lunghezza esatta.

Non so se ci sono altri problemi comunque posto il codice completo.

#include <SoftwareSerial.h>
#include <TinyGPS.h>
#include <String.h>
#include<stdlib.h>

unsigned long fix_age;

SoftwareSerial GPS(12,11); 
TinyGPS gps;
void gpsdump(TinyGPS &gps);
bool feedgps();
void getGPS();
long lat, lon;
float LAT, LON;

//Receiver Init
int inputA = 4;
int inputB = 3;
int inputC = 5;
int inputD = 2;
//Led Init
int LED_PIN = 6;
boolean ledState = false;

//Mills
long previousMillis = 0;
long interval = 5000;           // interval at which to blink (milliseconds)

//GSM Init
SoftwareSerial gsmSerial(7, 8);
String textSms = "";
char incoming_char=0;
boolean sendSMS = false;
unsigned long start = 0;

unsigned long startCheckCoordinate = 0;

void setup() {
  GPS.begin(9600);
  gsmSerial.begin(9600);
  Serial.begin(9600);
  
  
  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  
  
  pinMode(inputA, INPUT);
  pinMode(inputB, INPUT);
  pinMode(inputC, INPUT);
  pinMode(inputD, INPUT);
  
  LAT_PREVIOUS = "";
  LON_PREVIOUS = "";
  
  startCheckCoordinate = millis();
  

}

void loop() {
  
  unsigned long currentMillis = millis();
  
  if (digitalRead(inputA) == HIGH && !ledState)
  {
    long diff = currentMillis - previousMillis;
    if(diff > interval || previousMillis == 0)
    {
       previousMillis = currentMillis;
      Serial.println("A");
      ledState = true; 
      buzerState = true;
    }   
  }else if (digitalRead(inputA) == HIGH && ledState)
  {
    long diff = currentMillis - previousMillis;
    if(diff > interval || previousMillis == 0)
    {
       previousMillis = currentMillis;
      Serial.println("A");
      ledState = false;  
      buzerState = true;
    }  
  }
  
  
  if (ledState)
  {
    ledBlink();
    
    CheckCoordinateSendTextMessage();
  }else
  {
    digitalWrite(LED_PIN, LOW);
  }
  
  
  
  //receive SMS
  gsmSerial.listen();
  if (gsmSerial.available() >0)
  {
    Serial.println(gsmSerial.available());
    while(gsmSerial.available())
    {
      incoming_char=gsmSerial.read(); //Get the character from the cellular serial port.
      Serial.print(incoming_char); //Print the incoming character to the terminal.
    
      textSms = textSms + String(incoming_char);
    }
  }
  
  if ( textSms != "")
  {
    Serial.println("-----------------------");
      Serial.println("<"+textSms+">");
      
 
      textSms = "";
  }
  
  
}

void getGPS(){
  bool newdata = false;
  unsigned long start = millis();
  // Every 1 seconds we print an update
  while (millis() - start < 1000)
  {
    if (feedgps ()){
      newdata = true;
    }
  }
  
  if (newdata)
  {
    gpsdump(gps);
  }
}

bool feedgps(){
  
  while (GPS.available())
  {
    if (gps.encode(GPS.read()))
    {
      return true;
    }
  }
  return 0;
}

void gpsdump(TinyGPS &gps)
{
  //byte month, day, hour, minute, second, hundredths;
  gps.get_position(&lat, &lon);
  LAT = lat;
  LON = lon;
  {
    feedgps(); // If we don't feed the gps during this long routine, we may drop characters and get checksum errors
  }
}

void ledBlink()
{
  unsigned long start = millis();
    // Every 1 seconds we print an update
    while (millis() - start < 800)
    {
      digitalWrite(LED_PIN, HIGH);
    }
    
    start = millis();
    while (millis() - start < 400)
    {
     digitalWrite(LED_PIN, LOW);
    }
}





void CheckCoordinateSendTextMessage()
{
 
  while(millis() - startCheckCoordinate > 10000)
  {
    
    int counter=0;
    GPS.listen();
    
    for (;;)
    {
     long lat, lon;
     unsigned long fix_age, time, date, speed, course;
     unsigned long chars;
     unsigned short sentences, failed_checksum;
     long Latitude, Longitude;
      
     // retrieves /- lat/long in 100000ths of a degree
     gps.get_position(&lat, &lon, &fix_age);
     getGPS();
     Serial.print("Latitude : ");
     Serial.print(LAT/1000000,7);
     Serial.print(" :: Longitude : ");
     Serial.println(LON/1000000,7);
    counter++;
    Serial.print(counter);
    if (counter<2)
    {
      continue;    
    }
    
    
    if (LAT == 0 && LON == 0)
    {
      break;    
    }
    
         gsmSerial.listen();
        gsmSerial.print("AT+CMGF=1\r");    //Because we want to send the SMS in text mode
         delay(1500);
         gsmSerial.println("AT+CMGS = \"NUMBER\"");//send sms message, be careful need to add a country code before the cellphone number
         delay(1000);
         gsmSerial.println("A test message1!");//the content of the message
         
         delay(1000);
         gsmSerial.println((char)26);//the ASCII code of the ctrl+z is 26
         delay(1000);
         gsmSerial.println();
         delay(1000);
    }
     counter=0;
      break;
    }
    startCheckCoordinate = millis();
  }
}

String SendUSSD()
{
  
   String bodySms = "";
   textSms = "";
   
   int count = 0;    
   
  int countCicle = 0;
  while(true)
  {
    
     Serial.print("--- ");
     Serial.println(count++);
     
     gsmSerial.println("ATD*123#");//dial the number
     
     
     delay(15);
      char c; 
                        
    for (int i = 0; i < 100; i++) {
  
      while (gsmSerial.available() > 0){  // If there is data, read it and reset
         c = (char)gsmSerial.read();      // the counter, otherwise go try again
         textSms = textSms + String(c);
      }
      delay(100);
    }
      
      Serial.println("---<"+textSms+">---");
      
      int val1 = textSms.indexOf("+CUSD: 0,\""); //line separator
    bodySms = textSms.substring(val1 + 10, textSms.length() - 1);
    
    Serial.println("****<"+bodySms+">****");
    
    if (textSms.indexOf("Euro") == -1)
    {
      countCicle = countCicle + 1;
      
      if (countCicle == 3)
      {
        break;
      }
    }else
    {
      break;
    }
    
    delay(1000);
    

  }
  Serial.println("++++<"+bodySms+">+++");
  
  return bodySms;
  
  
  
}

NO, non una cosa lato applicativo, devi proprio modificare il file SoftwareSerial.h che è nella libreria SoftwareSerial che è dentro l'IDE di Arduino ... subito all'inizio trovi :

#define _SS_MAX_RX_BUFF 64 // RX buffer size

lo modifichi in :

#define _SS_MAX_RX_BUFF 128 // RX buffer size modified to 128 char

Guglielmo

gpb01:
NO, non una cosa lato applicativo, devi proprio modificare il file SoftwareSerial.h che è nella libreria SoftwareSerial che è dentro l'IDE di Arduino ... subito all'inizio trovi :

#define _SS_MAX_RX_BUFF 64 // RX buffer size

lo modifichi in :

#define _SS_MAX_RX_BUFF 128 // RX buffer size modified to 128 char

Guglielmo

Ok stasera appena arrivo a casa lo provo e ti faccio sapere

… considera che, per evitarmi di scordare di fare questa modifica ad ogni uscita di una nuova versione dell’IDE, in testa ai programmi dove mi occorre, ho messo :

#if (_SS_MAX_RX_BUFF < 128)
  #error SoftwareSerial buffer too small, increase.
#endif

… così, se me ne scordo, va in errore la compilazione :smiley: :smiley: :smiley:

Guglielmo

gpb01:
… considera che, per evitarmi di scordare di fare questa modifica ad ogni uscita di una nuova versione dell’IDE, in testa ai programmi dove mi occorre, ho messo :

#if (_SS_MAX_RX_BUFF < 128)

#error SoftwareSerial buffer too small, increase.
#endif




... così, se me ne scordo, va in errore la compilazione :D :D :D

Guglielmo

Stringa cambiata, stasera lo testo

@shuttle, per favore, non quotare tutto il msg precedente.

@Gugliemo…grazie 1000 con i suggerimenti che mi hai dato funziona…

Visto che ci sono posso chiedere un altra cosa?

Quando provo ad inviare una strina ussd:

gsmSerial.listen();
   gsmSerial.println("AT+CMGF=0");
     delay(2000);
     gsmSerial.println("AT+CUSD=1,\"*123#\"");
     
   delay(10000);
   
   
   
    char c;
    if (gsmSerial.available() > 0)
     {
       
       char textSmsArray[gsmSerial.available()];
       
         int i = 0;
       while (gsmSerial.available() > 0){  // If there is data, read it and reset
         c = gsmSerial.read();      // the counter, otherwise go try again
         
         textSmsArray[i] = c;
         i++;
         
         delay(50);
     
      }
      
      Serial.println("+++++++++++++");
      textSms = "";
      for (int i = 0; i < sizeof(textSmsArray); i++)
      {
        Serial.println(textSmsArray[i]);
        textSms += String(textSmsArray[i]);
      }
     }
     
     Serial.println("+++++++++++++");
      
      Serial.println("+++<"+textSms+">+++");

quello che ottengo è solo una parte del messaggio (i primi 74caratteri) . Se provo a ridurre il dalay da 10000 da 2000 textsms è vuoto e subito dopo ricevo il testo completo, se provo ad aumentarlo (qualsiasi valore >10000) recevo sempre i primi 74 caratteru

Come posso risolvere?