problems converting String to Array of Characters.

Hi Guys! I'm working on an SMS-based LED Matrix Display board. I'm having problems parsing the String to an Array of Characters. any help please? thanks! :slight_smile:

/*

GSM BASED LED MATRIX DISPLAY USING ARDUINO
October 2012

*/

#include "CMAP.h"
#include <SIM900.h>
#include <sms.h>
#include <SoftwareSerial.h>

// ---------- for led display ----------

#define INTEN 6000         //Delay Speed of scroll
int ctr;                   //counter variable
int charsize;              //number of characters in sms
char count;		   //scan count 
char DisplayRam[101];      //32x3 leds + 5 display count
unsigned char shiftcounter;//shift counter for characters
unsigned char mask;        //display mask, led on/off
unsigned char charpointer; //character pointer map

// ---------- for sms ----------

char smsbuffer[160];	   //holds buffered data
char smsdata[250];         //sms only accept 160 char, remaining for header
char numberRx[20];         //holds sender number

char incomingChar;

boolean checkNum=false;  //if valid sender
boolean checkPass=false; //if valid password
boolean started=false;

//---------- registered numbers ----------
String regnum1="639339182267";

String passRx="default#";           //holds password, must be 8 char only! and ends with #
String msgBuff;
String parSMS;

// ---------- define pins - pic to led shield driver ----------
const char CLK = 5; 
const char DAT = 6; 
const char STR = 7; 
const char K0 = A0; 
const char K1 = A1; 
const char K2 = A2; 
const char K3 = A3; 
const char K4 = 8; 
const char K5 = 9; 
const char K6 = 10; 
const char K7 = 11; 

void setup ()
{
// ---------- initialize board ----------
  pinMode(CLK, OUTPUT);     
  pinMode(DAT, OUTPUT);     
  pinMode(STR, OUTPUT);     
  pinMode(K0, OUTPUT);     
  pinMode(K1, OUTPUT);     
  pinMode(K2, OUTPUT);     
  pinMode(K3, OUTPUT);     
  pinMode(K4, OUTPUT);     
  pinMode(K5, OUTPUT);     
  pinMode(K6, OUTPUT);     
  pinMode(K7, OUTPUT);

// ---------- turn all pins on ----------
  digitalWrite(K0,HIGH);  
  digitalWrite(K1,HIGH);  
  digitalWrite(K2,HIGH);  
  digitalWrite(K3,HIGH);  
  digitalWrite(K4,HIGH);  
  digitalWrite(K5,HIGH);  
  digitalWrite(K6,HIGH);  
  digitalWrite(K7,HIGH);  
 
// ---------- serial port ----------
  gsmsetup();  
 
// ---------- loop display 32x3 leds ----------
  for (ctr=0;ctr<32;ctr++)
  {clock();}
  strobe();
  ctr=0;
  
}


void loop ()
{
// ---------- check sms new ----------
  checkSMS();
  
// ---------- loop display ----------
   Display();
   shift();
 
}


void gsmsetup(void)
// ---------- serial setup ----------
{
  //Serial connection.
  Serial.begin(9600);
  Serial.println("GSM Shield testing.");
  //Start configuration of shield with baudrate.
  //For http uses is raccomanded to use 4800 or slower.
  if (gsm.begin(4800)){
    Serial.println("GSM SHIELD READY");
    started=true;  
  }
  else Serial.println("GSM SHIELD IDLE");
 
}

void checkSMS()
// ---------- check if there is new message ----------
{
   if(started){
    //Read if there are messages on SIM card and print them.
	
    if(gsm.readSMS(smsbuffer, 160, numberRx, 20))
    {
      Serial.print("\nFrom: ");
      Serial.print(numberRx);
      Serial.print("\nMessage: ");
      Serial.print(smsbuffer);
      Serial.println("\n");
    }
    delay(1000);
    checkSender();
  }
}

void checkSender()
{

  String numRx(numberRx);
  if(numRx.startsWith(regnum1))
  {
    checkNum=true;
    Serial.println("Authorized Sender.");
    checkPassword();
  }
  else
  {
    Serial.println("Unauthorized Sender."); 
  }
}

