Hi Robertbu,
I made a box that worked like a Magic 8 Ball using a list of strings. Both the strings and the list of strings are kept in PROGMEM. Originally I also kept the string length in an array, but it turned out to be easier to calculate the string length with strlen(). Here's a short program that should be easy to follow as an example of how to keep strings, and a list of the strings in PROGMEM.
Here's my sketch*:
/*
Magic8BallWithCounting in an mint tin printed with a Ouija board
ATTiny85 - 1 MHz internal clock, 3 volts: 2x aaa alkalines (1 year)
Adafruit red 14 segment I2C backpack (0x70)
Tiny85 pins: cds on pin 3; switche on pin 6; button on 1; pin 2 unconnected for random
History:
date by flash/ram why
052816 clh 4082/116 - first circuit: 9 ua in snooze mode
120316 clh 3982/127 - solder, seal & sell!
*/
// libraries
#include <TinyWireM.h> // https://github.com/adafruit/TinyWireM
#include <Narcoleptic.h> // https://github.com/brabl2/narcoleptic
#include "Adafruit_GFX.h" // https://learn.adafruit.com/adafruit-led-backpack/downloads
#include "Adafruit_LEDBackpack.h" // as above ...
// define the pins and i2c addresses
#define cds A2 // pin --> cds --> gnd
#define in A3 // unconnected
#define reset A0 // pin 1
#define button 1 // pin --> button --> gnd
#define SDA 0
#define SCL 2
#define alphaAddress 0x70 // 14 segment I2C device
#define startMinute 59 // Modify these defines to
#define startSecond 59 // change the timer interval
// phrases and names - first 20 are official phrases
const char yes1[] PROGMEM = " WITHOUT A DOUBT";
const char yes2[] PROGMEM = " YOU MAY RELY ON IT";
const char yes3[] PROGMEM = " YES DEFINITELY";
const char yes4[] PROGMEM = " SIGNS POINT TO YES";
const char yes5[] PROGMEM = " IT IS DECIDEDLY SO";
const char yes6[] PROGMEM = " AS I SEE IT - YES";
const char yes7[] PROGMEM = " YES";
const char yes8[] PROGMEM = " MOST LIKELY";
const char yes9[] PROGMEM = " IT IS CERTAIN";
const char yes10[] PROGMEM = " OUTLOOK GOOD";
const char no1[] PROGMEM = " MY SOURCES SAY NO";
const char no2[] PROGMEM = " DONT COUNT ON IT";
const char no3[] PROGMEM = " VERY DOUBTFUL";
const char no4[] PROGMEM = " OUTLOOK NOT SO GOOD";
const char no5[] PROGMEM = " MY REPLY IS NO";
const char idk0[] PROGMEM = " BETTER NOT TELL YOU NOW";
const char idk1[] PROGMEM = " ASK AGAIN LATER";
const char idk2[] PROGMEM = " REPLY HAZY TRY AGAIN";
const char idk3[] PROGMEM = " CANNOT PREDICT NOW";
const char idk4[] PROGMEM = " CONCENTRATE AND ASK AGAIN";
char phrase[36]; // -->|" "|<--
const char* const theAnswers[] PROGMEM = { yes1, yes2, yes3, yes4, yes5, yes6, yes7, yes8, yes9, yes10,
no1, no2, no3, no4, no5, idk0, idk1, idk2, idk3, idk4,
};
int numerics[] = { // my numerals (rather than use the ugly builtins)
0b0000000000111111, // 0
0b0000010000000110, // 1 A
0b0000100010001011, // 2 FhjkB
0b0000010010001101, // 3 g1 g2
0b0000000011100110, // 4 ElmnC
0b0000000110001101, // 5 D dp
0b0000100010111100, // 6
0b0000110011000001, // 7 binary: 0, dp, n, m, l, k, j, h, g2, g1, F, E, D, C, B, A
0b0000000011111111, // 8 1 = lit up, 0 = dark
0b0000000011100111, // 9
};
unsigned long previousSecondMillis = 0UL;
const long oneSecond = 1000L;
byte minutes = startMinute;
byte seconds = startSecond;
byte answer;
byte scrollPosition;
byte answerLength;
boolean isBlank;
boolean colon;
// output device
Adafruit_AlphaNum4 alpha = Adafruit_AlphaNum4();
void setup()
{
pinMode(cds, INPUT_PULLUP);
pinMode(button, INPUT_PULLUP);
pinMode(reset, INPUT_PULLUP);
alpha.begin(alphaAddress); // i2c address of the alphanumeric display
randomSeed(analogRead(in));
previousSecondMillis = millis() + Narcoleptic.millis();
}
void loop() {
snooze(125); // nap while timing lighting interface
// if the box is closed, turn it off
if (analogRead(cds) < 960) {
isBlank = false;
scrollPosition = 0;
// select a random answer number
answer = random(21);
// set start time for hourglass
minutes = startMinute;
seconds = startSecond;
while (analogRead(cds) < 900) {
snooze(187); // nap while timing the scroll rate
// ambience dimming
byte ambience = constrain(map(analogRead(cds), 500, 0, 0, 30), 0, 11);
alpha.setBrightness(ambience); // values from trial-and-error
// read the switch
if (digitalRead(button)) { // do hourglass ...
// do this part once a second
if ((millis() + Narcoleptic.millis()) - previousSecondMillis >= oneSecond) {
previousSecondMillis += oneSecond;
// show the time on the LED
colon = !colon;
alpha.writeDigitRaw(0, numerics[minutes / 10]);
alpha.writeDigitRaw(1, (numerics[minutes % 10] | (colon ? 0b0100000000000000 : 0))); // flash decimal point
alpha.writeDigitRaw(2, (numerics[seconds / 10]));
alpha.writeDigitRaw(3, (numerics[seconds % 10]));
alpha.writeDisplay();
// decriment seconds
if (seconds-- == 0) {
if (minutes == 0) { // time is up
minutes = startMinute;
seconds = startSecond;
// show the ararm
for ( byte n = 0; n < 5; n++) {
alpha.writeDigitAscii(0, 'D');
alpha.writeDigitAscii(1, 'O');
alpha.writeDigitAscii(2, 'N');
alpha.writeDigitAscii(3, 'E');
alpha.writeDisplay();
snooze(250);
blankDisplay();
}
} else { // decriment minutes
minutes--;
seconds = 59;
}
}
} // end 'once a second' part
} else { // ... do 8 ball
// a family of tomatos is walking, but the baby lags behind. The father stomps and shouts Catch Up!
previousSecondMillis = millis() + Narcoleptic.millis();
// copy the phrase into RAM: https://www.arduino.cc/en/Reference/PROGMEM
strcpy_P(phrase, (char*)pgm_read_word(&(theAnswers[answer])));
// add 4 spaces to provide a short 'all off', so it can go to sleep if the box is closed
strcat(phrase, " ");
answerLength = (byte)strlen(phrase) - 4;
// scroll phrase across 14 segment display
if (scrollPosition > answerLength) scrollPosition = 0;
alpha.writeDigitAscii(0, phrase[scrollPosition]);
alpha.writeDigitAscii(1, phrase[scrollPosition + 1]);
alpha.writeDigitAscii(2, phrase[scrollPosition + 2]);
alpha.writeDigitAscii(3, phrase[scrollPosition + 3]);
alpha.writeDisplay();
scrollPosition++;
}
}
} else { // turn all 14 segments off
if (!isBlank) {
isBlank = true;
blankDisplay();
}
}
}
void blankDisplay() {
alpha.writeDigitRaw(0, 0);
alpha.writeDigitRaw(1, 0);
alpha.writeDigitRaw(2, 0);
alpha.writeDigitRaw(3, 0);
alpha.writeDisplay();
}
// sleep with ADC off - http://forum.arduino.cc/index.php?topic=248690.msg1778100
void snooze(unsigned long int ms) {
byte adcsra_save = ADCSRA;
ADCSRA = 0; // turn adc off
Narcoleptic.delay(ms); // Zzzzzzz.
ADCSRA = adcsra_save; // adc back on
}
EDIT: * Additional replies have been removed for the 9000 character limit.