Go Down

Topic: passing a char array (Read 1 time) previous topic - next topic

jeroen870

Hi!

I'm trying to do some LCD stuff, and for that I need a little routine to cut a string into pieces depending of the with of each character.
Since I can't find a lib with "text clipping" and "var width fonts", I'm trying to make something myself.

I wrote some code, and it's working fine, but I can't put it into a function. Can someone help me?

Code: [Select]

static int lengte[] = {
3, 1, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 2, 5, 2, 5, //20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f
5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 4, 5, 4, 5, //30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 3, 5, 5, //50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f
3, 4, 4, 4, 4, 4, 4, 4, 4, 1, 3, 4, 3, 4, 4, 4, //60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f
4, 4, 4, 4, 4, 4, 5, 5, 5, 3, 3, 3, 1, 3, 5, 5, //70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f
};

char *FormatString(String Vtext) {

  #define LCDWIDTH   84
  int Vlengthtext=0;
  int Vprevlengthtext=0;
  char Vtext2[100]="";
  char *Vtexttoprint[200];
  int j=0;
  int k=0;

  for (int i=0; i<=Vtext.length();i++){
    Vtext2[k] = Vtext.charAt(i);
    k++;
    Vlengthtext = Vlengthtext + lengte[Vtext.charAt(i) - 0x20];
    if ((Vprevlengthtext <= LCDWIDTH*(1+j) && Vlengthtext > LCDWIDTH*(1+j)) || i==Vtext.length()){
      Vtexttoprint[j]=Vtext2;
      memset(Vtext2,0,sizeof(Vtext2));//for (int z=0; z<100;z++){Vtext2[z]=0;}
      k=0;
      j++;
    } else{
      Vprevlengthtext=Vlengthtext;
    }
  }
   
  return (Vtexttoprint); 
}



void setup(void){
}

void loop(void){
 
  for (int k = 0; k < 1; k++) {
    Serial.begin(9600);
    Serial.println(FormatString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"))
    ;delay(100);
  }
    delay(10000);

}


Thanks,

Jeroen

PaulS

There are several problems with that function.

Code: [Select]
  char Vtext2[100]="";
If you are going to specify a length, why are you not specifying the same number of initializers?

Code: [Select]
  char *Vtexttoprint[200];
This is an array of pointers. It is unlikely that that is what you want.

Passing a String to this function is a waste of resources. Pass it a char array (or pointer to char) instead.

Code: [Select]
  for (int i=0; i<=Vtext.length();i++){
If there are 3 characters in the String, you are going to access characters 0, 1, 2, and 3. Hardly seems like a good idea to me.

You are trying to return an array of pointers from a function defined to return a single pointer. That pointer, or array of pointers if you change the return type appropriately go out of scope when the function ends, so the caller would get a load of garbage.

You need to pass to the function a pointer to the memory location where it is to put its results, after allocating that memory in the caller.

mkwired

I would write a function that returns how much of the string can "fit" on a line.
Code: [Select]

#define LCDWIDTH   84

static const uint8_t lengte[] = {
3, 1, 3, 5, 5, 5, 5, 2, 3, 3, 5, 5, 2, 5, 2, 5, //20,21,22,23,24,25,26,27,28,29,2a,2b,2c,2d,2e,2f
5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 4, 5, 4, 5, //30,31,32,33,34,35,36,37,38,39,3a,3b,3c,3d,3e,3f
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, //40,41,42,43,44,45,46,47,48,49,4a,4b,4c,4d,4e,4f
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 3, 5, 5, //50,51,52,53,54,55,56,57,58,59,5a,5b,5c,5d,5e,5f
3, 4, 4, 4, 4, 4, 4, 4, 4, 1, 3, 4, 3, 4, 4, 4, //60,61,62,63,64,65,66,67,68,69,6a,6b,6c,6d,6e,6f
4, 4, 4, 4, 4, 4, 5, 5, 5, 3, 3, 3, 1, 3, 5, 5, //70,71,72,73,74,75,76,77,78,79,7a,7b,7c,7d,7e,7f
};

char* maxline(char* p, uint8_t max_width)
{   
   for (uint8_t w = lengte[*p - 0x20]; w < max_width; p++)
      w += lengte[*p - 0x20];
   return p;
}

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

void loop(void){
  char* b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  char* e = maxline(b, LCDWIDTH);
 
  Serial.write((const uint8_t *)b, e-b);
  Serial.println("");
  delay(10000);
}

tuxduino

I often use this macro:

Code: [Select]
#define ARY_LEN(a) (sizeof(a) / (sizeof(a[0])))

jeroen870

Thanks to you guys I've fabricated something that works (for 95%).
I can now show some text on my 3310 nokia lcd screen.
There is still a weird sign at the end of the text, and I don't know how to delete that last caracter.
If someone has an idea in what I'm doing wrong, please comment.

Greetings, Jeroen

Go Up