Clearing SRAM help

Hi

System is running arduino uno /w GSM shield and a SD card reader attatched.
The problem is (I think) that im too low on SRAM, because when I run all the functions seperately, they work like a charm :slight_smile:

The sensor reads fine and posts to the SQL server just fine. But nothing is put on the SD card.

Any advice is very much appreciated :slight_smile:

The code:

#include <GSM.h>
#include <SPI.h>
#include <SD.h>
#include <avr/pgmspace.h>
#include "LowPower.h"

#define PINNUMBER ""
#define GPRS_APN       "Internet"
#define GPRS_LOGIN     ""
#define GPRS_PASSWORD  ""

GSMClient client;
GPRS gprs;
GSM gsmAccess; 

const char server[] = "";
const char path[] = "/water_reading/post.php";
const int port = 80;

int read1 = 0;
String POST1 = "";

const int sensorPin = A0;
const int chipSelect = 4;
const unsigned long __TIMEOUT__ = 10 * 1000;

void setup()
{
  Serial.begin(115200);
  
  while (!Serial) 
  {
    ;
  }

  //SD CARD
  Serial.print(F("Initializing SD card: "));

  if (!SD.begin(chipSelect)) {
    Serial.println(F("Card failed, or not present"));
    return;
  }
  Serial.println(F("Card initialized."));

  //MODEM
  Serial.println(F("Starting POST Web Client."));
  boolean notConnected = true;

  while(notConnected)
  {
    if((gsmAccess.begin(PINNUMBER)==GSM_READY) &
      (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD)==GPRS_READY)){
      notConnected = false;
      } else
    {
      Serial.println(F("Not connected"));
      delay(1000);
    }
  }

  Serial.println(F("connecting..."));
}

void loop() 
{
  read1 = analogRead(sensorPin);

  //Define POST data
  POST1 = "POST1="+(String(read1));

  File dataFile = SD.open("datalog.txt", FILE_WRITE);

  if (dataFile) {
    dataFile.println(POST1);
    dataFile.close();
    Serial.print(F("Datalogging succesfull"));
    Serial.println(POST1);
    delay(1000);
  }
  else {
    Serial.println(F("Error opening datalog.txt"));
    delay(1000);
  }

  if (client.connect(server, port))
  {
    Serial.println(F("conected to web server, sending data"));
    client.print("POST "); //Begin HTTP POST request
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");
    client.println(POST1.length());
    client.println();
    client.print(POST1);
    client.stop();
    
    //Post the info we sent
    Serial.print(F("Variable: "));
    Serial.println(POST1);
    Serial.print(F("Variable Length: "));
    Serial.println(POST1.length());
  }
  else
  {
    Serial.println(F("the connection failed"));
  }
   LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);  
  //delay(5000); // delay to send data every x seconds seconds
}

The output:

Initializing SD card: Card initialized.
Starting POST Web Client.
connecting...
Error opening datalog.txt
conected to web server, sending data
Variable: P√ŅjE√™¬Ę√ä¬≤j
Variable Length: 9
Error opening datalog.txt
conected to web server, sending data
Variable: P√ŅjE√™¬Ę҆Ұj
Variable Length: 9

A couple of comments on the code Do not use ints where bytes would be large enough

const char server[] = "";

How many characters are going to be saved in this array ?

You can't clear SRAM.

You CAN stop pissing away resources uselessly:

String POST1 = "";

The File class KNOWS how to write text and ints to a file. It does not your help to wrap a string in a String that then needs to be unwrapped to write to the file.

sprintf() and a character array will waste less resources, for the actual POST process, although a GET makes more sense. I can't imagine why the data needs to be "hidden" in a POST packet.

Seems you might need to move to a Mega.
I had similar issues when running an Uno with SD card and moved to a Mega.
You could try using PetitFat which is a smaller SD card library, but not sure it will save you enough SRAM with everything else you have going on.

    Serial.println(F("conected to web server, sending data"));
    client.print("POST "); //Begin HTTP POST request
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");

Did you get bored with using the F() macro?

UKHeliBob: A couple of comments on the code Do not use ints where bytes would be large enough

const char server[] = "";

How many characters are going to be saved in this array ?

Currently, the array holds 12 chars, might be more for the final product.

PaulS: You can't clear SRAM.

You CAN stop pissing away resources uselessly:

String POST1 = "";

The File class KNOWS how to write text and ints to a file. It does not your help to wrap a string in a String that then needs to be unwrapped to write to the file.

sprintf() and a character array will waste less resources, for the actual POST process, although a GET makes more sense. I can't imagine why the data needs to be "hidden" in a POST packet.

Its a POST because its sensitive data from sensors placed around the country.

Now, I THINK I know what you mean with wrapping a string on a String, but could you elaborate? Thanks :)

aisc: Seems you might need to move to a Mega. I had similar issues when running an Uno with SD card and moved to a Mega. You could try using PetitFat which is a smaller SD card library, but not sure it will save you enough SRAM with everything else you have going on.

Moving to a mega isnt an option, I have to stay on a 3.3V system, since it has to hold battery for 2 years (3.7V industrial grade lithium batteries). The final product will be on a arduino pro mini.

[quote author=Nick Gammon link=msg=2396046 date=1442219343]

    Serial.println(F("conected to web server, sending data"));
    client.print("POST "); //Begin HTTP POST request
    client.print(path);
    client.println(" HTTP/1.1");
    client.print("Host: ");
    client.println(server);
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.print("Content-Length: ");

Did you get bored with using the F() macro? [/quote]

No, but from what I understood, you couldnt use it during http requests. I assume I read wrong?

Update: changed the int to byte in the top of the code. I also F()'ed the strings in the POST.

The SD card now logs, and the SQL server also still sends just fine.

But the output is still a bit junky:

Initializing SD card: Card initialized.
Starting POST Web Client.
connecting...
Datalogging succesfull
POST1=243
conected to web server, sending data
Variable: P√ŅjE√™‚Äô¬ĘŇ°j
Variable Length: 9
Datalogging succesfull
POST1=161
conected to web server, sending data
Variable: P√ŅjE√™Ň†¬≤҆j
Variable Length: 9
[code/]

Currently, the array holds 12 chars, might be more for the final product

 const char server[] = "";

How many bytes are allocated by the declaration ? Is the program expected to change the value of a const variable ?

H4rdstyler: But the output is still a bit junky:

See the second half of reply #2.

UKHeliBob: const char server[] = "";

How many bytes are allocated by the declaration ? Is the program expected to change the value of a const variable ?

No idea what is allocated. The server MIGHT change, Im unsure :/ Ive got everything working now, just gotta build on the sleep mode functions now and keep testing :)

They're tying to get you to realize that you've allocated an array with nothing but a single null terminator in it. If you try to add anything to it then you are going to write over the end of the array and step on memory you don't own.

H4rdstyler: No, but from what I understood, you couldnt use it during http requests. I assume I read wrong?

Try it and see. The only downside is that there might be a speed penalty, however there are various ways around that.