Unable to 'stream' charachters

Hi Arduino-heads!

After developing for two weeks non-stop, I came to the very last annoyance before finishing my project.

I'm trying to make a device that responds on incoming SMSes by forwarding the message (an array of chars) to another person.
I can't pinpoint the problem, whether I wrongly chose pointers/vartypes or some other conflict.

Please correct me if I'm wrong!:
Because I learned that I cannot pass a string/char variable to a function, I decided to create a publicly shared class object (called mzg), to allow myself write messages as needed. This is done by calling the WrapAndSend-routine. It gets the information from getLocation, but when it's supposed to send the message, all I read is this:

>

Which means that the message, although the object SMS.mzg (or this->mzg) contains the message, it doesn't 'print' it to the NSS port. :cry:
Sometimes, after changing some code around, I only receive the first character of the fetched string.

Have been trying over a week now and it seems that it's taking the life out of me. Can anyone help me on this issue?

Kind regards
Royale

main

void WrapAndSend() {
SMS.mzg = getLocation();

Serial.print("The mzg");
Serial.println(SMS.mzg);

SMS.sendSMS("+12345678900");
 delay(1500);
iterbuf(0); // Get Response from mobile
}

char  * getLocation() {

//Some thingies here

return locationcode;
}

hilo.h

#ifndef hilo_h
#define hilo_h
#include <NewSoftSerial.h>
#include <WProgram.h>

class hilo
{
  NewSoftSerial GSM; // Works like a charm btw!!
  public:
  // some methods
    void sendSMS(char *receiver);
    char *mzg;
private:
    char *_receiver;

hilo.cpp

void hilo::sendSMS(char *receiver)
{   
    _receiver = receiver;

    GSM.print("AT+CMGS=");
    GSM.print(34,BYTE);
    GSM.print(_receiver);
    GSM.print(34,BYTE);
    GSM.println(0x0D,BYTE);

    delay(1500); 
    GSM.print(this->mzg);
    delay(500);
    GSM.println(0x1A,BYTE);    
    delay(5000);
}

An update:

It seems that my problem is as following.

When you send an SMS, it requires you to do two things:

  1. You send the AT command followed by the recipient.
    e.g. AT+CMGS="+1234567890" <CR>

