Buffer e serial print

Buongiorno a tutti
chiedo il vostro aiuto, non riesco ad inviare la ricezione di un sms alla seriale di arduino.
di seguito posto il codice

void cres()
{
 
  Serial.println("EFFETTUO LA CHIAMATA");
  
  gsm.SimpleWrite(F("ATD"));
  gsm.SimpleWrite("401212");    
  gsm.SimpleWriteln(F(";"));

  gsm.WaitResp(15000, 50);
  gsm.SetCommLineStatus(CLS_FREE);

  if (CLS_FREE != gsm.GetCommLineStatus()) return;
  gsm.SetCommLineStatus(CLS_ATCMD);
  
  
  Serial.println("PREMO 1");
  delay(15000);
  
  gsm.SimpleWrite(F("AT+VTD="));
  gsm.SimpleWriteln(1000);
  gsm.WaitResp(1000, 100, "OK");

  gsm.SimpleWrite(F("AT+VTS=\""));
  gsm.SimpleWrite(1);
  gsm.SimpleWriteln(F("\""));

  gsm.WaitResp(3000, 100, "OK");
  gsm.SetCommLineStatus(CLS_FREE);
 
  
  Serial.println("PREMO 1 ");
delay(5000);
  gsm.SimpleWrite(F("AT+VTD="));
  gsm.SimpleWriteln(1000);
  gsm.WaitResp(1000, 100, "OK");

  gsm.SimpleWrite(F("AT+VTS=\""));
  gsm.SimpleWrite(1);
  gsm.SimpleWriteln(F("\""));

  gsm.WaitResp(3000, 100, "OK");
  gsm.SetCommLineStatus(CLS_FREE);
  delay(3000);
  
    pos = sms.IsSMSPresent(SMS_UNREAD);

  if (pos) 
  {
    sms.GetSMS(pos, n, buffer1, 50);
    Serial.println("DEBUG SMS phone number: ");
    Serial.println(n);
    Serial.println("SMS text: ");
  String Credito;

char credito;
for(int i=0; i<=30; i++)
{
  credito = buffer1[i];
 Serial.println(Credito);
}
Serial.println("ho letto il buffer");


sms.DeleteSMS(pos);


  
}
}

La seriale esegue tutto correttamente fino al punto in cui deve stampare la lettura del buffer dove sbaglio?

Grazie

Perdona, ma non mi è chiaro cosa pensavi di fare qui ...

String Credito;

char credito;
for(int i=0; i<=30; i++)
{
  credito = buffer1[i];
 Serial.println(Credito);
}

Dichiari un una variabile di tipo String di nome Credito ... dichiari poi una variabile di tipo char di nome credito ... per 30 volte assegni a quel singolo char un valore (... e quindi gli riscrivi sopra) ... e poi stampi Credito ... e ...
... cosa ti aspetti ??? :astonished: :astonished: :astonished:

Guglielmo

Ciao Guglielmo
pensavo che leggendo carattere per carattere riuscivo a far scrivere sulla seriale il testo del messaggio creando una stringa.
Ma dalla tua risposta così non è; potresti aiutarmi a capire come posso fare?

Ma non stai creando una stringa ... stai praticamente scrivendo 30 volte nello stesso byte di nome "credito" (nota la c minuscola) e poi mandi in stampa una variabile di tipo String di nome "Credito" (nota la C maiuscola) e ... il C è sensibile alle maiuscole e minuscole, quindi "credito" e "Credito" sono due cose diverse !