void checkPassword()
{
  // ---------- convert array to string -----------
  msgBuff.concat(smsbuffer[0]);
  for (int i=1;i<=10;i++)
  {
    msgBuff.concat(smsbuffer[i]);
  }
  Serial.print("\nMessage Buffer: "); Serial.println(msgBuff);
  Serial.print("\nMessage Length: "); Serial.println(msgBuff.length());

  
  // ---------- check for password in string ------------
  if(msgBuff.startsWith(passRx))
  {
    checkPass=true; 
    Serial.println("Password Correct.");
  }
  else
  {
    checkPass=false; 
    Serial.println("Password inCorrect.");
  }
  
  if(checkPass==true)
  {
    parseSMS();
  }
}

void parseSMS()
{
          parSMS.concat(smsbuffer[9]);
          int i=10;
          while(smsbuffer[i]!='\0')
          {
            parSMS.concat(smsbuffer[i]);
            i++;
          }

          Serial.print("\nParsed SMS: ");
          Serial.println(parSMS);
          
          msgBuff=""; // clear message Buffer
          // ---------- convert to array ---------      
          parSMS="";  // clear parsed sms buffer
          getSMS();
}

void getSMS()
{
 // --------- convert string to array --------
  int y;
  int stringLen = parSMS.length();
  
  for(y=0;y<=stringLen;y++)
  {     
     smsdata[y]+=parSMS[y];
     smsdata[y+1]='\0'; 
  }   
          Serial.print("\nArray SMS: ");
          Serial.println(smsdata); 
         
}


void shift(void)
{
// ---------- DisplayRam[0]~[99] = DisplayRam[1]~[100] ----------  
  int x;
  for(x=0;x<100;x++)
  {
   DisplayRam[x] = DisplayRam[x+1]; 
  }
  
// ---------- # value denotes spacing of letters ----------  
  shiftcounter++;
  if(shiftcounter == 8)
  {
    shiftcounter=0;
    //load();
  }
  
}

void Display(void)
{
  mask = 0x01;
  scan();
  digitalWrite(K7,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K7,HIGH);

  mask = 0x02;
  scan();
  digitalWrite(K6,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K6,HIGH);

  mask = 0x04;
  scan();
  digitalWrite(K5,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K5,HIGH);

  mask = 0x08;
  scan();
  digitalWrite(K4,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K4,HIGH);

  mask = 0x10;
  scan();
  digitalWrite(K3,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K3,HIGH);

  mask = 0x20;
  scan();
  digitalWrite(K2,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K2,HIGH);

  mask = 0x40;
  scan();
  digitalWrite(K1,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K1,HIGH);

  mask = 0x80;
  scan();
  digitalWrite(K0,LOW);
  for(ctr=0;ctr<INTEN;ctr++){}
  digitalWrite(K0,HIGH);
}

void load(void)
{

  char cctr;
  if(smsdata[charpointer+1] == '~')
  {
    charpointer = 0;
  }
  for (cctr =0; cctr<5;cctr++)
  {
    DisplayRam[94 + cctr] = character_data[(smsdata[charpointer] - 0x20)][cctr]; 
  }
  DisplayRam[101]=0;
  charpointer++;
  
}

void Clear_Display_Ram(void)
{
  unsigned char rcount;
  for(rcount = 0; rcount < 101; rcount++)
    DisplayRam[rcount] = 0xff;
}

void scan(void)
{
  for (count=94;count>(-1);count--){
    if ((DisplayRam[count] & mask) == mask)
      digitalWrite(DAT,LOW);
    else
      digitalWrite(DAT,HIGH);
    clock();
  }
  strobe();
}


void clock(void)
{
  digitalWrite(CLK,HIGH); // clock hi
  digitalWrite(CLK,LOW);  // clock low
}

void strobe(void)
{
  digitalWrite(STR,HIGH); // strobe hi
  digitalWrite(STR,LOW);  // strobe low
}

I'm having problems parsing the String to an Array of Characters.

Where? In what function? You have Strings all over the place. They are a disaster waiting to happen. When it happens, don't say you weren't warned.

PaulS:

I'm having problems parsing the String to an Array of Characters.

Where? In what function? You have Strings all over the place. They are a disaster waiting to happen. When it happens, don't say you weren't warned.

oh, sorry. It's in the getSMS() function. when the getSMS function is not included in the code, the messages show up on the Serial Monitor. but when i include the getSMS() function, it throws "random" ASCII characters. been trying String.toChar(), getChar, concat., but none seem to be working. thanks!

  for(y=0;y<=stringLen;y++)

Suppose the SMS was 3 characters. You are now accessing the characters in positions 0, 1, 2, and 3. Does that make sense?

The library you are using gives you the message as a char array. Ditch the String class and make use of the char array. Copying that (potentially huge) array into a String so you can unpack it later does not make sense.

