Assigning arrays to words and using it in function - please help :)

Hi there, I tried to post already 20mins ago, but it seems that my post is gone, I can't find it in my posts...

so long story short:

I need to read data from SD.card and that data describes a colour. I don't know what variable type to use to assign that data to this function:

tft.fillScreen(variable);

the problem seems to be that that particular function takes that exact same text inside ( ) without understanding it as variable. So it will try to find if "variable" is defined somewhere.

I have tried this things:

#define RED 0xF800 //this is just an example
#define BLACK 0x0000

//1st try
word backCOLOUR = RED;
tft.fillScreen(backCOLOUR); // --> this works, but that's what I wrote inside code, not the value from SD...

//2nd try
word backCOLOUR;

function for getting value from SD{
File DOC = SD.open("backcolr.txt");
    char sett[15], c;
    int i = 0;
    memset(sett, 0, sizeof(sett));

    if (DOC) {
      while (DOC.available()) {
        c = DOC.read();
        if (c != '\0') {
          sett[i] = c;
          i++;
        }
        delay(10);
      }
      backCOLOUR = sett; // this doesn't work --> it stores some numbers to backCOLOUR //
      backCOLOUR = word(sett); //also doesn't work
      backCOLOUR = (word)sett; // too...

      Serial.print("sett: ");
      Serial.println(sett); //gives "BLACK"
      Serial.print("backCOLOUR: ");
      Serial.println(backCOLOUR); //gives "8324" (example)---> it's a random number but not a color code or name
      DOC.close();
}


//3rd try
char backCOLOUR[15];

File DOC = SD.open("backcolr.txt");
    char c;
    int i = 0;
    memset(backCOLOUR, 0, sizeof(backCOLOUR));

    if (DOC) {
      while (DOC.available()) {
        c = DOC.read();
        if (c != '\0') {
          backCOLOUR[i] = c;
          i++;
        }
        delay(10);
      }
      Serial.print("backCOLOUR: ");
      Serial.println(backCOLOUR); //gives correct value "RED" or "BLACK" or any other colour but...
      DOC.close();

//when I later try this:
tft.fillScreen(backCOLOUR); //this doesn't work even though backCOLOUR is now BLACK or RED...

So my question is how to do any of these:

  1. Assign an array sett[15] to a - word backCOLOUR;
  2. Assign that word backCOLOUR to - tft.fillScreen(backCOLOUR);
  3. Assign an array backCOLOUR[15] to that function - tft.fillScreen(backCOLOUR)

sorry for long post and thanks in advance everyone :slight_smile:

You are reading a string from your SD card: "BLACK".
You have defined a word in your program with value 0x0000 and the name BLACK.

You need some code to check the value of the string and set the background colour.
Like this:

if(strcmp(sett,"BLACK")==0)
  {
  backCOLOUR=BLACK;
  }

wildbill:
You are reading a string from your SD card: "BLACK".
You have defined a word in your program with value 0x0000 and the name BLACK.

You need some code to check the value of the string and set the background colour.
Like this:

if(strcmp(sett,"BLACK")==0)

{
 backCOLOUR=BLACK;
 }

First of all thank you for your reply. :slight_smile:
hmm, I get your point, but that would make me have many if statemets, with many parameters which would make my long code even longer. I was trying to make kind of "direct" transfer of what is saved inside .txt file. Because I have many colour options in my project, what you wrote would mean I have to have many lines of code just to set my startup settings. So is it possible to somehow transfer that value from .txt file to the tft.fillScreen() function?
I need to somehow get tft.fillScreen(BLACK) or tft.fillScreen(RED) or tft.fillScreen(any word that is writtten inside .txt file)?

Thanks :wink:

You can do it with little code if you put the data into arrays. One array of the strings and a corresponding array with the colour numbers.

Better would be to use an array of structs.

Thank you, I'll be back with my result when I do it :slight_smile:

I tried to post already 20mins ago, but it seems that my post is gone, I can't find it in my posts...

This might be of interest: More forum weirdness - Website and Forum - Arduino Forum

Use Strings, they are safer and easier.
Try this.

#define RED 0xF800 //this is just an example
#define BLACK 0x0000

bool haveSetColor = false;

String colorText;
void setup() {
  Serial.begin(115200);
  for (int i = 10; i > 0; i--) {
    Serial.print(i); Serial.print(' ');
    delay(500);
  }
  Serial.println();
  colorText.reserve(15);
}

bool readColourFromSD() {
  File DOC = SD.open("backcolr.txt");
  if (DOC) {
    while (DOC.available()) {
      char c = DOC.read();
      colorText += c;
      if (colorText.length() >= 15) {
        break; // should have it by now
      }
    }
    DOC.close();
    Serial.print("sett: ");
    Serial.println(colorText); //gives "BLACK"
    if (colorText == "BLACK") {
      tft.fillScreen(BLACK);
    } else if (colorText == "RED") {
      tft.fillScreen(RED);
    } else {
      return false; // bad color
    }
    return true; // the other two case
  }
}

void loop() {
  // . . .
  if (!haveSetColor) {
    if (readColourFromSD()) {
      haveSetColor = true;
    } else {
      Serial.println("bad color not set");
    }
    colorText = ""; // finished with this clear for next time
    // .. other stuff
  }
}

drmpf:
Use Strings, they are safer and easier.

Can you explain why you believe Strings are safer?

Short answer, Strings handle the null terminator and prevent buffer overflows and were introduced in C++ to overcome the systemic coding errors caused by using c-strings methods on char[]

drmpf:
Use Strings, they are safer and easier.
Try this.

#define RED 0xF800 //this is just an example

#define BLACK 0x0000

bool haveSetColor = false;

String colorText;
void setup() {
 Serial.begin(115200);
 for (int i = 10; i > 0; i--) {
   Serial.print(i); Serial.print(' ');
   delay(500);
 }
 Serial.println();
 colorText.reserve(15);
}

bool readColourFromSD() {
 File DOC = SD.open("backcolr.txt");
 if (DOC) {
   while (DOC.available()) {
     char c = DOC.read();
     colorText += c;
     if (colorText.length() >= 15) {
       break; // should have it by now
     }
   }
   DOC.close();
   Serial.print("sett: ");
   Serial.println(colorText); //gives "BLACK"
   if (colorText == "BLACK") {
     tft.fillScreen(BLACK);
   } else if (colorText == "RED") {
     tft.fillScreen(RED);
   } else {
     return false; // bad color
   }
   return true; // the other two case
 }
}

void loop() {
 // . . .
 if (!haveSetColor) {
   if (readColourFromSD()) {
     haveSetColor = true;
   } else {
     Serial.println("bad color not set");
   }
   colorText = ""; // finished with this clear for next time
   // .. other stuff
 }
}

Thank you for your suggestion, I'll try something like this, but as I can see here you have been using:

if(colour == black) then...
if(colour == red) then...

the point is that I want to override that, because I have around 20 colours and in the future there will be even more. What I'm trying to do later is some kind of on screen settings. But for now I want to get it working with just setting up the whole thing with one or two colours with as little as possible variables :slight_smile:

Another alternative is to store the color in the file as a hex string value and then use my SafeString library instead of Strings and use the hexToLong() method to convert the hex string to a number and use that directly to set the background color.
Post back here if you need help with that.

Comparing an input c-string with an array of constant strings is perfectly easy to make safe. The only thing you have to guard against is an input overflow. That is also easy to make completely safe. The code for this is really so simple that verifying its integrity will also be easy.

Don't be frightened by non-issues like, "handling the null terminator". The native c string functions have been handling that quite well for almost 40 years.

There is only one possible buffer overflow, which you can guard by sizing the input buffer slightly larger than the longest array string, furthermore guarding the index during a file read, which at worst would truncate the string.

native c string functions have been handling that quite well for almost 40 years.

No they haven't. c-string functions have been the bane of programming for over 30 years and the cause of so many programming errors that Microsoft has banned their programmers from using them and text books have been written on why they should not be used.

drmpf:
Use Strings, they are safer and easier.

Here we go again ...

My "backup" solution to this problem:

Thank you all for helping me out, I decided that I will go with one relatively long yet simple solution. When I think of it now, it's even not that long. But here is what I did:

instead of saving words or HEX inside .txt files (RED, BLACK, 0x0000...) I'm now storing only one number (from 0 to x). I read that number from .txt file and I'm sending it to custom function which, depending on what the number is returns the value of predefined colors. Take a look and if you have any advice here to make my code shorter or run smoother than it is now, great! :slight_smile:

So this is the code of that part with colours... they are #defined before void setup(), but I haven't put it here...

void ColourSettings() {
  {
    File DOC = SD.open("backcolr.txt");

    char sett; //just for reading number from the file

    if (DOC) {
      while (DOC.available()) {
        sett = DOC.read();
        DOC.close();
      }
      backCOLOUR = ColourPicker(sett); //backCOLOUR is the one I use in function tft.fillScreen(backCOLOUR);
    }
  }

  {
    File DOC = SD.open("textcolr.txt");

    char sett;

    if (DOC) {
      while (DOC.available()) {
        sett = DOC.read();
        DOC.close();
      }
      txCOLOUR = ColourPicker(sett);
    }
  }

}



//having this custom function allows me to pick colors for text, background, fill, frame... with only this func.

word ColourPicker(char C) {
  if (C == 0) return BLACK;
  else if (C == 1) return PURPLE;
  else if (C == 2) return PINK;
  else if (C == 3) return NAVY;
  else if (C == 4) return BLUE;
  else if (C == 5) return DARKCYAN;
  else if (C == 6) return CYAN;
  else if (C == 7) return DARKGREEN;
  else if (C == 8) return GREEN2;
  else if (C == 9) return OLIVE;
  else if (C == 10) return GREEN;
  else if (C == 11) return GREENYELLOW;
  else if (C == 12) return YELLOW;
  else if (C == 13) return ORANGE;
  else if (C == 14) return BROWN;
  else if (C == 15) return MAROON;
  else if (C == 16) return MAGENTA;
  else if (C == 17) return DARKROSE;
  else if (C == 18) return RED;
  else if (C == 19) return WHITE;
  else if (C == 20) return LIGHTGREY;
  else if (C == 21) return DARKGREY;

  /*
    #define BLACK 0x0000     --------------->  0
    #define PURPLE 0x780F    --------------->  1
    #define PINK 0xF816      --------------->  2
    #define NAVY 0x000F      --------------->  3
    #define BLUE 0x001F      --------------->  4
    #define DARKCYAN 0x03EF  --------------->  5
    #define CYAN 0x07FF      --------------->  6
    #define DARKGREEN 0x03E0 --------------->  7
    #define GREEN2 0x0C40 //0x1CE0 --------->  8
    #define OLIVE 0x7BE0     --------------->  9
    #define GREEN 0x07E0     --------------->  10
    #define GREENYELLOW 0xAFE5  ------------>  11
    #define YELLOW 0xFFE0    --------------->  12
    #define ORANGE 0xFD20    --------------->  13
    #define BROWN 0x9AA0     --------------->  14
    #define MAROON 0x7800    --------------->  15
    #define MAGENTA 0xF81F   --------------->  16
    #define DARKROSE 0x9000  --------------->  17
    #define RED 0xF800       --------------->  18
    #define WHITE 0xFFFF     --------------->  19
    #define LIGHTGREY 0xC618 --------------->  20
    #define DARKGREY 0x7BEF  --------------->  21
        
  */
}

if you have any advice here to make my code shorter

Use an array to hold the colour values and the value of C (or rather its numerical equivalent) to get the associated value

UKHeliBob:
Use an array to hold the colour values and the value of C (or rather its numerical equivalent) to get the associated value

Thanks, I did, I made int array with all codes converted from HEX to decimal of COLOURS I use. Then I sent number that is in my .txt file, converted with atoi(sett), so I get integer instead of string number. And then everything is easy because I just have my array x[number of colours] = {assigned colour numbers in dec}
return Picked = x[num from .txt]
And that's it, I have my values finally.
Thanks everyone :slight_smile:

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.