Senza scomodare le String, che io sconsiglio sempre di usare su una MCU piccolina come Arduino, con solo 2 KB di SRAM (le String sono oggetti che vengono allocati dinamicamente e, ogni volta che ne cambi la lunghezza, vengono distrutte e riallocate ... con rapida frammentazione della memoria e spesso ... errori del programma che sovrascrive variabili e quant'altro :~), puoi benissimo fare come hai fatto, solo :

  1. Non ti server la : String Credito;

  2. dichiara credito non un char, ma un array di char della lunghezza del numero massimo di caratteri più uno (il terminatore di stringa 0x00) : char credito[31];

  3. Dopo aver riempito credito come fai (... solo aggiungendo l'indice anche a lui, essendo ora un array), nell'ultima posizione metti 0x00 (che indica la fine della stringa)

  4. stampa credito : Serial.println(credito);

Prova e fammi sapere :wink:

Guglielmo

Grazie mille
Proverò e ti farò sapere
speriamo bene...... :smiley: :smiley: :smiley: :smiley: :smiley:

Ciao Guglielmo
sto trovando delle difficoltà nell'inserire il terminatore perchè non riesco a capire dove va posizionato

Ciao Guglielmo
orma mi da anche questo errore se dichiaro char credito [31];

sms_switchrev2_2.ino: In function 'void cres()':
sms_switchrev2_2:253: error: incompatible types in assignment of 'char' to 'char [31]'

#include "SIM900.h"
#include <SoftwareSerial.h>
SoftwareSerial gsmserial(5, 6);
#include <call.h>
#include "sms.h"
SMSGSM sms;
#include <dht11.h> //libreria temperatura
dht11 DHT11; //libreria temperatura
#define DHT11PIN 10 //libreria temperatura
#include <string.h>
#include <LiquidCrystal.h>
int i;
boolean started=false;
char inchar;
int addr;
String smstesto;
char n[20];
char credito[31];
char myRAM[70];
int clima = 13;
boolean messagComplete = false;
boolean sirena = false;
char buffer[50];
char buffer1[50];
char pos;
char *cmp;
LiquidCrystal lcd(11, 9, 8, 7, 4, 3);
const char* MESSAGE = buffer1;
const int MESSAGE_LENGTH = 55;
const int DISPLAY_WIDTH = 16;
//String Credito;
// int begin(9600); // verificare se il modulo si spegne
void setup()
{

  pinMode(clima,OUTPUT);

  Serial.begin(9600);

// char forceON(); // previsto per simcom 908 da provare FORZATURA ACCENSIONE
  if (gsm.begin(9600))
  {
    started=true;
  }  

  if(started){
    
    Serial.println("READY");	
    sms.DeleteSMS(pos);
    clearbuffer();	
  
    //Enable this two lines if you want to send an SMS.
    //sms.SendSMS("3452174198", "GSM CONTROL in attesa di comando");
    //gsm.SimpleWrite("AT+CMGD=1,4\r");
  }
  gsmserial.begin(9600);
};

void loop()
{
  if(started)
  {
    ricevo();

  }
};

void ricevo()
{
  //Read if there are messages on SIM card and print them.
  gsm.listen(); // IMPORTANT!!!!
  delay(200);

  pos = sms.IsSMSPresent(SMS_UNREAD);
  
  if (pos) 
  {
    sms.GetSMS(pos, n, buffer, 50);
    Serial.println("DEBUG SMS phone number: ");
    Serial.println(n);
    Serial.println("SMS text: ");
    Serial.println(buffer);

    //istruzione per accendere il clima
    if (strcmp(buffer,"Accendi")==false)    
    {
      ClimaOn();
      SendTextMessage();
    }

    else if (strcmp(buffer,"Spegni")==false)    
    {
      ClimaOff();
      SendTextMessage();
    }

    else if (strcmp(buffer,"Temp")==false)    
    {
      Temp();
      
    }


    if (strcmp(buffer,"Credito")==false)    
    {
      cres();
      
    }
    
    
    sms.DeleteSMS(pos);
    clearbuffer();	


  }                       


  delay(1000);
};



void SendTextMessage()
{
  if(started){
    //Enable this two lines if you want to send an SMS.
    sms.SendSMS("3452174198", "Comando eseguito");
    gsm.SimpleWrite("AT+CMGD=1,4\r");		
    //svuoto buffer
    clearbuffer();
  }
}
void Temp()
{
  if(started)
  {

    char strmsg [50];
    char buffer[50];
    delay (2000);
    char str1[]="°C";
    char *str;

    DHT11.read (DHT11PIN);
    Serial.println((float)DHT11.temperature, 2);

    dtostrf(DHT11.temperature, 2, 2, buffer);

    str = strcpy (str1,buffer);

    sms.SendSMS("3452174198" , str); 
    gsm.SimpleWrite("AT+CMGD=1,4\r");		

    clearbuffer();
/*
int number = 20;
char numstr[2]; // la stringa contenente i numeri da inviare
sprintf(numstr, "%d", number); //ti converte i numeri in una stringa
result = name + numstr; //ti concatena due stringhe
*/



  }
};



void clearbuffer()
{
  for (int i=0;i<50;i++)
  {
    buffer[i]=0;
  }
};

void ClimaOn()
{
  digitalWrite(clima,HIGH);
};



void ClimaOff()
{	
  digitalWrite(clima,LOW);
};



// Scrivo la funzione controllo credito

void cres()
{
 
  Serial.println("EFFETTUO LA CHIAMATA");
  
  gsm.SimpleWrite(F("ATD"));
  gsm.SimpleWrite("401212");    
  gsm.SimpleWriteln(F(";"));

  gsm.WaitResp(15000, 50);
  gsm.SetCommLineStatus(CLS_FREE);

  if (CLS_FREE != gsm.GetCommLineStatus()) return;
  gsm.SetCommLineStatus(CLS_ATCMD);
  
  
  Serial.println("PREMO 1");
  delay(15000);
  
  gsm.SimpleWrite(F("AT+VTD="));
  gsm.SimpleWriteln(1000);
  gsm.WaitResp(1000, 100, "OK");

  gsm.SimpleWrite(F("AT+VTS=\""));
  gsm.SimpleWrite(1);
  gsm.SimpleWriteln(F("\""));

  gsm.WaitResp(3000, 100, "OK");
  gsm.SetCommLineStatus(CLS_FREE);
 
  
  Serial.println("PREMO 1 ");
delay(5000);
  gsm.SimpleWrite(F("AT+VTD="));
  gsm.SimpleWriteln(1000);
  gsm.WaitResp(1000, 100, "OK");

  gsm.SimpleWrite(F("AT+VTS=\""));
  gsm.SimpleWrite(1);
  gsm.SimpleWriteln(F("\""));

  gsm.WaitResp(3000, 100, "OK");
  gsm.SetCommLineStatus(CLS_FREE);
  delay(3000);
  
    pos = sms.IsSMSPresent(SMS_UNREAD);

  if (pos) 
  {
    sms.GetSMS(pos, n, buffer1, 50);
    Serial.println("DEBUG SMS phone number: ");
    Serial.println(n);
    Serial.println("SMS text: ");


char Credito [31];
for(int i=0; i<=31; i++) = 0x00 ;
{
  Credito = buffer1[i];
 Serial.println(Credito);
}
Serial.println("ho letto il buffer");


sms.DeleteSMS(pos);


  
}
}

costa stai cercando di assegnare ??? Posta il pezzo di codice completo ...
... mi sa che stai cercando di assegnare un char ad un array ... devi assegnare un char ad ogni elemento char dell'array !!!

Guglielmo

Edit : Io ho modificato il mio post e tu hai postato assieme a me XD XD XD

??????????????????

aiuto sto andando nel pallone......

Come supponevo ...
... cerchi di assegnare un char ad un array ... perdona, ma ... prima di buttarti in certe applicazioni ... dovresti studiarti le basi del C ... perché qui siamo proprio alle nozioni elementari ... :~

Comunque ... questa dovrebbe essere la logica se hai da stampare 30 caratteri ....

char Credito [31];
for(int i=0; i < 30; i++)
{
  Credito[i] = buffer1[i];
}
Credito[30] = 0x00;
Serial.println(Credito);

Guglielmo

Grazie mille
ma tra lavoro e figli il tempo per studiare è poco ma quel poco che ho letto dopo un po che non lo applichi lo dimentichi.

mi impegno di applicarmi di più e domani ti faccio sapere se funzione grazie ancora

marco134:
Grazie mille
ma tra lavoro e figli il tempo per studiare è poco ma quel poco che ho letto dopo un po che non lo applichi lo dimentichi.

Lo so, ma ... una buona base di teoria è comunque fondamentale e ti permette di superare molti di questi semplici problemi di ... "sintassi" :wink:

Guglielmo

Scusate se mi intrometto, ma colgo l'occasione per dire grazie a Guglielmo!
Ho trovato molto utili le dritte che ha dato.

Nonostante una discreta esperienza di programmazione, la maggior difficoltà che ho trovato
nel passaggio ad Arduino (o forse al 'C') è stata la definizione delle variabili per utilizzare
al meglio il sistema.

Non avresti qualche link (magari in italiano) da leggere?

Grazie

Renzo

Figurati Renzo, è un piacere :slight_smile:

Manuali in Italiano .. ce ne sono pochi ... :roll_eyes:

Prova a guardare sul sito di Michele Maffucchi ... le guide relative al C si trovano QUI ... ma fai anche un giro su tutto il sito, c'è un sacco di bella roba :slight_smile:

Poi ... c'è QUESTO ... in Italiano costa uno sproposito ... sul sito dell'editore si trova in versione pdf ad un prezzo più umano, anche se comunque non economico. Però ... è veramente un gran bel libro !!! :slight_smile:
Per dare un'idea ... allego l'indice ... così è possibile rendersi conto degli argomenti che tratta :wink:

Guglielmo

indice.pdf (52.3 KB)

Noto proprio adesso QUESTO thread ... sono sicuro che troverai vari link utili :wink:

Guglielmo

Buongiorno
ho seguito alla lettera i consigli di Guglielmo ma il programma ora non stampa in seriale il mio buffer si ferma al dubug del messaggio?

Consigli idee????

allego foto schermata

Grazie a tutti

Scusa, ma a me sembra che il buffer lo stampa eccome, tanto è vero che dopo la scritta "SMS text:" ti stampa il messaggio "PosteMobile: ..........". ]:smiley:

Quello che non stampa, casomai, è l'ultima frase che hai messo "ho stampato il buffer" ... :roll_eyes:

Il dubbio è ... da cosa ricavi che devi copiare 50 bytes ? Perché tu hai si allocato 50 caratteri per buffer (... o almeno spero tu lo abbia fatto), ma dove ti chiedi quale è la lunghezza REALE di ciò che hai ricevuto ?

Sicuro di non andare fuori di memoria ? Hai verificato l'occupazione ? ... QUI è chiaramente spiegato come farlo con una piccola funzione ...

Guglielmo

Edit : poi, prendi il tuo codice nel IDE e, dal menu Tools fai Auto Format ... perché come lo hai formattatto tu ... emmm ... lascia un tantino a desiderare ...

Inoltre, scusa, ma mi spieghi lo scopo di copiare "buffer" in "credito" ??? Pensavo ti servisse a qualche cosa, ma se devi solo stampare il valore ... perché non fai direttamente la stampa di buffer ???

Inoltre ... visto che la GetSMS scrive l'SMS nella stringa che gli passi (buffer) ...
... e dato che la GetSMS termina la stringa con uno 0x00, tu dovresti uscire dal FOR dopo aver copiato lo 0x00 terminatore di stringa e non ti serve aggiungerlo dopo !

Guglielmo

P.S. : Questo è il codice della GetSMS e come vedi, anche se il buffer è troppo corto, tronca il messaggio, ma comunque lo termina con 0x00 :

char SMSGSM::GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len) 
{
  char ret_val = -1;
  char *p_char; 
  char *p_char1;
  byte len;

  if (position == 0) return (-3);
  if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val);
  gsm.SetCommLineStatus(CLS_ATCMD);
  phone_number[0] = 0;  // end of string for now
  ret_val = GETSMS_NO_SMS; // still no SMS
  
  //send "AT+CMGR=X" - where X = position
  gsm.SimpleWrite(F("AT+CMGR="));
  gsm.SimpleWriteln((int)position);  

  // 5000 msec. for initial comm tmout
  // 100 msec. for inter character tmout
  switch (gsm.WaitResp(5000, 100, "+CMGR")) {
    case RX_TMOUT_ERR:
      // response was not received in specific time
      ret_val = -2;
      break;

    case RX_FINISHED_STR_NOT_RECV:
      // OK was received => there is NO SMS stored in this position
      if(gsm.IsStringReceived("OK")) {
        // there is only response <CR><LF>OK<CR><LF> 
        // => there is NO SMS
        ret_val = GETSMS_NO_SMS;
      }
      else if(gsm.IsStringReceived("ERROR")) {
        // error should not be here but for sure
        ret_val = GETSMS_NO_SMS;
      }
      break;

    case RX_FINISHED_STR_RECV:
      // find out what was received exactly

      //response for new SMS:
      //<CR><LF>+CMGR: "REC UNREAD","+XXXXXXXXXXXX",,"02/03/18,09:54:28+40"<CR><LF>
		  //There is SMS text<CR><LF>OK<CR><LF>
      if(gsm.IsStringReceived("\"REC UNREAD\"")) { 
        // get phone number of received SMS: parse phone number string 
        // +XXXXXXXXXXXX
        // -------------------------------------------------------
        ret_val = GETSMS_UNREAD_SMS;
      }
      //response for already read SMS = old SMS:
      //<CR><LF>+CMGR: "REC READ","+XXXXXXXXXXXX",,"02/03/18,09:54:28+40"<CR><LF>
		  //There is SMS text<CR><LF>
      else if(gsm.IsStringReceived("\"REC READ\"")) {
        // get phone number of received SMS
        // --------------------------------
        ret_val = GETSMS_READ_SMS;
      }
      else {
        // other type like stored for sending.. 
        ret_val = GETSMS_OTHER_SMS;
      }

      // extract phone number string
      // ---------------------------
      p_char = strchr((char *)(gsm.comm_buf),',');
      p_char1 = p_char+2; // we are on the first phone number character
      p_char = strchr((char *)(p_char1),'"');
      if (p_char != NULL) {
        *p_char = 0; // end of string
        strcpy(phone_number, (char *)(p_char1));
      }


      // get SMS text and copy this text to the SMS_text buffer
      // ------------------------------------------------------
      p_char = strchr(p_char+1, 0x0a);  // find <LF>
      if (p_char != NULL) {
        // next character after <LF> is the first SMS character
        p_char++; // now we are on the first SMS character 

        // find <CR> as the end of SMS string
        p_char1 = strchr((char *)(p_char), 0x0d);  
        if (p_char1 != NULL) {
          // finish the SMS text string 
          // because string must be finished for right behaviour 
          // of next strcpy() function
          *p_char1 = 0; 
        }
        // in case there is not finish sequence <CR><LF> because the SMS is
        // too long (more then 130 characters) sms text is finished by the 0x00
        // directly in the gsm.WaitResp() routine

        // find out length of the SMS (excluding 0x00 termination character)
        len = strlen(p_char);

        if (len < max_SMS_len) {
          // buffer SMS_text has enough place for copying all SMS text
          // so copy whole SMS text
          // from the beginning of the text(=p_char position) 
          // to the end of the string(= p_char1 position)
          strcpy(SMS_text, (char *)(p_char));
        }
        else {
          // buffer SMS_text doesn't have enough place for copying all SMS text
          // so cut SMS text to the (max_SMS_len-1)
          // (max_SMS_len-1) because we need 1 position for the 0x00 as finish 
          // string character
          memcpy(SMS_text, (char *)(p_char), (max_SMS_len-1));
          SMS_text[max_SMS_len] = 0; // finish string
        }
      }
      break;
  }

  gsm.SetCommLineStatus(CLS_FREE);
  return (ret_val);
}

Ciao Guglielmo
il programma si ferma al sms text non va a ristampare il buffer1 per capirci perchè io quel buffer lo devo poi mandare ad un lcd