Problem with PROGMEMAnything not working

Attention for Nick…

I've been using your PROGMEMAnything.h file for a long time now with much success. Thank you for posting it here a while back. However now I'm having a problem.

I just recently installed the Arduino 1.0.4 IDE on my Raspberry Pi whereas I had been using 1.0.1 on my Windows PC. When I try to compile code on the newer IDE (possibly using a different version of GCC I'm not sure) I'm getting compile errors. Basically it's telling me that anything program memory has to be declared "const". I can go through and add that to all of my definitions but I don't know what to do with your typedef's because I never really understood how they worked. Can you offer suggestions or post a new version of your library? Here is a typical error message I'm getting.

In file included from use3b.ino:31:0:
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h: In instantiation of ‘T PROGMEMAnything(T*) [with T = const cmnd]’:
use3b.ino:332:107:   required from here
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h:17:7: error: uninitialized const ‘result’ [-fpermissive]
use3b.ino:91:16: note: ‘const struct cmnd’ has no user-provided default constructor
use3b.ino:92:8: note: and the implicitly-defined constructor does not initialize ‘long int cmnd::Value’
In file included from use3b.ino:31:0:
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h:18:5: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
In file included from /home/pi/arduino-1.0.4/hardware/arduino/cores/arduino/WString.h:29:0,
                 from /home/pi/arduino-1.0.4/hardware/arduino/cores/arduino/Print.h:26,
                 from /home/pi/arduino-1.0.4/hardware/arduino/cores/arduino/Stream.h:26,
                 from /home/pi/arduino-1.0.4/libraries/Wire/Wire.h:26,
                 from use3b.ino:3:
/usr/lib/gcc/avr/4.7.2/../../../avr/include/avr/pgmspace.h:1040:14: error:   initializing argument 1 of ‘void* memcpy_P(void*, const void*, size_t)’ [-fpermissive]

Posting your code is important, error messages are mostly a guess without it.

const struct cmnd

As this is marked constant, its contents has to be defined when initialised. You must be using it wrong as progmem is read-only and you have not provided any data for some/all members.

/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h

PROGMEMAnything is NOT a core library, and does not belong in the core library folder.

About midnight last night I realized I should have made the components constant as well. Got up this morning and tried it only to get a whole bunch more error messages. Sorry I should've posted code in my original message. Here is a slightly stripped-down version of what is in the actual code. I have a typedef that is a structure of commands. Then I have a large table of commands all of which I want in program memory. Here is a sample of one of trying to do. This is just an excerpt. The command table is much larger than is shown here.

enum IRTYPES {UNKNOWN, NEC, SONY, RC5, RC6, SA, JVC, NECX, HASH_CODE, LAST_PROTOCOL=HASH_CODE};

enum SPECIAL {NONE,SHUTDOWN, RECORD, GOTO_AR, GOTO_SELECT, GOTO_UP, MODE_CH};

typedef const struct cmnd{
  const long Value;
  const IRTYPES ProtType;
  const byte Bits;
  const SPECIAL Special;
}cmnd_t;

const cmnd_t PROGMEM MyCommands[]= {
 {0x37c906,SA,0,NONE}, {0x37291a,SA,0,NONE}, {0x37990c,SA,0,NONE}, {0x36293a,SA,0,NONE},
 {0x374117,SA,0,NONE}, {0x365934,SA,0,GOTO_UP}, {0x36b129,SA,0,NONE},  {0x180d,RC5,13,NONE},
 {0x1811,RC5,13,NONE}, {0x1810,RC5,13,NONE},  {0x377111,SA,0,NONE}, {0x36f121,SA,0,NONE},
 {0x36213b,SA,0,NONE}, {0x37f101,SA,0,NONE}
}

The original version of my code did not have "const" anywhere and it works fine under the old IDE and compiler. I've not tried installing the 1.0.4 IDE on my Windows machine. I'm still using 1.0.1 and it works fine but when I went to install the IDE on my raspberry pi I figured I would start out with the newest version and this is the problem I've got. My guess is there is a compiler switch I can throw somewhere that would allow this to go through the old way but I don't know how to do it. Back when I first learned about program memory I thought perhaps it ought to require "const" so philosophically I like that it now does. But I can't figure out how to make it work now that it does require it.

On a separate issue of where to put libraries I was under the impression that all the libraries had to be in the library folder. If I want to use non-core libraries like yours or ones that I get from other sources, where do I put them so that the compiler can find them if I don't put them in the traditional core library folder?

I have a typedef that is a structure of commands.

No, you don't. You have a struct that defines something you think of as a command, and a typedef statement that assigns another name to "struct cmnd". Correct terminology is important.

On a separate issue of where to put libraries I was under the impression that all the libraries had to be in the library folder. If I want to use non-core libraries like yours or ones that I get from other sources, where do I put them so that the compiler can find them if I don't put them in the traditional core library folder?

User downloaded libraries go in the libraries folder where you store sketched. On my Win7 box, I store sketches in C:\Users\PaulS\Documents\Arduino, so I download libraries to C:\Users\PaulS\Documents\Arduino\libraries.

Okay so I called it the wrong thing. I have a structure called "cmnd" consisting of a couple of enums, a long, and a bite. I have a typedef which defines cmnd_t. I have an array of cmnd_t My_Commands with an initializer. I want the entire thing in program memory. It used to work now it doesn't.

I'm still not having anyluck solving this problem of where to put the const specifications. The code I posted in a previous message doesn't work and I don't know what else to try. As I mentioned before this works on an older version of the Arduino IDE and possibly different version of the compiler that I have installed on my Windows PC but does not work on the latest Arduino IDE installed on my Raspberry Pi. I don't want to install the new IDE on my Windows machine to I'm sure I can fix this problem.

This is how I would write what you are trying:

struct cmnd_t{
  long Value;
  IRTYPES ProtType;
  byte Bits;
  SPECIAL Special;
};
const cmnd_t  MyCommands[] PROGMEM = {
 {0x37c906,SA,0,NONE}, {0x37291a,SA,0,NONE}, {0x37990c,SA,0,NONE}, {0x36293a,SA,0,NONE},
 {0x374117,SA,0,NONE}, {0x365934,SA,0,GOTO_UP}, {0x36b129,SA,0,NONE},  {0x180d,RC5,13,NONE},
 {0x1811,RC5,13,NONE}, {0x1810,RC5,13,NONE},  {0x377111,SA,0,NONE}, {0x36f121,SA,0,NONE},
 {0x36213b,SA,0,NONE}, {0x37f101,SA,0,NONE}
};

Okay let’s start from scratch with a complete sketch that illustrates my problem. I can compile the following code on my Windows PC using Arduino 1.0.4 with no errors.

#include <PROGMEMAnything.h>
struct My_Struct{
  long Value;
  byte Bits;//number of bits to send
};
My_Struct PROGMEM My_Array_Of_Struct[]= {
 {0x12345678, 01}, {0xabcd1234,02}, {0x1234abcd,03}
};
My_Struct Particular_Struct;
void setup() {
  Particular_Struct=PROGMEMAnything (&My_Array_Of_Struct[1]);
};
void loop() {
};

However if I compile it on my Raspberry Pi using Arduino 1.0.4 I get the following error

pgmany_bug.ino:6:38: error: variable My_Array_Of_Struct must be const in order to be put into read-only section by means of __attribute__((progmem))

if I modify the code as follows…

const My_Struct PROGMEM My_Array_Of_Struct[]= {

I get the following message on Raspberry Pi…

In file included from pgmany_bug.ino:1:0:
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h: In instantiation of ‘T PROGMEMAnything(T*) [with T = const My_Struct]’:
pgmany_bug.ino:11:60:   required from here
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h:17:7: error: uninitialized const ‘result’ [-fpermissive]
pgmany_bug.ino:2:8: note: ‘const struct My_Struct’ has no user-provided default constructor
pgmany_bug.ino:3:8: note: and the implicitly-defined constructor does not initialize ‘long int My_Struct::Value’
In file included from pgmany_bug.ino:1:0:
/home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h:18:5: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
In file included from /home/pi/arduino-1.0.4/hardware/arduino/cores/arduino/Arduino.h:8:0,
                 from /home/pi/arduino-1.0.4/libraries/PROGMEMAnything/PROGMEMAnything.h:4,
                 from pgmany_bug.ino:1:
/usr/lib/gcc/avr/4.7.2/../../../avr/include/avr/pgmspace.h:1040:14: error:   initializing argument 1 of ‘void* memcpy_P(void*, const void*, size_t)’ [-fpermissive]

The problem appears to be a difference in compiler versions. The latest Windows Arduino 1.0.4 distribution uses avr-gcc 4.3.2 WinAVR 20081205.
However my Raspberry Pi is running avr-gcc 4.7.2. That is the current version which you get when you do “sudo apt-get install avr-libc” on Raspberry Pi Rasabiln “wheezy” 2013-20-09 which is the current version. I also note that the latest Arduino 1.0.4 is based on WinAVR 20081205 however the most recent version of WinAVR at Source Forge is listed as 2010011. So I’m surprised that the official Arduino for Windows IDE is using such an old compiler and such an old WinAVR… But that’s slightly off-topic. It still doesn’t tell me what I need to do to get rid of that error on the Raspberry Pi version and to do so in a way that the sketch can be compiled either there or on my Windows machine and/or presumably any other platform was Arduino IDE.

Please help!

I’m sitting on the sidelines here, watching with interest, since I have a project that I will eventually want to store character strings for menus in progmem. I’ve done some google searching and I think you might be on the right track with looking at the avr-gcc version. I seem to remember reading somewhere (posted somewhen) about some progmem methods being depreciated. I have a similar issue with an example for a phi-panel backpack that uses progmem that compiles w/o issue on 1.0.4ERW, but not on ArduinoDroid and I don’t have anything useful to give ArduinoDroid’s author about the issue. If you track the issue down, please keep us updated here.