How to use Print function

Hi all,
I am writing some code where I want to use the print function,
It's that I am writing a library, for a IO expander that controles a lcd.

and I want to write a function like lcd.print();

but I've written the function like this:

void IOlcd::print(char* arrayc){
	int linelength = strlen(arrayc);
	for(int i=0;i<linelength;i++){
		write(arrayc[i]);
	}
}


void IOlcd::write(uint8_t c){
	c = byteShift(c);
	Wire.beginTransmission(addr);
	Wire.send(0x00);
	Wire.send(c);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B11000000);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B10000000);
	Wire.endTransmission();
	
	delayMicroseconds(100);
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B01000000);
	Wire.endTransmission();
}

but when I write something like
int count = 90;
lcd.print(count);

I get an error like: invalid conversion from ‘int’ to ‘char*’

what lcd.print(); does at the moment is being able to print strings,
but how do I do this for integers

I wanted to use the Print.h for this,
but when I look at liquidcrystal.h it writes #include "Print.h"
but I can't find in liquidcrystal.cpp how this is used or works,
so I hope you all can help me with this :slight_smile:

I might be getting confused by the amount of code in liquidcrystal.ccp though.

Greetings,
Duality

hi this is how I fixed it temporarily:

void IOlcd::print(char* arrayc){
	int linelength = strlen(arrayc);
	for(int i=0;i<linelength;i++){
		write(arrayc[i]);
	}
}

void IOlcd::print(uint8_t arrayc){
	char value2[4];
	itoa(arrayc,value2, 10);
	int linelength = strlen(value2);
	for(int i=0;i<linelength;i++){
		write(value2[i]);
	}
}

void IOlcd::write(uint8_t c){
	c = byteShift(c);
	Wire.beginTransmission(addr);
	Wire.send(0x00);
	Wire.send(c);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B11000000);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B10000000);
	Wire.endTransmission();
	
	delayMicroseconds(100);
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B01000000);
	Wire.endTransmission();
}

the problem here probably is that the array value2 is 4 long so it will only go to 9999,
what if I want to print a longer number? is there a way to find out the length of int arrayc?
everything over 1000 is 4 long, and every thing over 100 is over 3 long or longer so...
is there a way to find out the length of int arrayc?
like I can find out the length of a sting?

duality:
hi this is how I fixed it temporarily:

...

void IOlcd::print(uint8_t arrayc){
char value2[4];
itoa(arrayc,value2, 10);
...




the problem here probably is that the array value2 is 4 long so it will only go to 9999,
what if I want to print a longer number?

Well it won't, because a byte (uint8_t) can only to to 255. Assuming you allow for longer numbers, then the strlen in there will stop at the end of the number anyway, eg.

void IOlcd::print (int num)
  {
  char buf [10];
  itoa (num, buf, 10);
  int linelength = strlen (buf);
  for (byte i = 0; i < linelength; i++)
    {
    write (buf [i]);
    }
  }

Try to use meaningful names. Calling a number "arrayc" and a buffer "value2" is just throwing extra confusion into the mix.

Hi,
Thanks for the reply,
I figured out that uint8_t only displays a value from 0 to 255,
And yes I am not using meaning full names,
But I always can change that later on when I am some further with my library :slight_smile:
but this is what it looks like right now:

void IOlcd::print(char* arrayc){
	int linelength = strlen(arrayc);
	for(int i=0;i<linelength;i++){
		write(arrayc[i]);
	}
}

void IOlcd::print(int arrayc){
	int declength = sizeof(arrayc);
	char value2[declength];
	itoa(arrayc,value2,10);
	int linelength = strlen(value2);
	for(int i=0;i<linelength;i++){
		write(value2[i]);
	}
}

void IOlcd::write(uint8_t c){
	c = byteShift(c);
	Wire.beginTransmission(addr);
	Wire.send(0x00);
	Wire.send(c);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B11000000);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B10000000);
	Wire.endTransmission();
	
	delayMicroseconds(100);
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B01000000);
	Wire.endTransmission();
}