but when i include the getSMS() function, it throws "random" ASCII characters.

Most likely because you are out of memory, because of the above issue.

The library you are using gives you the message as a char array. Ditch the String class and make use of the char array. Copying that (potentially huge) array into a String so you can unpack it later does not make sense.

i tried this but i'm having a hard time converting the String codes to Char Array codes. Could you help me out please?

Most likely because you are out of memory, because of the above issue.

I don't think this is the issue, I'm using a Gizduino, an Arduino Uno equivalent. it has 32kb of memory, the code only consumes around 12-13kb.

maskinao:
I don't think this is the issue, I'm using a Gizduino, an Arduino Uno equivalent. it has 32kb of memory, the code only consumes around 12-13kb.

Wrong memory. The Uno only has 2K of SRAM, which is what you are likely running out of.

i tried this but i'm having a hard time converting the String codes to Char Array codes. Could you help me out please?

You'll need to post code where you actually try to use the char array, and say what problems you are having.

You'll need to post code where you actually try to use the char array, and say what problems you are having.

I'm not quite sure how to make the Strings into a Char Array. Any Ideas? I'm really sorry for not being able to tell much. How can i use the msgBuff and parSMS as an array?

#include <SIM900.h>
#include <sms.h>
#include <SoftwareSerial.h>

// ---------- for sms ----------

char smsbuffer[160];	   //holds buffered data
char smsdata[250];         //sms only accept 160 char, remaining for header
char numberRx[20];         //holds sender number

char incomingChar;

boolean checkNum=false;  //if valid sender
boolean checkPass=false; //if valid password
boolean started=false;

//---------- registered numbers ----------
String regnum1="639339182267";

String passRx="default#";           //holds password, must be 8 char only! and ends with #
String msgBuff;
String parSMS;

void setup ()
{
  gsmsetup();  
}


void loop ()
{
  checkSMS();
}


void gsmsetup(void)
// ---------- serial setup ----------
{
  Serial.begin(9600);
  if (gsm.begin(4800)){
    Serial.println("GSM SHIELD READY");
    started=true;  
  }
  else Serial.println("GSM SHIELD IDLE");
}

void checkSMS()
// ---------- check if there is new message ----------
{
   if(started){	
    if(gsm.readSMS(smsbuffer, 160, numberRx, 20))
    {
      Serial.print("\nFrom: ");
      Serial.print(numberRx);
      Serial.print("\nMessage: ");
      Serial.print(smsbuffer);
      Serial.println("\n");
    }
    delay(1000);
    checkSender();
  }
}

void checkSender()
{

  String numRx(numberRx);
  if(numRx.startsWith(regnum1))
  {
    checkNum=true;
    Serial.println("Authorized Sender.");
    checkPassword();
  }
  else
  {
    Serial.println("Unauthorized Sender."); 
  }
}

void checkPassword()
{
  // ---------- convert array to string -----------
  msgBuff.concat(smsbuffer[0]);
  for (int i=1;i<=10;i++)
  {
    msgBuff.concat(smsbuffer[i]);
  }
  Serial.print("\nMessage Buffer: "); Serial.println(msgBuff);
  Serial.print("\nMessage Length: "); Serial.println(msgBuff.length());

  
  // ---------- check for password in string ------------
  if(msgBuff.startsWith(passRx))
  {
    checkPass=true; 
    Serial.println("Password Correct.");
  }
  else
  {
    checkPass=false; 
    Serial.println("Password inCorrect.");
  }
  
  if(checkPass==true)
  {
    parseSMS();
  }
}

void parseSMS()
{
          parSMS.concat(smsbuffer[9]);
          int i=10;
          while(smsbuffer[i]!='\0')
          {
            parSMS.concat(smsbuffer[i]);
            i++;
          }

          Serial.print("\nParsed SMS: ");
          Serial.println(parSMS);
          
          msgBuff=""; // clear message Buffer
          // ---------- convert to array ---------
         
          parSMS="";  // clear parsed sms buffer
          getSMS();  
}

void getSMS()
{
 // --------- convert string to array --------
 int y;
  int stringLen = parSMS.length();
  Serial.print("\nArray SMS: ");
  for(y=0; y <=stringLen; y++)
  {
     smsdata[y]= char(parSMS[y]);
     smsdata[y+1]='\0';
     smsdata[y+2]='~';
     Serial.println(parSMS); 
  }  
          
}

How can i use the msgBuff and parSMS as an array?

