Yún Memory Issues

Hi Forum,
I am working on an Arduino project on the Arduino Yún that involves many different tweets that must be tweeted in order. Many of these tweets are long (as far as a tweet goes) and I found that I ran out of memory. I expanded the Yún disk space, following the instructions from this tutorial, but still found that I ran out of memory. This is the error message:

Sketch uses 16,814 bytes (58%) of program storage space. Maximum is 28,672 bytes.
Global variables use 2,620 bytes (102%) of dynamic memory, leaving -60 bytes for local variables. Maximum is 2,560 bytes.
processing.app.debug.RunnerException: Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.
	at processing.app.Sketch.size(Sketch.java:1679)
	at processing.app.Sketch.build(Sketch.java:1589)
	at processing.app.Sketch.exportApplet(Sketch.java:1610)
	at processing.app.Sketch.exportApplet(Sketch.java:1596)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2392)
	at java.lang.Thread.run(Thread.java:745)
Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint.

I am completely confused because I formatted a 32GB SD CARD so that roughly 1/3 of it (10.3G) is partitioned. When I type df -h / /mnt/sda1 after connecting to the Yún through terminal I see this:

Filesystem Size Used Available Use% Mounted on
rootfs 18.9G 46.3M 17.9G 0% /
/dev/sda1 10.3G 24.0K 10.3G 0% /mnt/sda1

Shouldn't I have 10.3G to use. I may have many tweets but I know for sure that they would definitely not take up more that than 10.3GBs!!! What is going on!!!! Please respond quickly!!! :fearful:

Thanks,
ma7730

You have run out of RAM inside the 32U4 Arduino processor. The SD card is connected to the AR3391 processor. They are completely different animals. Even if the SD card was attached to the Arduino processor, it wouldn't matter what size card you had. RAM memory is independent of SD disk space.

Post your code and we will probably have ways to help you save memory. This may be as simple as using the F() macro to put your long strings in flash (program memory) or perhaps the tweeting portion (and those long strings) can be moved onto the AR3391 Linux processor which has much more space (as well as direct access to the SD card.)

Thanks for the help. The code is pasted here. This file does not use up all the memory but there is another short file with some variables so that the entire sketch has negative memory left.

#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h" // contains Temboo account information, as described below

int quoteCounter = 1;   // Execution count, so this doesn't run forever
int maxRuns = 26;   // Maximum number of times the Choreo should be executed

//tweets 1-26 are defined up here
void setup() {
  Serial.begin(9600);
  
  // For debugging, wait until the serial console is connected.
  delay(4000);
  while(!Serial);
  Bridge.begin();
}