converting it to a string then determining the length of the string and using that number to find out the length of the data that I want to display,
It might be overkill in a sense,
since I might be able to use sizeof(); to determine the length of the variable, but when I do this, I get weird data that manifests it's self on the lcd as weird tokens,
that I can't understand nor read, just symbols.

But I always can change that later on when I am some further with my library

Now, when there is a small amount of code, or later when there is more. I know when I'd start using better names.

	int declength = sizeof(arrayc);

The arrayc variable (dumb name) is an int. All ints are 2 bytes. That's what sizeof() is telling you.

	char value2[declength];
	itoa(arrayc,value2,10);

So, you are reserving space for one character and the trailing NULL.

since I might be able to use sizeof(); to determine the length of the variable

No, you can't.

An int can hold a value between -32768 and +32767. If you can't figure out the size of an array necessary to hold the string representation of an int from that information, we can't really help you anymore.

duality:

...

void IOlcd::print(int arrayc){
int declength = sizeof(arrayc);
char value2[declength];
itoa(arrayc,value2,10);
int linelength = strlen(value2);
for(int i=0;i<linelength;i++){
write(value2[i]);
}
}
...




since I might be able to use sizeof(); to determine the length of the variable, but when I do this, I get weird data that manifests it's self on the lcd as weird tokens,
that I can't understand nor read, just symbols.

What was wrong with my suggestion of using 10 bytes? An int won't go over 65535, plus a byte for the trailing null, so really 6 would have been enough. As Paul said, sizeof (int) is 2, so you aren't allocating enough.

And yes I am not using meaning full names,
But I always can change that later on when I am some further with my library :slight_smile:

Once you have confused both yourself, and people on the forum, a little bit more?

Ah,
I get it, sizeof integer gives 2 bytes, making the array only 2 bytes long?
stop me if im wrong here,
Still learning, this is what it looks like right now:

void IOlcd::print(char inputArray[]){
	int linelength = strlen(inputArray);
	for(int i=0;i<linelength;i++){
		write(inputArray[i]);
	}
}

void IOlcd::print(int input){
	char buf[10];
	itoa(input,buf,10);
	int linelength = strlen(buf);
	for(int i=0;i<linelength;i++){
		write(buf[i]);
	}
}

void IOlcd::write(uint8_t c){
	c = byteShift(c);
	Wire.beginTransmission(addr);
	Wire.send(0x00);
	Wire.send(c);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B11000000);
	Wire.endTransmission();
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B10000000);
	Wire.endTransmission();
	
	delayMicroseconds(100);
	
	Wire.beginTransmission(addr);
	Wire.send(0x01);
	Wire.send(B01000000);
	Wire.endTransmission();
}

does it look better with the names?
so determinin the size of the integer was unnecesery?
since it's ending with a \o in the array anyway?
or do understand it wrong lol,

anyway can only learn from this :slight_smile:
so that code is what it looks like right now, and it works :slight_smile:

greetings,
Duality

Yes I think you have it. Now that I look closely at your code, you seem to be re-inventing the Print class.

If you look in the LiquidCrystal.h file (wherever that is exactly) you will see something like this:

class LiquidCrystal : public Print {
public:
 
...

  virtual void write(uint8_t);

What that is basically doing is deriving all of the printing functions (eg. print in hex, print a string, print an integer) from the Print class. Then by simply providing a virtual function "write" (which the Print class uses) all of the other stuff you get "for free".

Since you already have a "write" function your job is done. Just get rid of all the extra "print" functions and add ": public Print" to your class header.

Effectively the Print class assumes you give it a write function to do the low-level writing, and then it handles all the format conversion. Simple!

Thats handy!

This might be the golden Ticket! :stuck_out_tongue:

Let me try and use this,
I'll post any update's and if it works :slight_smile:

Greetings,
Duality

Love you for giving me that tip!
this is awesome,
thanks so much,
it works!

Greetings,
Duality