It's the first time i'm using this & i thought this one would be easy.....no.
I need to count the number of characters in a int (first conversion to string and then use lenght()?) and ad this number to the number of characters in a String.
I want to store the result as a int, with everything in the previous in one line.
Both the int and the string are stored in two separate array's.
Everything else works in my sketch/project but this is extra to always get a part of my displayed text to the far right of the 16x2 lcd display. That why i need that count so i can set the cursor on the right spot every time i display the text.
int menuVariables[5] = { 180, 30, 170, 150, 60 }; //last int is 120 minutes and needs to be converted to ms
String menuUnits[] = { "cm ", "cm ", "cm ", "cm ", "min " };
and someting like this:
int startCursor = 16 - (String((menuVariables[lcdMenu-1]).lenght() + (menuUnits[lcdMenu-1]).lenght());
Don't mind the lcdMenu-1. It's got to do with re-indexing the info in combo with switch/case method.
I can't get specific info about this.
It is not very efficient but this will give you the length of n
int len = int(log10(n) + 1);
Personally I would probably put the ints and their lengths in an array of structs and use lcdMenu - 1 as the index to the values and I would not use Strings either
There may well be a more efficient way to do what you want so expect further comments
First thing I did was to "decode" your expression:
int startCursor = 16 - (String((menuVariables[lcdMenu-1]).lenght()
+ (menuUnits[lcdMenu-1]).lenght());
Making it a bit more readable to me, let's say you have in "VarLen" the length of the variable, and in "MenuLen" the length of the menu string.
int startCursor = 16 - VarLen + MenuLen
So, if considering "menuVariables[0]" or 180, VarLen is 3, and "menuunits[0]" or "cm ", so MenuLen is 4. I don't get why you need to add the "menuUnits" length (you'd have done better to show us the wanted result, letting us also understand if that units string should be displayed at the left or right of the value...), but this expression gives us the value of 17, when the LCD display cursor valid position is from 0 to 15, and id doesn't make sense to me.
Anyway, let's ignore all this useless bunch of calculations and lengths, you just need to have kinda right-justified value, right?
If you just need to right-justify (with spaces) a value and a measure unit you can simply use sprintf() and print the resulting string (I usually do it with a "buffer" variable) at a fixed display position. And possibly celaring the area first.
Example:
lcd.setCursor(6,0);
lcd.print(" "); // change it, based on the total length
char buf[10]; // Change this value accordingly (max string length + 1)
sprintf(buf, "%5d%s", menuVariables[lcdMenu-1], menuUnits[lcdMenu-1]);
lcd.setCursor(6,0);
lcd.print(buf);
Thx for reminding me sprintf. Although i'm using a other methode to print my int and strings in one line: lcd.print(menuText[lcdMenu - 1] + menuVariables[lcdMenu - 1] + menuUnits[lcdMenu - 1]);
I have not yet used sprintf (only 3 months at it) so my question about your example (because i can't seem to find a answer). The '5' in %5d%s . What is the purpose?
your right from 0 to 15 so my ...16- is probably wrong. I want to display the int and string next to each other as far at the right side of the lcd display as possible. The actual problem to solve is that the int varies from a single digit to a three digit number and i don't want any space left at the far right side of the lcd if the int is a for example '9' (that means two spaces at the right without the correction i want to achieve)
Ok, so if the value is from 1 to 3 chars long and also the unit, the total size/space is up to 6 chars starting from the right, so column 15-6 is 9. And get rid of "String" variables, use plain "C-strings".
See if this example code could help you for this job:
'works' like a charm! thx!
I read about c strings and sprintf but if i don't use it in a project it gets forgotten verry fast.
Now i have to try to incorporate this c string/sprintf solution in my project. It is not essential but i'm eager to perfect the result. My waterlevelmeter with refill valve command and double refill valve alarm needs to be very intuitive and simple to operate (one button for everything!). The last coding hurdle wil be the use of EEPROM to store settings in case of a power loss.
Only handles positive ints, but that'll probably be loads faster than computing a log function and rounding the resulting float. Wouldn't be that hard to modify it to handle signed numbers, and there's probably a way to recursively define it based on the maximum size of the specific variable you use. But that's a good base.
question const char *menuUnits [] = { "cm ", "cm ", "cm ", "cm ", "min " };
If i'm correct this is a array of pointers.
But { "cm ", "cm ", "cm ", "cm ", "min " } ar these the names of the pointers? How do i have to look at this? And and the content where the pointers 'point' to can only be occupied by type char. Right? Or am i rambling?
After looking some stuff up this seems to be the most logical and simplest solution for my problem (i don't need to make a buffer with sprintf).
And i'm not shure if this realy takes up that mutch computing power.
I'll wait with appointing a solution. Still trying to soak it all up but everybody has been very helpfull!
yes, the array holds the addresses of the strings which are stored elsewhere.
pointers don't have names like what you're suggesting, they are variables which are named.
accessing an array element requires using an index into the array.
a c string is an array of chars with a NUL following the last char in the string. A pointer to a string will be to an addresses containing a char. the next address and subsequent addresses will also contain a chars.
look this over
output
0x100 names
0x146 tom
0x14a dick
0x14f harry
0x155 harry bellefonte
dump: tom
0146: 74 6f 6d 00
dump: dick
014a: 64 69 63 6b 00
dump: harry
014f: 68 61 72 72 79 00
dump: harry bellefonte
0155: 68 61 72 72 79 20 62 65
015d: 6c 6c 65 66 6f 6e 74 65
0165: 00
const char *names [] = { "tom", "dick", "harry", "harry bellefonte" };
const int Nnames = sizeof(names) / sizeof(char*);
char s [90];
// -----------------------------------------------------------------------------
void
dumpChar (
char *p,
int nByte,
const char *label )
{
sprintf (s, "dump: %s", label);
Serial.print (s);
for (int n = 0; n < nByte; n++) {
if (! (n % 8)) {
sprintf (s, "\n %04x:", & p [n]);
Serial.print (s);
}
sprintf (s, " %02x", p [n]);
Serial.print (s);
}
Serial.println ();
}
// -----------------------------------------------------------------------------
void
setup (void)
{
Serial.begin (9600);
Serial.println ();
sprintf (s, " %p %-4s", names, "names");
Serial.println (s);
Serial.println ();
for (int n = 0; n < Nnames; n++) {
sprintf (s, " %p %-4s", names [n], names [n]);
Serial.println (s);
}
Serial.println ();
for (int n = 0; n < Nnames; n++)
dumpChar (names [n], 1+strlen(names [n]), names [n]);
}
void loop (void) { }
just test your function.
In the German section we had a similar discussion 5 years ago. In the end I have compared 11 variants (well 12, but one is not correct) with different compiler settings.
I have aded a extra char array because that is like in my project but is doens't seem to work. And i have defined the lenght for all the elements in the buffer. (your example works fine)
What am i missing here? I took the time to get info but i feel it has been a waste of time:
You are filling in all 16 bytes of buf so there is no room for the trailing nul '\0' which a c-string needs. If you display is 16 chars wide, buf needs to be 17 chars in size.
i'v made it char buf[17];
but it still doesn't work. It still keeps showing - TESTCODE - but the flickering is gone.
It's damn hard, that coding stuff to learn. The moment i think i figured something out i'm completely wrong.
Your menuText variable is not correct. You have declared an array of pointers to char with each array being 5 chars in length which is not the case. You really want an array of char pointers
Your wise guidence of using the array of char pointer just happened to spring to mind while i was on my way to work (yes these days i'm starting & going to sleep with it. Even my wife is complaining!) This is the last posibilty i didn't yet tested.
question: Am i correct that a array of char pointers actualy holds different arrays of char in the background? for example "Minlevel" is actualy a char array that holds char 'M' at offset 0, char 'i' at offset 1, char 'n' at offset 2, etc...? Right? This realy sucks in C because this is not actualy visible when coding this stuff. Also the use of "" or , or ; is still confusing. @gcjr@blh64 thx for the help with your solution. I'll test it asap. btw i have found a not so elegant working solution that completly does wat i want it to do but i want to solve it like you guy's.
Less elegant:
int startCursor = 14 - menuUnits[lcdMenu-1].length();//prep calculation to set the second part of the lcd text on the first line to the right
lcd.setCursor(0, 0); //cursor set line 0, character 0
lcd.print(menuText[lcdMenu-1]);
lcd.setCursor(startCursor, 0);
lcd.print(menuVariables[lcdMenu - 1] + menuUnits[lcdMenu - 1]);