My current project has a lot of variables and a lot of strings, and I don't want it to crash due to a lack of RAM. I though that I could wrap strings in F() to save space, but then I get
warning: only initialized variables can be placed into program memory area
What's this about?
Also, will the compiler/AVRdude tell me if I have too many variables and am going to use up the RAM?
I think that the message is pretty explicit. Flash/PROGMEM is read-only at run time, so placing an uninitialized variable in Flash/PROGMEM means that it can never be assigned a value, which means that placing it in Flash/PROGMEM is a waste of time and code space.
Specifically, what are you doing that causes the compiler to complain? This is the Programming section, where we expect to see code.
At runtime, PROGMEM behaves like a ROM. It is accessible in read-only mode, but its content cannot be changed. Therefore the only time when you can decide what to put into a PROGMEM-variable is at compile time.
Until you show the code, though, no direct advice can be given.
My code is 10Kbytes and ~300 lines long... I'll just post setup() for now.
/* Science Research Program Yr. 1 2011 - 2012
* Reaction test
*
* Connections:
* Button, LED defines in includes.h; EEPROM to I2C SDA (A4) and SCL (A5)
*/
#include <Wire.h> //Communication with 24LC256
#include <EEPROM.h> //storage for seeds and other data
#include <EEPROMAnything.h> //write anything to EEPROM.
#include "includes.h" //preferences, defines, macros, etc.
unsigned long subjectNumber = 0; //subject number
//For time storage
byte currentRound; //used like testNames[currentRound], zero indexed;
byte testNames[3]; //control, phone, or texting
/* stores times, in (rounded) milliseconds (raw timing done in micros)
* format always 0:contol, 1:phone, 2:text
*/
unsigned long testTimes[3];
unsigned int memPointer = 0; //24LC256 memory pointer
byte testRunning = false;
//Start of program
void setup () {
unsigned int prandSeed;
Serial.begin(19200); //Change this in Serial Monitor!
Wire.begin();
Serial.println(F("SRP Reaction Timer")); //warning right here.
pinMode(BUTTON_PIN, INPUT);
digitalWrite(BUTTON_PIN, HIGH); //pullup
pinMode(LED_PIN, OUTPUT);
EEPROM_readAnything(PRANDSEED_ADDRESS, prandSeed);
randomSeed(prandSeed);
}
It also will happen with other Serial.print strings throughout the program. But if this won't work, then why is it listed under the print() reference?
how do I figure out how much of the RAM is being used?
The amount of RAM in use changes as your program runs. So, there is no one "This is how much SRAM you are using" point. You can add calls to freeMemory() (once you search and find the function) to your code, at various places, to see how much you have at various points in the program.
A very primitive count of my program shows that I have 60 bytes of variables (not counting the scope of variables) + 264 bytes of strings = 324 bytes total, neglecting scope. So I could go neurotic anyway and wrap the strings in F(), but I think I'll be fine: '328P has 2K...
It would be interesting if you started removing F() one by one, leaving the problematic one in place tough, and tell us when the error stops showing up...
Sorry if I wasn't being clear... it comes up as a compiler warning (it still compiles). But it turns out that something in Arduino's Tone.cpp causes this warning, too, so I'll ignore it.
I have exactly the same compilation warnings.
Tone.cpp indeed has the same warning.
It is due to the usage of F() strings (PROGMEM).
Is there a way to workaround this? Ideally I prefer to get Zero warnings.
Why is the the usage of F() strings recommended if the compiler warns against it??
The necessary changes to the Tone file have been documented. You could search for the fix, and implement it.
Is there a way to workaround this? Ideally I prefer to get Zero warnings.
See above. There are plenty of other warnings that are not shown to you, so zero warnings is pretty difficult to achieve.
Why is the the usage of F() strings recommended if the compiler warns against it??
The F() macro moves strings into program memory, removing them from SRAM, making SRAM available for other things. The compiler isn't warning against using F() in general, only in what Tone specifically is doing that causes the issue.
The warning is really just a warning in IDE 1.0. It is triggered in tone.cpp, too. If you search the web it is not unique to arduino. I modified arduino.h by adding the following at line ~58.
Marek080:
The warning is really just a warning in IDE 1.0. It is triggered in tone.cpp, too. If you search the web it is not unique to arduino. I modified arduino.h by adding the following at line ~58.
// Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
Great, exactly what I was looking for!
I have zero tolerance to compilation warnings, once you get used to them the quality of the code quickly deteriorates.
I don't know why Arduino team is releasing code that has warnings (like tone.cpp). It should not be allowed - period.
As for F() usage, I find it problematic:
A simple usage of:
String test = F("hello");
does not compile: "error: conversion from '__FlashStringHelper*' to non-scalar type 'String' requested"
The String constructors do not support this data type, which is very unfortunate. Sure, I can go to that class and start making it work but it should be working out of the box;