void loop() {
  String tweets[] = {tweet1, tweet2, tweet3, tweet4, tweet5, tweet6, tweet7, tweet8, tweet9, tweet10, tweet11, tweet12, tweet14, tweet15, tweet16, tweet17, tweet18, tweet19, tweet20, tweet21, tweet22, tweet23, tweet24, tweet26};
  if (quoteCounter <= maxRuns) {
  
    Serial.println("Running StatusesUpdate - Run #" + String(quoteCounter));
    
    TembooChoreo StatusesUpdateChoreo;

    // Invoke the Temboo client
    StatusesUpdateChoreo.begin();
    
    // Set Temboo account credentials
    StatusesUpdateChoreo.setAccountName(TEMBOO_ACCOUNT);
    StatusesUpdateChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
    StatusesUpdateChoreo.setAppKey(TEMBOO_APP_KEY);
    
    // Set Choreo inputs
    StatusesUpdateChoreo.addInput("AccessToken", ACESSTOKEN);
    StatusesUpdateChoreo.addInput("AccessTokenSecret", ACESSTOKENSECRET);
    StatusesUpdateChoreo.addInput("ConsumerSecret", CONSUMERSECRET);
    StatusesUpdateChoreo.addInput("StatusUpdate", tweets[quoteCounter]);
    StatusesUpdateChoreo.addInput("ConsumerKey", "ONSUMERKEY);
    
    // Identify the Choreo to run
    StatusesUpdateChoreo.setChoreo("/Library/Twitter/Tweets/StatusesUpdate");
    
    // Run the Choreo; when results are available, print them to serial
    StatusesUpdateChoreo.run();
    
    while(StatusesUpdateChoreo.available()) {
      char c = StatusesUpdateChoreo.read();
      Serial.print(c);
    }
    StatusesUpdateChoreo.close();
    quoteCounter++;
  }

  Serial.println("Waiting...");
  delay(30000); // wait 30 seconds between StatusesUpdate calls
}

Also: THE CODE DOESN'T WORK! I don't understand why. I just took it from the statusupdate_sketch Temboo example which works. All I did was add a counter! Please, how do I get it to work?
Thanks,
ma7730

Please define "it doesn't work." That could mean just about anything.

I haven't studied the whole sketch, but this line jumps out at me:

StatusesUpdateChoreo.addInput("ConsumerKey", "ONSUMERKEY);

It looks like you've overwritten a C character with a quote character. That will never compile.

And how many different threads are you going to start for this same sketch topic? You had one in December, and now you've started another one since then. Having so many threads talking about the same sketch is confusing.

If you ran out of ram on the Arduino side then you should consider doing this program on the linux side (64 MB ram) with python script or another language.

@ShapeShifter
It's not because of that otherwise it wouldn't compile. Also where I put that I have my actual consumer key so that's not the problem. The thing is the sketch compiles and uploads but does absolutely nothing.
I started this new one because the problem wasn't solved and nobody was responding for a while and I thought if I said something on it, nobody would see it.
@mart256
How do you do that? Is there a tutorial.

Thanks so much for all your help, I really do appreciate it,
ma7730

ma7730:
@ShapeShifter
It's not because of that otherwise it wouldn't compile. Also where I put that I have my actual consumer key so that's not the problem. The thing is the sketch compiles and uploads but does absolutely nothing.
I started this new one because the problem wasn't solved and nobody was responding for a while and I thought if I said something on it, nobody would see it.
@mart256
How do you do that? Is there a tutorial.

Thanks so much for all your help, I really do appreciate it,
ma7730

Well, you know how to access to the linux side right? (via ssh)
Once inside linux machine, you can create a linux script with nano text editor:

nano helloWorld.py

The code

print "Hello world"

Exit editor and execute

python helloWorld.py

Then you can write more complex python code, there are many tutorials to learn python and doing scripts for servers.

ma7730:
I started this new one because the problem wasn't solved and nobody was responding for a while and I thought if I said something on it, nobody would see it.

Actually, as soon as anyone posts on a thread, it moves to the top of the list, just like a new topic. An old thread with new posts is just as visible as a new thread. In fact, it may be more visible: many people, like me, set up the forum options to notify us of new posts in threads we are following. Posting in an old thread makes your post more visible to these people, not less. And, it's a lot less confusing, especially since we now have similar conversations going on in two active threads.

@Shapeshifter: Oh, I'm sorry, I actually didn't know. I thought the threads were listed by date of creation so after some time can't expect anyone to see it. I'll make sure to keep using this thread. Thanks! I'd deactivate the other threads, is there a way?
@mart256: Yes, I know how to access the Yún over ssh. After I've created a file usisng the touch command I try to edit it by typing "nano test.py " The response is "-ash: nano: not found"
Thanks for your help,
ma7730

Also, if i try to upload the sketch on on of the USB ports it get's stuck in the uploading phase and if I try to upload it on the other absolutely nothing happens and Arduino crashes. Is this from the lack of memory available, because I tired with the Blink example sketch and on both ports it can't get past the "Uploading" stage.

Thanks,
ma7730

@shapeshift, I researched the F() macro and added it into the array and it does reduce the amount of memory used.
The problem is the tweeting no longer works. In the Serial Monitor is displays

0...
Success! Tweet sent!
Waiting...

Where it should have said

Running SendATweet - Run #0 ....
Success! Tweet sent!
Waiting...

Also, before if I tried just using three of the quotes from the array it would tweet them in order but since adding the F() macron it doesn't tweet anything. Is there a way to fix this?
Thanks,
ma7730

Here is the full code:

#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h" // contains Temboo account information
#include <avr/pgmspace.h> //this is for the F() and PROGMEM

//tweets 1-24 are defined up here; no need to put them in here


int numRuns = 0;   // execution count, so this sketch doesn't run forever //1
int maxRuns = 24;  // the max number of times the Twitter Update Choreo should run //3?

 

void setup() {
  Serial.begin(9600);

  // for debugging, wait until a serial console is connected
  delay(4000);
  while(!Serial);

  Bridge.begin();
}

void loop()
{
   String tweets[]  = {F(tweet1), F(tweet2), F(tweet3), F(tweet4) , F(tweet5), F(tweet6), F(tweet7), F(tweet8), F(tweet9), F(tweet10),F(tweet11), F(tweet12), F(tweet13), F(tweet14) , F(tweet15), F(tweet16), F(tweet17), F(tweet18), F(tweet19), F(tweet20), F(tweet21), F(tweet22), F(tweet23), F(tweet24)};
  //int nums[] = {1, 2, 3};     //just a testing array

  //the real array
  //must I put this outside???
 
  if (numRuns <= maxRuns) {
  
    Serial.println("Running SendATweet - Run #" + String(numRuns) + "...");

  
    // define the text of the tweet we want to send
   String tweetText = String(tweets[numRuns]);

    
    TembooChoreo StatusesUpdateChoreo;

    // invoke the Temboo client
    // NOTE that the client must be reinvoked, and repopulated with
    // appropriate arguments, each time its run() method is called.
    StatusesUpdateChoreo.begin();
    
    // set Temboo account credentials
    StatusesUpdateChoreo.setAccountName(TEMBOO_ACCOUNT);
    StatusesUpdateChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
    StatusesUpdateChoreo.setAppKey(TEMBOO_APP_KEY);

    // identify the Temboo Library choreo to run (Twitter > Tweets > StatusesUpdate)
    StatusesUpdateChoreo.setChoreo("/Library/Twitter/Tweets/StatusesUpdate");
 
    // add the Twitter account information
    StatusesUpdateChoreo.addInput("AccessToken", AccessToken);
    StatusesUpdateChoreo.addInput("AccessTokenSecret", AccessTokenSecret);
    StatusesUpdateChoreo.addInput("ConsumerKey", ConsumerKey);    
    StatusesUpdateChoreo.addInput("ConsumerSecret", ConsumerSecret);

    // and the tweet we want to send
    StatusesUpdateChoreo.addInput("StatusUpdate", tweetText);

    // tell the Process to run and wait for the results. The 
    // return code (returnCode) will tell us whether the Temboo client 
    // was able to send our request to the Temboo servers
    unsigned int returnCode = StatusesUpdateChoreo.run();

    // a return code of zero (0) means everything worked
    if (returnCode == 0) {
        Serial.println("Success! Tweet sent!");
    } else {
      // a non-zero return code means there was an error
      // read and print the error message
      while (StatusesUpdateChoreo.available()) {
        char c = StatusesUpdateChoreo.read();
        Serial.print(c);
      }
    } 
    //StatusesUpdateChoreo.close();
     numRuns++;
    // do nothing for the next 90 seconds
    Serial.println("Waiting...");
    delay(15000);    //this may have to be larger to avoid 403 error
     
  }
  else{
   numRuns = 0;
   delay(50000);  //THIS is what should be larger - space between different "sessions"
  }
}

UPDATE: It might not be because of the F() macro. It's strange because when I tried it with just 3 tweets it all worked perfect but then I tried it with 10 tweet, without the macro, and it did the same thing as above. Then I tried it with the nums testing array but with 1-10 and it worked fine.

Another Update: I did absolutely nothing and no all of the sudden when I try to run the sketch it compiles but this is what I get in the Serial Monitor:

Running SendATweet - Run #0...
Error
A Step Error has occurred: "An input error has occurred. ConsumerKey, ConsumerSecret, AccessToken, AccessTokenSecret, and StatusUpdate are required.".  The error occurred in the Stop (Input error) step.
HTTP_CODE
500
Waiting...

What is going on?

ma7730

ma7730:
I'd deactivate the other threads, is there a way?

It can only be done by a moderator. Us mere mortals don't have access to those functions.

  String tweets[]  = {F(tweet1), F(tweet2), F(tweet3), F(tweet4) , F(tweet5), F(tweet6), F(tweet7), F(tweet8), F(tweet9), F(tweet10),F(tweet11), F(tweet12), F(tweet13), F(tweet14) , F(tweet15), F(tweet16), F(tweet17), F(tweet18), F(tweet19), F(tweet20), F(tweet21), F(tweet22), F(tweet23), F(tweet24)};

While the F() keeps the strings in program memory, and doesn't copy them to RAM like normal strings are copied, I don't think this construct will work.

The 32U4 has discrete address spaces for data and code. Special methods are needed to access data out of program memory. The F() macro puts the strings in program memory, but I think then putting them in the array makes the code think they are in data memory. Someone with more experience with this processor will have to speak to the best way to do this. (I have 30+ years of embedded programming experience, but I am very new with Arduino, and this is an issue that's specific to this processor family.) Basically, you need a proper way to get the data from program memory into the string.

 //the real array
  //must I put this outside???

Not "must" but "should." Declaring that array there, it is put on the stack and set up/torn down on each invocation of loop(). Making it global will statically allocate it once and set it up once. Much more efficient. However, I'm not sure if declaring that array of strings (in RAM) will just make a copy of all of the strings anyway, eliminating the benefit of the F() macro. If it's globally defined (statically allocated) it will show up in the memory usage message displayed after a build. If it's on the stack (defined inside loop()) it won't show up in that message, but will still take runtime memory. Perhaps that's why you still get crashes?

Like I said before, it requires some research. Hopefully someone with more experience of how F() and PROGMEM works will speak up. In the mean time, do some reading on those two topics and see if you can figure it out.

If I were writing this application, I would take all of the tweet string out of the sketch. On the Linux side I would write a Python script that defines all of the strings, and accepts a parameter that indicates a string index number. The script would then print the selected string. On the Arduino side, when it's time to send a tweet, use the Process class to call the Python script, passing in the desired index, and reading the return string. This way, only one string us ever in the 32U4 memory at one time. At least that's the way I would do it - completely bypass the memory issues.

As to your latest error message, that sounds like Temboo is not liking something in the authorization data you gave it. Either you accidentally changed something in the code, or they are having server issues, or there are some communications issues. That's my best guess.

If I put the String Array outside of the void loop with the F() macro I get this an error.

I will try your way, but, like I asked Mart256, how/where do I create/edit the file. If I connect to the Yún in terminal and try the nano command it says -ash:nano: command not found.
Thanks,
ma7730

The error:

Arduino: 1.5.8 (Mac OS X), Board: "Arduino Yún"

Build options changed, rebuilding all
Using library Bridge in folder: /Applications/Arduino.app/Contents/Resources/Java/libraries/Bridge 
Using library Temboo in folder: /Applications/Arduino.app/Contents/Resources/Java/libraries/Temboo 

/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega32u4 -DF_CPU=16000000L -DARDUINO=158 -DARDUINO_AVR_YUN -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x8041 -DUSB_MANUFACTURER= -DUSB_PRODUCT="Arduino Yun" -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino -I/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/variants/yun -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Bridge/src -I/Applications/Arduino.app/Contents/Resources/Java/libraries/Temboo/src /var/folders/xp/pylhclxs4_d6d08cbt4ttjzh0000gn/T/build9156446877167087242.tmp/TweetingInSucession.cpp -o /var/folders/xp/pylhclxs4_d6d08cbt4ttjzh0000gn/T/build9156446877167087242.tmp/TweetingInSucession.cpp.o 
In file included from /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/Arduino.h:28:0,
                 from /Applications/Arduino.app/Contents/Resources/Java/libraries/Bridge/src/Bridge.h:22,
                 from TweetingInSucession.ino:9:
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:25: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:36: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:47: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:58: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:70: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:81: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:93: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:105: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:117: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:128: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
TweetingInSucession.ino:55:139: note: in expansion of macro 'F'
/Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/avr/cores/arduino/WString.h:38:74: error: statement-expressions are not allowed outside functions nor in template-argument lists
 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
                                                                          ^
=
TweetingInSucession.ino:55:330: note: in expansion of macro 'F'
Error compiling.

I thought it was standard, but perhaps nano needs to be installed. Make sure your Yun has a network connection that can go out to the Internet, then from a SSH session type:

opkg update
opkg install nano

I think writing the Python code and interfacing to it from the Arduino side will be a good learning experience. Especially if you want your list of possible tweets to get really long.

On the other hand, I've done a little research. It didn't take much time with Google to turn up a bunch of links talking about F() and PROGMEM. The discussion quickly led me to this page, which you should read carefully a few times until it starts to sink in (it's not an easy subject): Arduino Reference - PROGMEM

If you look at the bottom of the page, there is a section titled "Array of strings" which includes some sample code. This is very much your application, except that you want to send the string as a tweet while this one just prints it out.

Looking at the code, it has includes:

  • A bunch of introductory comments.
  • A list of individual string definitions. These use character arrays in program memory, rather than string objects. It's more efficient this way. Using the PROGMEM modifier and using the type prog_char instead of char makes the compiler place these strings only in program memory. You will want to create more of these strings, one for each of your tweet phrases.
  • The next thing it does is set up string_table[], a constant array of pointers to characters, and initializes it with the strings. So you end up with an array of pointers, with each one pointing to an array of characters in program memory. Note that the array size is empty in this declaration: that means that the compiler will automatically make it the size necessary to hold everything in the initializaer list (which you will have to update to include all of the tweets you defined in the previous block of definitions.)
  • Next, there is the definition of buffer. This is a simple character array in RAM. It is a workspace to hold the current tweet your are processing. The sample defines it as 30 characters, you will have to make that larger so that it holds your longest tweet. (Doesn't Twitter impose a limit of 160 characters for a tweet? Make it at least 161 to be able to hold a trailing NULL character.) You will have to explicitly state the size of this array, since there is no initalizer list and the compiler doesn't know what you are going to store there. Whatever size you use, make sure that NONE of your tweet strings are as long as that size: if just one string is even one character longer, it will overrun the end of the buffer and could either crash your sketch or make it do strange things.
  • setup() just sets up the serial port. You, of course, will do more in your sketch's setup().
  • The loop() function is where the real work is done. Read the introductory comment and understand it, keeping in mind that the data in PROGMEM is not directly accessible as data, and must be processed with special instructions. What this code is doing is calling strcpy_P() which is a special version of the strcpy() function. strcpy() copies arrays of characters (strings) from one location in RAM to another location in RAM. strcpy_P() copies arrays of characters from PROGMEM to RAM. Both functions expect a pointer to the destination as the first parameter, and a pointer to the source data as the second parameter. It will start copying data from the beginning of the string, and will stop when a terminating NULL character has been copied.

So, it requires some special declarations to put all of the string data in PROGMEM. Then, when you want to use one of the strings, it takes a special function to copy the data from PROGMEM into RAM where the data can be accessed by "normal" functions. In your code, once you get the desired string in the buffer variable, you should be able to tweet it directly by changing that line of your code to this:

   // and the tweet we want to send
    StatusesUpdateChoreo.addInput("StatusUpdate", buffer);

and there should then be no need for this bit of code:

   // define the text of the tweet we want to send
   String tweetText = String(tweets[numRuns]);

I agree with ShapeShifter that the best way to save memory on the 32U4 side is to make the AR3391 do the heavy string lifting, but if you want to do in Flash on the 32U4 side, you could write a function to pull the strings out of Flash and into a String. That way you will only have one string in RAM at a time. I put together a sample to show what I mean, using your strings and putting them in a text file as output:

#include <FileIO.h>

int index = 0;

void setup() {
  Bridge.begin(); // Initialize the Bridge
  FileSystem.begin();
}

void loop() {
  Process p;
   String nextTweet;
  nextTweet = getTweet(index++);
  File dataFile = FileSystem.open("/mnt/sd/test.txt", FILE_APPEND);

  if (dataFile) {
    dataFile.println(nextTweet);
    dataFile.close();
  }  

  delay(5000);  // wait 5 seconds before you do it again
}

String getTweet(int index) {
   char newTweet[120];
   
   switch(index) {
      case 0:  strcpy_P(newTweet, PSTR("1949 - Mao becomes Chairman")); break;
      case 1:  strcpy_P(newTweet, PSTR("1949 - Mao convinces Stalin to sign a treaty for economic aid #sucess")); break;
      case 2:  strcpy_P(newTweet, PSTR("1956 -  Mao encourages 'a hundred flowers to bloom', telling intellectuals to speak out")); break;
      case 3:  strcpy_P(newTweet, PSTR("Mao then imprisoned the intellectuals who spoke out for improvement")); break;
      case 4:  strcpy_P(newTweet, PSTR("1958 - Mao launches Great Leap Forward")); break;
      case 5:  strcpy_P(newTweet, PSTR("He encouraged people to set up 'people's communes' - dissolving private property")); break;
      case 6:  strcpy_P(newTweet, PSTR("People did not have resources or administration to manage such large social units")); break;
      case 7:  strcpy_P(newTweet, PSTR("In an effort to please Mao party officials left very little grain for people, most of it sent to the government")); break;
      case 8:  strcpy_P(newTweet, PSTR("'Backyard steel' created in an attempt to rapidly industrialize China was useless and consumed resources.")); break;
      case 9:  strcpy_P(newTweet, PSTR("30 million starved")); break;
      case 10: strcpy_P(newTweet, PSTR("1959 - Mao realizes change is needed.")); break;
      case 11: strcpy_P(newTweet, PSTR("1966 - The Great Proletariat Cultural Revolution")); break;
      case 12: strcpy_P(newTweet, PSTR("Called for students to become 'Red Guards', a group of Mao followers dedicated to his idea for China")); break;
      case 13: strcpy_P(newTweet, PSTR("Red Guards rampaged through cities to destroy Four Olds")); break;
      case 14: strcpy_P(newTweet, PSTR("Four Olds - Old Customs, Old Culture, Old Habits, and Old Ideas")); break;
      case 15: strcpy_P(newTweet, PSTR("Red Guards attacked and humiliated people from 'bad class status' - intellectuals or wealthy")); break;
      case 16: strcpy_P(newTweet, PSTR("Private property was invaded by Red Guards and trashed")); break;
      case 17: strcpy_P(newTweet, PSTR("This created great chaos, violence, injury and death #unsuccessful")); break;
      case 18: strcpy_P(newTweet, PSTR("1966 - Mao Zhuxi Yulu, often known as the #Little_Red_Book, was published")); break;
      case 19: strcpy_P(newTweet, PSTR("Mao's quotes were the unchallenged rules the by which Chinese lived")); break;
      case 20: strcpy_P(newTweet, PSTR("August 1966 - Culture - Lao She, a famous playwright, is beaten to death by Red Guards")); break;
      case 21: strcpy_P(newTweet, PSTR("Culture - All art supposed to be #propaganda for Mao")); break;
      case 22: strcpy_P(newTweet, PSTR("1972 - Nixon Visits China")); break;
      case 23: strcpy_P(newTweet, PSTR("Despite differences Mao can negotiate with US to China's advantage")); break;
      case 24: strcpy_P(newTweet, PSTR("US agrees to aid China if Taiwan tries to take power")); break;
      case 25: strcpy_P(newTweet, PSTR("US used to support Taiwan, Mao made China a more valuable ally")); break;
      case 26: strcpy_P(newTweet, PSTR("The end result: 1.5 million murdered, a million more tortured, imprisoned, humiliated or robbed of property.")); break;
      default: strcpy_P(newTweet, PSTR("Index out of range")); break;
   }
   String strTweet(newTweet);   // convert char array to String object
   return strTweet;
}

@Shapeshifter: Thank you so much for all your help. You have been so kind to help me all the way through. I think I have solved the problem. Temboo has something they call "profiles" where one can store all the necessary info for an api call at Temboo so it doesn't take up any space on the Arduino.
Thank you so much and thanks for putting up with me this whole time,
ma7730