  2. after half a second, you enter the message:

> This is my message <CTRL+Z>

When I use:

SMS.sendSMS("+1234567890", "Hurray");

My message gets sent correctly and I receive a message on my phone.

When I use

SMS.sendSMS("+1234567890", themessage);

It does nothing. Better yet, when I check what my the phone is doing, it returns:

>

... meaning it's waiting for the message to turn op.

Can I conclude that my routine doesn't stream variables to the phone (like char themessage[14]). Is there a workaround for this?

Thanks in advance!

Here is a test you can do:
after
GSM.print(_receiver);
Add
Serial.print(_receiver);
If you can't see the string on the serial monitor you may find it easier to debug your code using the serial monitor and move back to NSS when you have it working.

That's funny!

I made another routine, which only uses HardwareSerial for printing all the commands. Thus when doing this:

char loccode[15] = "secret message";
SMS.SsendSMS("+1234567890", loccode);

It prints this on the serial port:

AT+CMGS="+1234567890"

?

What does this mean?

in your class code, try printing receiver directly (without _receiver = receiver;)

Whoops, my bad!
I accidentally forgot to change some variables.
now, when I use

char loccode[15] = "secret message";
SMS.SsendSMS("+1234567890", loccode);

It does print out:

AT+CMGS="+1234567890"
secret message

However
Doing the normal routine (ie. to GSM modem, not to Hardware serial), again returns

> >

That's strange, ain't. So the variable is actually there, but doesn't get printed to the port?

Perhaps your format is not correct. Are you sure about that carriage return. Try sending a complete hard coded message bypassing your class code, this will help you check that the message format to the GSM modem is ok.

I think the problem here cuold be the scope of the variable.

This:

char* getLocation(){
  char* buf = "test";
  return buf;
}

Won't work, because by the time you return the buf it's no longer active in memory.

You need to declare such a variable at class scope.
[edit]May I see your getLocation()[/edit]

Well, the format is correct.

Wait a sec. Could it be that NSS doesn't handle print requests like this?:
GSM.print(34**,BYTE**); Naaah, don't think so, since I've been able to succesfully send messages with the same set of commands.

Update: It doesn't work hardcoded either. When sending commands only using my sendCmd routine, it doesn't show up on the modem monitor (as above.) However, when using Serial.print, it works just fine :-/

AlphaBeta:
Alot of garbage between the code, don't mind :slight_smile:

void getLocation() { //const char *getLocation() {

 
  int k;
  inString = ""; // From the Wstring library
  SMS.sendCmd("AT+CMGR=1");
  iterbuf(1); // reads modem - option 1 = only SMS header
  inString= MySMS; 
   if (inString.contains("+1234567890")) {   
    SMS.sendCmd("AT+CMGR=1");
      iterbuf(2); // reads modem - option 2 = read SMS body and is stored to 'MySMS' (from Pstring library)
      k=0;
      for (k=0; k<13; k++) {
      locationcode[k] = MySMS[k];
        } 
       locationcode[k+1] = '0';
      } 
Serial.println("Here's substring");
Serial.println(locationcode);
inString ="";

}

It's hard to see exactly what is happening. Can you post the minimal test sketch that sends a hard coded message through NSS. Ideally, this test would only print a hard coded string using NSS without going through any of your class code. If the problem persists then you know its not any of your class code.

It works!!!!!!

It seems that, for some reason, the variable needs to be streamed to the modem port, as if it being a literal text.
I used Mikal's Streaming library to get this baby going like this:

void hilo::sendZ(char *cmdd)
{   
_cmd = cmdd;
 GSM << _cmd << _BYTE(26) << endl;
}

Can you explain the difference between GSM.print and the Streaming operation as above?

And another thing: I keep an eye on the RAM by printing the free space in my Serial monitor. Before it GSM.sendZ(var), it had 250 bytes left. After it send the message, I only had '1023' bytes left, which means stack overflow, right? Any reason why this operation uses a lot of RAM space? Especially concerning the fact that Mikal states that it doesn't consume resources.
http://arduiniana.org/libraries/streaming/

Geez, wasted a week to get this done. Thank you for your help till now and thanks in advance for the remaining questions.

-R

does this work this?

void hilo::sendZ(char *cmdd)
{
_cmd = cmdd;
GSM.print(_cmd);
GSM.print(_BYTE(26);
GSM.print(endl);
}

or this?
void hilo::sendZ(char *cmdd)
{
GSM.print(cmdd);
GSM.print(_BYTE(26);
GSM.print(endl);
}

what is the _BYTE(26) for ?

Byte(26) denotes Ctrl+Z, i.e. the end of the message.
I'll get back to you in a minute

SHIT? Wtf?!! This also works?!!

void hilo::sendZ(char *cmdd)
{   

   _cmd = cmdd;
   GSM.print(_cmd);
   GSM.print(26, BYTE);
   GSM.print(endl);
}

Okay, this is over my head? :o What's happening here?

Btw, RAM usage also dropped here with about 240 bytes till stack overflowish 1023. Or is this not a stack of?

This is even simpler, did you try it?
void hilo::sendZ(char *cmdd)
{
GSM.print(cmdd);
GSM.print(26, BYTE);
GSM.print(endl);
}

RAM usage also dropped here with about 240 bytes till stack overflowish 1023. Or is this not a stack of?

huh?

Mem: Indeed, that piece of code also works.

But uhm, what's up with the excessive RAM usage? Anyone who can shine his wisdom on this problem?

-R

can you say a little more about what exactly is happening with the RAM, I am not clear what you are saying.

Also, does the simple test code that does not use your class also run out of RAM.

Well, I have small routine in my main (loop) that checks how much RAM memory is left. This to check if I still enough memory for variables & performance.

So everytime I call I perform function (e.g. getLocation, sendSMS, sendCmd etc.), I also let my board check how much RAM is left.

Now, here's a copy of my Serial monitor:

OK (<--- RESPONSE OF: SMS.sendCmd("AT");

218  (<---- THIS IS LEFTOVER MEMORY)



Here's substring (<--- RESPONSE OF: getLocation();
10425 12eiok

218 (<---- THIS IS LEFTOVER MEMORY)



OK (<--- RESPONSE OF: SMS.sendZ(locationcode);

1023 (<--- UH OH, WE START RECOUNTING)

This is the routine

int availableMemory() 
{
  int size = 1024;
  byte *buf;
  while ((buf = (byte *) malloc(--size)) == NULL);
  free(buf);
  return size;
}

My guess is that the string library you are using is not releasing memory. You could try replacing the string code with a static character array big enough to hold your longest string to see if that is the cause.

Well mem, I cleaned up some more variables. I freed up about 200 bytes of valuable space.

BUT

Running the code again gives me the same symptom: The memory counter suddenly drops to 1023.
It's really keen on this number. No matter how much space i free up additionaly, the available memory drops excessively. Giving me a reason to think that there's a problem. And this started ever since I used 'endl'

Is there a problem?

I would expect other symptoms if you were using up all the RAM.

BTW, did you try the test that replaced the string class with a static character array?