Word Generator Project

Hello All,

New to the forums and am honestly a new programmer. I'm attempting to put together a word generation box for a friend (to play things like Pictionary and Catchphrase) but I've hit a couple dead ends.

In attempting to upload a long list I have hit memory road blocks in that even with 300 words I have nearly 100% Global variables used up.

Now after a lot of research I came upon these threads:
https://forum.arduino.cc/index.php?topic=409083.0
http://forum.arduino.cc/index.php?topic=45653.15

They suggest using EEPRAM, and as such I adopted into my code using the suggestions as a base. While I was able to have up to 10000 words with Wawa's code seen here
When I enter my list of words that are all underneath 8 characters the program barely can handle 300 hundred. For reference here is my code for the project as a whole.

#include <Wire.h>
#include "rgb_lcd.h"

rgb_lcd lcd;
const unsigned int numberofwords = 300;
const char * const wordlist[numberofwords] PROGMEM = {
"water",  "fuel", "soup", "shock",  "stew", "end",  "man",  "cart", "stone",  "title",  "deer", "duck", "kiss", "use",  "pleasure", "wax",  "cabbage",  "hope", "jail", "bee",
"hat",  "mom",  "crowd",  "interest", "horse",  "taste",  "quiet",  "spy",  "bit",  "look", "skin", "tax",  "flight", "stocking", "pin",  "idea", "mouth",  "actor",  "key",  "nut",
"rod",  "hour", "waste",  "yarn", "pies", "bone", "stick",  "trade",  "ball", "slope",  "thrill", "smell",  "mother", "crate",  "gold", "question", "cap",  "poison", "sort", "system",
"fog",  "window", "lettuce",  "space",  "shake",  "loss", "room", "trick",  "yam",  "mask", "art",  "care", "yak",  "desire", "bird", "library",  "glass",  "test", "boat", "match",
"vein", "zipper", "pipe", "cub",  "things", "toys", "fowl", "donkey", "carriage", "death",  "field",  "pan",  "motion", "clam", "voyage", "horses", "bag",  "way",  "grass",  "prose",
"recess", "group",  "maid", "rule", "jump", "vest", "flag", "thumb",  "shirt",  "texture",  "wind", "slip", "burst",  "spring", "throat", "cushion",  "border", "expert", "cream",  "pet",
"pets", "wren", "tail", "wool", "produce",  "partner",  "screw",  "beef", "letters",  "sound",  "friction", "eggs", "market", "kittens",  "harmony",  "rhythm", "plough", "hot",  "place",  "jewel",
"liquid", "cattle", "week", "spoon",  "ladybug",  "monkey", "party",  "cause",  "oatmeal",  "tooth",  "juice",  "edge", "ray",  "army", "value",  "attack", "business", "advert", "dime", "crow",
"mine", "turn", "shame",  "zephyr", "bait", "cemetery", "size", "tiger",  "waves",  "knee", "cobweb", "fact", "boy",  "icicle", "land", "cats", "action", "sign", "country",  "chew",
"snotty", "hushed", "chunky", "bloody", "thread", "range",  "innate", "left", "mountain", "sin",  "beef", "fasten", "birds",  "house",  "rhythm", "tight",  "hammer", "bait", "crow", "supreme",
"part", "tired",  "blush",  "sore", "sister", "abaft",  "living", "opposite", "nation", "erratic",  "remind", "mature", "fragile",  "home", "dislike",  "approve",  "destroy",  "roof", "bolt", "dam",
"fact", "fairies",  "disarm", "arrest", "frame",  "nippy",  "acidic", "puzzling", "wink", "teeth",  "support",  "shut", "cook", "join", "aloof",  "one",  "humdrum",  "lewd", "train",  "race",
"bucket", "turkey", "flagrant", "chin", "rainy",  "squeak", "grain",  "throat", "wound",  "button", "clumsy", "sack", "wakeful",  "swing",  "dime", "fit",  "fearful",  "oafish", "dog",  "birth",
"accurate", "regular",  "back", "rail", "trap", "enter",  "small",  "white",  "smile",  "mug",  "staking",  "breathe",  "spiky",  "ragged", "teaching", "reduce", "ten",  "shelter",  "fabulous", "medical",
"juvenile", "mine", "literate", "wax",  "stain",  "stone",  "rejoice",  "gratis", "develop",  "curvy",  "hot",  "verdant",  "current",  "zippy",  "sniff",  "wanting",  "pray", "snore",  "fearless", "camp",
};