Here:

    if(gsm.readSMS(smsbuffer, 160, numberRx, 20))

You get the message in smsbuffer, which is a character array.

Here:

  msgBuff.concat(smsbuffer[0]);
  for (int i=1;i<=10;i++)
  {
    msgBuff.concat(smsbuffer[i]);
  }

You copy the message extremely inefficiently into a String. Don't do that.

You are doing it apparently because you find startsWith() easier to use than strncmp(). Why, I can't imagine.

Here:

          parSMS.concat(smsbuffer[9]);
          int i=10;
          while(smsbuffer[i]!='\0')
          {
            parSMS.concat(smsbuffer[i]);
            i++;
          }

You make another inefficient copy of part of smsbuffer.

You are doing so apparently because you don't know how to use String::substring and because you don't know how to use a for loop to print part of a char array.

Clearly, you do know how to use for loops to copy part of a char array to a String, so print it the same way.

You are doing it apparently because you find startsWith() easier to use than strncmp(). Why, I can't imagine.

I didn't know there was a function such as strncmp(). I'll look it up in a bit. :slight_smile:

You get the message in smsbuffer, which is a character array.

So you're suggesting I should use the smsbuffer as the output to the LED matrix? :slight_smile: I've thought of that as well, but it would include the password. I'll think of a way to get the password out of the message.

thanks for the tip! :slight_smile:

I've thought of that as well, but it would include the password.

How are you getting the password out of the String that you copy smsbuffer to? Or, is the password in the 8 characters that you skip?

How are you getting the password out of the String that you copy smsbuffer to? Or, is the password in the 8 characters that you skip?

Yes, it's like I'm skipping the "default#" string by using the concat. function like this one:

parSMS.concat(smsbuffer[9]);
          int i=10;
          while(smsbuffer[i]!='\0')
          {
            parSMS.concat(smsbuffer[i]);
            i++;
          }

it skips the password at the start of the message and then displays only the remaining text. any idea how to do this using the String Compare function?

Appreciate all the help very much! :slight_smile:

any idea how to do this using the String Compare function?

It can't be done using the string compare function.

Wherever you want to use the rest of what is in smsbuffer, just use a for loop starting at 9, just like in the code that copies the data to a string.

Or, after verifying that the 1st 8 characters are what you expect, move the data all up 8 positions.

for(int i=0; i<strlen(smsbuffer) - 8; i++)
{
  smsbuffer[i] = smsbuffer[i+8];
}
for(int i=0; i<strlen(smsbuffer) - 8; i++)

{
  smsbuffer[i] = smsbuffer[i+8];
}

OH YEAH! why haven't i thought of that? :cold_sweat:

thanks a bunch!

here's what i got so far :slight_smile:

/*

GSM BASED LED MATRIX DISPLAY USING ARDUINO
October 2012

*/

#include <SIM900.h>
#include <sms.h>
#include <SoftwareSerial.h>

// ---------- for sms ----------

char smsbuffer[160];	   //holds buffered data
char smsdata[160];         //sms only accept 160 char, remaining for header
char numberRx[20];         //holds sender number

char incomingChar;

boolean checkNum=false;  //if valid sender
boolean checkPass=false; //if valid password
boolean started=false;

//---------- registered numbers ----------
char regnum[] = {"639339182267"};

char passRx[] = {"default#"};           //holds password, must be 8 char only! and ends with #
char msgBuff[160];
char parSMS[160];

void setup ()
{
  gsmsetup();  
}


void loop ()
{
  checkSMS();
}


void gsmsetup(void)
// ---------- serial setup ----------
{
  Serial.begin(9600);
  if (gsm.begin(4800)){
    Serial.println("GSM SHIELD READY");
    started=true;  
  }
  else Serial.println("GSM SHIELD IDLE");
}

void checkSMS()
// ---------- check if there is new message ----------
{
   if(started){	
    if(gsm.readSMS(smsbuffer, 160, numberRx, 20))
    {
      Serial.print("\nFrom: ");
      Serial.print(numberRx);
      Serial.print("\nMessage: ");
      Serial.print(smsbuffer);
      Serial.println("\n");
    }
    delay(1000);
    checkSender();
  }
}

void checkSender()
{
  char numRx[12];
  int p = sizeof(regnum);
  for (int x=0;x<=p;x++)
  {
    numRx[x]= regnum[x];
  }
  
  if (strncmp (numberRx, numRx, 11) == 0)
    {
    checkNum=true;
    Serial.println("Authorized Sender.");
    checkPassword();;
    }
    
  else
  {
    Serial.println("Unauthorized Sender."); 
  }
}

