‘__attribute__((progmem))’ Error when compiling code for arduino uno

Hi fellow Arduino enthusiasts,

I’m building the Twitter Mood Light project with the help of Instructables.com (http://www.instructables.com/id/Twitter-Mood-Light-The-Worlds-Mood-in-a-Box/?ALLSTEPS). I tried running the existing code for this project from that website, but I get this weird error:

error: variable ‘string_0’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

This happens to 6 other string variables like string_0 named string_1 through string_6.

Finally, I get this other error on the very last line of the console and it says the following:

error: variable ‘searchStrings’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

I’m a beginner when it comes to arduino programming. Can anyone explain what’s happening here exactly? And how will I be able to correct this code?

Here’s all the code I’m working with:

#include <HtmlParser.h>
#include <TwitterParser.h>
#include <string.h>
#include <WiFly.h>
#include <WorldMood.h>
#include <LED.h>
#include <avr/pgmspace.h>


// LED setup - only some pins provide 8-bit PWM (Pulse-width modulation)
// output with the analogWrite() function. 
// http://www.arduino.cc/en/Main/ArduinoBoardDuemilanove
// PWM: 3,5,6,9,10,11
#define redPin    (3)
#define greenPin  (5)
#define bluePin   (6)

// delay in ms between fade updates
// max fade time = 255 * 15 = 3.825s
#define fadeDelay (15)

// Wifi setup
#define network ("Kumar24G")
#define password ("4162940067")
#define remoteServer ("twitter.com")

const char* moodNames[NUM_MOOD_TYPES] = {
  "love",
  "joy",
  "surprise",
  "anger",
  "envy",
  "sadness",
  "fear",
};

const char* moodIntensityNames[NUM_MOOD_INTENSITY] = {
  "mild",
  "considerable",
  "extreme",
};

// the long term ratios between tweets with emotional content
// as discovered by using the below search terms over a period of time.
float tempramentRatios[NUM_MOOD_TYPES] = {
  0.13f,
  0.15f,
  0.20f,
  0.14f,
  0.16f,
  0.12f,
  0.10f,
};

// these numbers can be tweaked to get the system to be more or less reactive
// to be more or less susceptible to noise or short term emotional blips, like sport results 
// or bigger events, like world disasters 
#define  emotionSmoothingFactor (0.1f)
#define  moodSmoothingFactor (0.05f)
#define  moderateMoodThreshold (2.0f)
#define  extremeMoodThreshold (4.0f)

// save battery, put the wifly to sleep for this long between searches (in ms)
#define SLEEP_TIME_BETWEEN_SEARCHES (1000 * 5) 

// Store search strings in flash (program) memory instead of SRAM.
// http://www.arduino.cc/en/Reference/PROGMEM
// edit TWEETS_PER_PAGE if changing the rpp value
prog_char string_0[] PROGMEM = "GET /search.json?q=\"i+love+you\"+OR+\"i+love+her\"+OR+\"i+love+him\"+OR+\"all+my+love\"+OR+\"i'm+in+love\"+OR+\"i+really+love\"&rpp=30&result_type=recent";
prog_char string_1[] PROGMEM = "GET /search.json?q=\"happiest\"+OR+\"so+happy\"+OR+\"so+excited\"+OR+\"i'm+happy\"+OR+\"woot\"+OR+\"w00t\"&rpp=30&result_type=recent";
prog_char string_2[] PROGMEM = "GET /search.json?q=\"wow\"+OR+\"O_o\"+OR+\"can't+believe\"+OR+\"wtf\"+OR+\"unbelievable\"&rpp=30&result_type=recent";
prog_char string_3[] PROGMEM = "GET /search.json?q=\"i+hate\"+OR+\"really+angry\"+OR+\"i+am+mad\"+OR+\"really+hate\"+OR+\"so+angry\"&rpp=30&result_type=recent";
prog_char string_4[] PROGMEM = "GET /search.json?q=\"i+wish+i\"+OR+\"i'm+envious\"+OR+ \"i'm+jealous\"+OR+\"i+want+to+be\"+OR+\"why+can't+i\"+&rpp=30&result_type=recent";
prog_char string_5[] PROGMEM = "GET /search.json?q=\"i'm+so+sad\"+OR+\"i'm+heartbroken\"+OR+\"i'm+so+upset\"+OR+\"i'm+depressed\"+OR+\"i+can't+stop+crying\"&rpp=30&result_type=recent";
prog_char string_6[] PROGMEM = "GET /search.json?q=\"i'm+so+scared\"+OR+\"i'm+really+scared\"+OR+\"i'm+terrified\"+OR+\"i'm+really+afraid\"+OR+\"so+scared+i\"&rpp=30&result_type=recent";

// be sure to change this if you edit the rpp value above
#define TWEETS_PER_PAGE (30)

PROGMEM const char *searchStrings[] = 	   
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
  string_5,
  string_6,
};

void setup()
{
  Serial.begin(9600);
  delay(100); 
}

