Problems with PROGMEM

Adafruit cellular platform - SMS and IoT over celluar

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
mhagerth
 
Posts: 9
Joined: Tue Feb 28, 2017 6:03 am

Problems with PROGMEM

Post by mhagerth »

Hello:

This post is concerned with the code specifically in the Adafruit geofencing sample at https://github.com/openhomeautomation/a ... ing_io.ino. Specifically it has the following block of code, which just sets up the mqtt variables in PROGMEM.

Code: Select all

// Adafruit IO configuration
#define AIO_SERVER           "io.adafruit.com"  // Adafruit IO server name.
#define AIO_SERVERPORT       1883  // Adafruit IO port.
#define AIO_USERNAME         "your-adafruit-io-name"  // Adafruit IO username (see http://accounts.adafruit.com/).
#define AIO_KEY              "your-adafruit-io-key"  // Adafruit IO key (see settings page at: https://io.adafruit.com/settings).

const char MQTT_SERVER[] PROGMEM    = AIO_SERVER;
const char MQTT_USERNAME[] PROGMEM  = AIO_USERNAME;
const char MQTT_PASSWORD[] PROGMEM  = AIO_KEY;

// Setup the FONA MQTT class by passing in the FONA class and MQTT server and login details.
Adafruit_MQTT_FONA mqtt(&fona, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
However, whenever this code later tries to connect using MQTT you can see in the output that the server, io.adafruit.com, is missing... notice those empty quotes.
AT+CIPSTART="TCP","","1883"

However if I don't use PROGMEM and declare the mqtt with the next line everything works great.

Code: Select all

Adafruit_MQTT_FONA mqtt(&fona, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_KEY);
In the arduino reference on PROGMEM it states, "Using PROGMEM is also a two-step procedure. After getting the data into Flash memory, it requires special methods (functions), also defined in the http://www.nongnu.org/avr-libc/user-man ... space.html[pgmspace.h] library, to read the data from program memory back into SRAM, so we can do something useful with it."

I don't see any special methods reading the data here, so I am not quite sure how this is supposed to work. It would be great if it did, because my sketch is a little tight on memory. Has anybody else had problems with this code.

-Michael

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Problems with PROGMEM

Post by adafruit_support_mike »

What kind of microcontroller are you using?

PROGMEM only has a useful meaning for microcontrollers from the ATmega family. Devices like the ESP8266 and SAMD21 handle memory differently, so PROGMEM doesn't mean anything there.

User avatar
mhagerth
 
Posts: 9
Joined: Tue Feb 28, 2017 6:03 am

Re: Problems with PROGMEM

Post by mhagerth »

I'm using an Adafruit Metro Mini. Once I realized that an UNO was going to be too big for my project I started searching for a smaller controller. I tried a bunch of things that didn't work for whatever reason. I then bought a Metro Mini because of its high compatibility with UNO code and that did the trick, until this PROGMEM issue.

-Michael

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Problems with PROGMEM

Post by adafruit_support_mike »

The Metro Mini also uses the Tmega328 microcontroller, so that eliminates problems with PROGMEM working in general.

As long as you're using that chip, there's an easier way to move constants into Flash memory: the F() macro:

Code: Select all

Adafruit_MQTT_FONA mqtt( &fona, F(AIO_SERVER), AIO_SERVERPORT, F(AIO_USERNAME), F(AIO_KEY) );
There's a set of low-level definitions that handle the low-level details of putting the strings in Flash and getting them back. The strings never get associated with variables, so you can simply inline all the strings you want to shove out of RAM:

Code: Select all

Adafruit_MQTT_FONA mqtt( &fona, F("io.adafruit.com"), AIO_SERVERPORT, F("your-adafruit-io-name"), F("your-adafruit-io-key") );
The strings above aren't the best example because they contain information you probably want to keep in a well-know place like a #define block, but you can save a lot of RAM using F() for strings in Serial.print() statements.

User avatar
mhagerth
 
Posts: 9
Joined: Tue Feb 28, 2017 6:03 am

Re: Problems with PROGMEM

Post by mhagerth »

Unfortunately I get an error when I try either of those things. I guess because it is not inside a function, but rather declared with the rest of the globals? Otherwise the F() trick is a good idea. I did that early with all my Serial.print statements and that helped, but it is still tight.

error: statement-expressions are not allowed outside functions nor in template-argument lists

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Problems with PROGMEM

Post by adafruit_support_mike »

Yeah, you can't use the F() macro in the same place as your #defines. You don't need to do that though.

#defines and literals work differently from variables. A #define creates a cut-and-paste rule that's applied before the code ever goes to the compiler. The code you write like this:

Code: Select all

#define AIO_SERVER           "io.adafruit.com"  // Adafruit IO server name.
#define AIO_SERVERPORT       1883  // Adafruit IO port.
#define AIO_USERNAME         "your-adafruit-io-name"  // Adafruit IO username (see http://accounts.adafruit.com/).
#define AIO_KEY              "your-adafruit-io-key"  // Adafruit IO key (see settings page at: https://io.adafruit.com/settings).

void someFunction () {
    Adafruit_MQTT_FONA mqtt( &fona, F(AIO_SERVER), AIO_SERVERPORT, F(AIO_USERNAME), F(AIO_KEY) );
}
turns into this when it hits the compiler:

Code: Select all

void someFunction () {
    Adafruit_MQTT_FONA mqtt( &fona, F( "io.adafruit.com"), 1883, F("your-adafruit-io-name"), F("your-adafruit-io-key") );
}
which should be legal. Strictly speaking, the #defines aren't necessary. They only exist for convenience, so you can keep all the config information at the top of the file.

Locked
Please be positive and constructive with your questions and comments.

Return to “FONA”