unsigned int chance, chance2;
int colorR = 200, colorG = 25, colorB = 5;
int button = 3, mode = 0;
unsigned long Time = 0, Interval = 0;
const int potnum = 1;

void setup() 
{
    lcd.begin(16, 2);
    lcd.setRGB(colorR, colorG, colorB);

    pinMode(button, INPUT);
    pinMode(potnum, INPUT);
    
    chance = 0;
    chance2 = 0;
    lcd.clear();
    Time = 0;
    randomSeed(analogRead(7));
}

void loop() 
{
    static int pressed = 0;
    if (Interval == 10) {
        Time ++;
        Interval = 0;
    }
    mode = analogRead(potnum);
    
    int buttonState = digitalRead(button);
    if(buttonState == 1 && !pressed){
        lcd.clear();
        chance = random(1, numberofwords);
        chance2 = random(1, numberofwords);
        Time = 0;
    }
    pressed = buttonState;

    lcd.setCursor(0,0);
    char* Word1 = (char *) pgm_read_word (&wordlist [chance]);
    char* Word2 = (char *) pgm_read_word (&wordlist [chance2]);
    lcd.print(Word1);
    
    if (mode >= 500){
      lcd.setRGB(colorR, colorG, colorB);
      lcd.setCursor(0, 1);
      lcd.print(Word2);
    }
    else
    {
    lcd.setRGB(184, 195, 93);
    lcd.setCursor(0, 1);
    lcd.print("Time:");
    lcd.setCursor(8,1);
    lcd.print(Time);
    }
\
    Interval++;
    delay(100);
    
}

After attempting this for a couple days I'm at my wits end and would like some advice. I have also bought an SD card reader and plan to just put all my info on that if this doesn't work for me. Though I would highly prefer to keep it all on the Arduino.

If possible I would love some help in solving this issue, 300 words is just not enough for what I'm attempting to do.

This does not sound like a project for an Arduino. I reckon it would be very much easier to implement on a RaspberryPi or just on a PC or laptop.

...R

At this point the code words for what I want, except that it simply doesn't have enough words. Why is it possible to store a huge amount of words as proven in the code options I've shown but not when I replace the words with something useful? Does the fact that words are repeated mean that they take up less space?

Today I'm going to start to try with an SD card, hopefully I can make that work. I know people have done projects like this in the past with arduino, that's why I'm attempting this in this manner. Especially because I have proof that it works for what I would like so far I feel that I can't give up just yet.

An Arduino has limited memory, especially little RAM where it stores variables (and that's where your words will go, unless you take measures that tells the compiler to store it in flash, such as the F() macro).

A standard Arduino has 32k of flash, 2k RAM. 300 words of average 6 characters = 1800 bytes, eating up most of your RAM.

If you can store it in flash, you may dedicate 16 kB for this. At an average of 6 characters you could store some 2700 words (6 characters plus null terminator).

Get a Mega (wth ATmega2560 processor) you get 256 kB or flash - 240 kB would store just over 35k 6-character words.

You need only 5 bits per letter so if you store them smartly you need 35 bits or just over 4 bytes for a 6-character word including a 5-bit null. Your 240 kB would now store 56k 6-letter words.

But that'd be it for just a Mega. For any more, go for external memory such as an SD card and your storage is virtually unlimited (you can store several complete dictionaries on one MicroSD).

You seem to be tring to code the words into your program. Why don't you use an SD card and put the words in files.
You could have 26 files one for each letter of the alphabet, file 'A' contains all the words beginning with 'A' and so on.

Your program would pick a random file then read a random line in the file to get a word.

You may be able to squeeze this project into an Arduino. But it is so much easier to write that sort of program using Python (or Ruby) on a PC or RaspberryPi. You could have it all finished in the time it takes to ask questions here.

...R