Hello all again.
What is PSTR and how should it be used? I understand it's something about just using flash instead of flash and ram?
Many thanks ppl.
Hello all again.
What is PSTR and how should it be used? I understand it's something about just using flash instead of flash and ram?
Many thanks ppl.
For example:
Serial.print("This is a test - Hello world!!");
uses SRAM for the string, so few such prints and your SRAM is full.
You may use:
Serial.print(F("This is a test - Hello world!!"));
and it uses FLASH for storing the string, thus you save the SRAM. p.
http://www.arduino.cc/playground/Learning/Memory http://arduino.cc/en/Reference/PROGMEM http://arduino.cc/playground/Main/Printf
I get this error when i try to use Serial.println(F(SoftwareVersion)); SoftareVersion = const char SoftwareVersion[] = "v0_1_0";
warning: only initialized variables can be placed into program memory area initializer fails to determine size of'__c'
Any ideas?
F is a macro, not a function. It expects something that looks to the compiler as a string literal, not a string constant.
Thank you :).
I have used #define SoftwareVersion "v0.1.0\r" then used the Serial.println(F(SoftwareVersion));. Saves some space.
Does the PSTR/F macro work with the SoftwareSerial library? My sketch works with PSTR with Serial.print(); but don't with the SoftwareSerial.print();.
ie. (ide 1.0.1): Serial.println(F("Unable to sync with the RTC")); lcd.print(F("Pa/30min")); myFile.print(F(","));
Here is a sketch that shows a user i/o command processor (allows variables to be changed while the sketch is running) and use of PROGMEM to store menus and help messages and print those out using 1 char of SRAM rather than a full-width buffer.
tested, working a while ago:
#include <avr/io.h>
#include <avr/pgmspace.h>
unsigned long mark = 0UL; // time and duration storage
unsigned long now = mark;
unsigned long last = now;
const char PROGMEM report[][20] = {
"\nedited: vertical ", " ... timescaler " };
const char PROGMEM tapLabel[3][20] =
{
"vertical value: ", " | tap + side: ", " | tap - side " };
const char PROGMEM usageMsg[][80] = { // all this text stored in flash
" Piezo touch sensor tuner.",
"Adjust vertical; enter W to subtract or X to add, and a number 0-255",
"Adjust timescaler; enter A to subtract or D to add, and 0-16535",
"to add 250 to vertical enter W250 in Serial Monitor and press enter",
"seperate multiple commands with spaces; ex: W25 D240",
" ** this message stored in flash ram **",
" ** and printed with a 1 byte buffer ** :-P"
};
PGM_P Msg; // pointer into flash memory
#define MAXVERT 255
#define MAXSCALE 16535
#define HELPLINES 7
unsigned long vertical = 0UL; // just a varible with meaningful name
unsigned long timescaler = 0UL; // ditto, not used any more except to change
unsigned long temp;
byte B, command;
void printMsg( PGM_P FM )
{
do
{
B = pgm_read_byte( FM++ );
if ( B ) Serial.print( B );
}
while ( B );
}
void printHelp(void)
{
for ( byte i = 0; i < HELPLINES; i++ )
{
printMsg( usageMsg[ i ]);
Serial.println();
}
Serial.println();
}
void setup(void)
{
Serial.begin(9600);
printHelp();
}
void loop(void)
{
// there used to be code to read touch sensors here, put something else in
// below reads serial input and reacts to single character commands
// with multidigit numbers following, like R500
// this might do, you might want to do more
// it's a real -simple- user i/o to tune variables used in now some other code
// a command line might look like D133, adding 133 usec to the timescaler
// all that happens in this sketch is two variables get changed
// those are vertical and timescaler just to provide examples with names
// timescaler usecs had to run out between digital HIGH read adds 1 to a counter
// that counter makes a digital pin into an ADC with variable possible precision
// each pin had a capacitor
if ( Serial.available())
{
B = Serial.read();
Serial.print( B );
if ( !command ) // only TRUE when command == 0
{
temp = 0UL;
if (( B & 0xDF ) == 'X' )
{
command = 1;
return; // shortcut back to loop() to wait for the next serial read
}
else if (( B & 0xDF ) == 'W' )
{
command = 2;
return; // shortcut back to loop()
}
else if (( B & 0xDF ) == 'A' )
{
command = 3;
return; // shortcut back to loop()
}
else if (( B & 0xDF ) == 'D' )
{
command = 4;
return; // shortcut back to loop()
}
}
else // looking for digits only, will limit and fit into an unsigned long
{
if (( B >= '0' ) && ( B <= '9')) // first turn digits into a value
{
temp *= 10UL;
temp += (unsigned long) ( B - '0' ); // so all numbers build in temp
}
else // as soon as it finds a non-digit, it assumes that to be a separator
// it's not bulletproof but doesn't allow values out of range
{
// Serial.println(); // debug code
// Serial.print( "command " );
// Serial.print( command, DEC );
// Serial.print( " temp " );
// Serial.println( temp, DEC );
// Serial.println();
switch ( command ) // next apply that number to the program variables
{
case 1:
{
if ( vertical < temp )
{
vertical = 0UL;
}
else
{
vertical -= temp;
}
command = 0;
break;
}
case 2:
{
if ( vertical + temp > MAXVERT )
{
vertical = MAXVERT;
}
else
{
vertical += temp;
}
command = 0;
break;
}
case 3:
{
if ( timescaler < temp )
{
timescaler = 0UL;
}
else
{
timescaler -= temp;
}
command = 0;
break;
}
case 4:
{
if ( timescaler + temp > MAXSCALE )
{
timescaler = MAXSCALE;
}
else
{
timescaler += temp;
}
command = 0;
break;
}
default:
{
command = 0;
temp = 0UL;
printHelp(); // carriage return will trigger this
return; // includes no command == 0 does not print status
}
}
// breaks above go here
printMsg( report[ 0 ]); // "\nedit: vertical "
Serial.print( vertical );
printMsg( report[ 1 ]); // " ... timescaler "
Serial.println( timescaler );
}
}
}
}
Thank you, i have this all sorted now and freed up some SRAM by using this function.