I would appreciate your help on this as I'm going crazy I have an ATMEGA328p in a standalone project and am having problems using PROGMEM for constants. To illustrate this, I have made a simple sketch and include file. What I am finding is if I set a program memory constant within a function, it is not being remembered (or I am not accessing it correctly). In the example below, the constant "KONSTANT" is heart of the issue
Focus on function1 in junk1.cpp which has the following lines:
prog_uint16_t KONSTANT PROGMEM=499;
if (pgm_read_word_near(&KONSTANT) != 499)
PORTD=0b00000000; // gets here!
else
PORTD=0b11000000;
This works if you have the library correctly installed in the Arduino's IDE library directory. If not, it won't work. What's the directory name where you are compiling the code?
This works if you have the library correctly installed in the Arduino's IDE library directory. If not, it won't work. What's the directory name where you are compiling the code?
econjack,
I am running the sketch from /junk/junk.ino the junk1.h and cpp files are in /libraries/junk1/
I have the arduino ide setup to see this library directory (when I go to Sketch->Add library I see the junk1 directory listed)
Sometimes they are but I try to use them only when I have to. As to why, I have run into issues using globals that multiple functions were modifying. It was a headache to debug. Also, according to "Atmel AVR4027: Tips and Tricks to Optimize
Your C Code for 8-bit AVR Microcontrollers" they have the following:
In most cases, the use of global variables is not recommended. Use local variables
whenever possible. If a variable is used only in a function, then it should be declared
inside the function as a local variable.
In theory, the choice of whether to declare a variable as a global or local variable
should be decided by how it is used.
If a global variable is declared, a unique address in the SRAM will be assigned to this
variable at program link time. Also accessing to a global variable will typically need
extra bytes (usually two bytes for a 16 bits long address) to get its address.
Local variables are preferably assigned to a register or allocated to stack if supported
when they are declared. As the function becomes active, the function’s local variables
become active as well. Once the function exits, the function’s local variables can be
removed.
Using a static local will defeat the main argument to avoiding globals. Static vars are also located in the heap, not registers or the stack.
The main difference is the compiler can 'sometimes' use one cycle to access a static local, over the 2 cycle operation on a 16-bit address. ( however even a real global can receive this benefit in rare circumstances ).
pYro_65:
Using a static local will defeat the main argument to avoiding globals.
The main advantage is that the variable is limited to the scope of the function that declares it, which eliminates a bunch of complexity and potential bugs relating to shared data.
Given that we're talking about a local constant defined in progmem, I can't imagine what other argument is being 'defeated' here.
pYro_65:
Using a static local will defeat the main argument to avoiding globals.
The main advantage is that the variable is limited to the scope of the function that declares it, which eliminates a bunch of complexity and potential bugs relating to shared data.
Given that we're talking about a local constant defined in progmem, I can't imagine what other argument is being 'defeated' here.
well, every variable declared inside a function is limited to its scope, however I'm referring to its lifetime and storage use. Global/static data provides persistent storage, and static locals can be quicker to access than variables in the global namespace.
My info is in reference to the post above it, try stay with the flow. PROGMEM is an AVR specific and not really part of C++ at all.
pYro_65:
well, every variable declared inside a function is limited to its scope, however I'm referring to its lifetime and storage use. Global/static data provides persistent storage
I'm not sure whether you're correcting me or agreeing with me.
Global data is generally disliked because it is visible to all code in the global scope which increases complexity and the potential for bugs. That's less of an issue in the sort of small application suitable to be implemented in an Arduino, but it's still an issue. Using static local variables gives you similar behaviour but takes the data out of the global scope, which avoids the main issues associated with global data.
I don't think that speed of access to memory should be a consideration unless you are up against a critical performance issue; an extra clock cycle here or there is insignificant compared to the other issues.
Given that we're discussing this in an Arduino forum, I don't understand your point about PROGMEM being AVR specific.