void loop()
{
  // create and initialise the subsystems  
  WiFly wifly(network, password, SLEEP_TIME_BETWEEN_SEARCHES, Serial);
  WorldMood worldMood(Serial, emotionSmoothingFactor, moodSmoothingFactor, moderateMoodThreshold, extremeMoodThreshold, tempramentRatios);
  LED led(Serial, redPin, greenPin, bluePin, fadeDelay);
  TwitterParser twitterSearchParser(Serial, TWEETS_PER_PAGE);

  wifly.Reset();
  
  char searchString[160]; 

  while (true)
  {
    for (int i = 0; i < NUM_MOOD_TYPES; i++)
    {
      twitterSearchParser.Reset();

      // read in new search string to SRAM from flash memory 
      strcpy_P(searchString, (char*)pgm_read_word(&(searchStrings[i]))); 

      bool ok = false;
      int retries = 0;

      // some recovery code if the web request fails
      while (!ok)
      {
        ok = wifly.HttpWebRequest(remoteServer, searchString, &twitterSearchParser);

        if (!ok)
        {
          Serial.println("HttpWebRequest failed");

          retries++;
          if (retries > 3)
          {
            wifly.Reset();
            retries = 0;
          }
        }
      }

      float tweetsPerMinute = twitterSearchParser.GetTweetsPerMinute();

      // debug code
      Serial.println("");
      Serial.print(moodNames[i]);
      Serial.print(": tweets per min = ");
      Serial.println(tweetsPerMinute);

      worldMood.RegisterTweets(i, tweetsPerMinute);
    }

    MOOD_TYPE newMood = worldMood.ComputeCurrentMood();
    MOOD_INTENSITY newMoodIntensity = worldMood.ComputeCurrentMoodIntensity();

    Serial.print("The Mood of the World is ... ");
    Serial.print(moodIntensityNames[(int)newMoodIntensity]);
    Serial.print(" ");
    Serial.println(moodNames[(int)newMood]);

    led.SetColor((int)newMood, (int)newMoodIntensity);

    // save the battery
    wifly.Sleep();

    // wait until it is time for the next update
    delay(SLEEP_TIME_BETWEEN_SEARCHES);

    Serial.println("");
  }
}

What version of the IDE are you using?
Which Arduino are you compiling for?
What operating system?

Version of the IDE: 1:1.0.5+dfsg2-2
Arduino: Uno R3
OS: Ubuntu 14.04 LTS

prog_char string_0[] PROGMEM = "GET /search.json?q=\"i+love+you\"+OR+\"i+love+her\"+OR+\"i+love+him\"+OR+\"all+my+love\"+OR+\"i'm+in+love\"+OR+\"i+really+love\"&rpp=30&result_type=recent";

I don't see const in there, anywhere.

error: variable ‘string_0’ must be const in order to be put into read-only section by means of ‘attribute((progmem))’

Not surprisingly, the compiler can't either.

Thanks Paul. I added the "const" keyword after prog_char and the error went away. However, the very last error still persists and I see the "const" keyword in front of *searchStrings.

WorldMood.ino:97:35: error: variable ‘searchStrings’ must be const in order to be put into read-only section by means of ‘__attribute__((progmem))’

I added the "const" keyword after prog_char and the error went away.

After the type, but before PROGMEM, right?

This cut-down version compiles OK for me under Ubuntu IDE 1.0.5:

// Store search strings in flash (program) memory instead of SRAM.
// http://www.arduino.cc/en/Reference/PROGMEM
// edit TWEETS_PER_PAGE if changing the rpp value
prog_char string_0[] PROGMEM = "GET /search.json?q=\"i+love+you\"+OR+\"i+love+her\"+OR+\"i+love+him\"+OR+\"all+my+love\"+OR+\"i'm+in+love\"+OR+\"i+really+love\"&rpp=30&result_type=recent";
prog_char string_1[] PROGMEM = "GET /search.json?q=\"happiest\"+OR+\"so+happy\"+OR+\"so+excited\"+OR+\"i'm+happy\"+OR+\"woot\"+OR+\"w00t\"&rpp=30&result_type=recent";
prog_char string_2[] PROGMEM = "GET /search.json?q=\"wow\"+OR+\"O_o\"+OR+\"can't+believe\"+OR+\"wtf\"+OR+\"unbelievable\"&rpp=30&result_type=recent";
prog_char string_3[] PROGMEM = "GET /search.json?q=\"i+hate\"+OR+\"really+angry\"+OR+\"i+am+mad\"+OR+\"really+hate\"+OR+\"so+angry\"&rpp=30&result_type=recent";
prog_char string_4[] PROGMEM = "GET /search.json?q=\"i+wish+i\"+OR+\"i'm+envious\"+OR+ \"i'm+jealous\"+OR+\"i+want+to+be\"+OR+\"why+can't+i\"+&rpp=30&result_type=recent";
prog_char string_5[] PROGMEM = "GET /search.json?q=\"i'm+so+sad\"+OR+\"i'm+heartbroken\"+OR+\"i'm+so+upset\"+OR+\"i'm+depressed\"+OR+\"i+can't+stop+crying\"&rpp=30&result_type=recent";
prog_char string_6[] PROGMEM = "GET /search.json?q=\"i'm+so+scared\"+OR+\"i'm+really+scared\"+OR+\"i'm+terrified\"+OR+\"i'm+really+afraid\"+OR+\"so+scared+i\"&rpp=30&result_type=recent";

PROGMEM const char *searchStrings[] = 	   
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
  string_5,
  string_6,
};

void setup ()
  {
  Serial.begin (115200);
  Serial.println ();

  }  // end of setup

void loop ()
  {
  char searchString[160]; 
  // read in new search string to SRAM from flash memory 
  strcpy_P(searchString, (char*)pgm_read_word(&(searchStrings[0]))); 
  Serial.print (searchString);
  }  // end of loop

However try downloading Ubuntu IDE 1.0.6 which did fix a couple of PROGMEM problems for me elsewhere.

Sorry to keep you hanging guys.

Paul: Yes, I added the "const" after the type and before PROGMEM like so:

prog_char const string_0[] PROGMEM

Nick: I'll try downloading 1.06 and see if that works.

Thanks!

prog_char is already PROGMEM:

typedef char PROGMEM prog_char;

Paul: Yes, I added the "const" after the type and before PROGMEM like so:

But, where did you put const in the other line that causes problems?

See other thread about this code: http://forum.arduino.cc/index.php?topic=269987