void checkPassword()
{
 
  // ---------- check for password in string ------------
  if (strncmp (smsbuffer, passRx, 8) == 0)
  {
    checkPass=true; 
    Serial.println("Password Correct.");
  }
  else
  {
    checkPass=false; 
    Serial.println("Password inCorrect.");
  }
  
  if(checkPass==true)
  {
//    parseSMS();
    int p = sizeof(smsbuffer);
    Serial.println(p);
    for (int i=0;i<=p;i++)
    {
    Serial.println("\nSMSBuffer: ");
    Serial.print(smsbuffer[i]);
    }  
  }
}
/*
void parseSMS()
{
  int i=10;
  while(smsbuffer[i]!='\0')
  {
    parSMS.concat(smsbuffer[i]);
    i++;
  }

          Serial.print("\nParsed SMS: ");
          Serial.println(parSMS);
          
          msgBuff=""; // clear message Buffer
          // ---------- convert to array ---------
         
          parSMS="";  // clear parsed sms buffer
          getSMS();  
}

void getSMS()
{
 // --------- convert string to array --------
 int y;
  int stringLen = parSMS.length();
  Serial.print("\nArray SMS: ");
  for(y=0; y <=stringLen; y++)
  {
     smsdata[y]= char(parSMS[y]);
     smsdata[y+1]='\0';
     smsdata[y+2]='~';
     Serial.println(parSMS); 
  }  
          
}
*/

still working on the smsbuffer array. but it's coming along well i think. :smiley:

Hi Guys! :slight_smile: thanks for all the help! :slight_smile: i did it thanks to all of your help! :smiley:

/*

GSM BASED LED MATRIX DISPLAY USING ARDUINO
October 2012

*/

#include <SIM900.h>
#include <sms.h>
#include <SoftwareSerial.h>

// ---------- for sms ----------

char smsbuffer[160];	   //holds buffered data
char smsdata[160];         //sms only accept 160 char, remaining for header
char numberRx[20];         //holds sender number

char incomingChar;

boolean checkNum=false;  //if valid sender
boolean checkPass=false; //if valid password
boolean started=false;

//---------- registered numbers ----------
char regnum[] = {"639339182267"};

char passRx[] = {"default#"};           //holds password, must be 8 char only! and ends with #
char msgBuff[160];
char parSMS[160];

void setup ()
{
  gsmsetup();  
}


void loop ()
{
  checkSMS();
}


void gsmsetup(void)
// ---------- serial setup ----------
{
  Serial.begin(9600);
  if (gsm.begin(4800)){
    Serial.println("GSM SHIELD READY");
    started=true;  
  }
  else Serial.println("GSM SHIELD IDLE");
}

void checkSMS()
// ---------- check if there is new message ----------
{
   if(started){	
    if(gsm.readSMS(smsbuffer, 160, numberRx, 20))
    {
      Serial.print("\nFrom: ");
      Serial.print(numberRx);
      Serial.print("\nMessage: ");
      Serial.print(smsbuffer);
      Serial.println("\n");
    }
    delay(1000);
    checkSender();
  }
}

void checkSender()
{
  char numRx[12];
  int p = sizeof(regnum);
  for (int x=0;x<=p;x++)
  {
    numRx[x]= regnum[x];
  }
  
  if (strncmp (numberRx, numRx, 11) == 0)
    {
    checkNum=true;
    Serial.println("Authorized Sender.");
    checkPassword();;
    }
    
  else
  {
    Serial.println("Unauthorized Sender."); 
  }
}

void checkPassword()
{
  // ---------- check for password in string ------------
  if (strncmp (smsbuffer, passRx, 8) == 0)
  {
    checkPass=true; 
    Serial.println("Password Correct.");
    parseSMS();
  }
  else
  {
    checkPass=false; 
    Serial.println("Password inCorrect.");
  }
}  

void parseSMS()
{
  int y = 0;
  int i = 9;
  Serial.print("\nSMS Buffer: ");
  while (smsbuffer[i] != '\0')
  {
    parSMS[y] = smsbuffer[i];
    Serial.print(smsbuffer[i]);
    i++;
    y++; 
  }
  loadSMS(); 
}
void loadSMS()
{
  int i = 0;
  Serial.print("\nParsed SMS: ");
  while (smsbuffer[i] != '\0')
  {
    Serial.print(parSMS[i]);
    i++; 
  }
}

thanks again! :smiley: