4bit DFROBOT LCD Shield and writing array of bytes

Ok so I came to the point in my program when I would like to display IP address of the Ethernet shield stored as array of bytes :

byte ip[4] = { 192, 168, 0, 10 };

onto the DFROBOT LCD.

now this wasn't very easy because 2 print functions implemented in LCD4Bit_mod library are printing byte by byte either dec value or message

so lcd.print(65) will display A
and lcd.printIn("Abc") will display Abc

so to display int x = 1 as ASCII you should lcd.print(x + 48);

what about byte value like ip[1] = 192 ?

lcd.print(ip[1] + 48) will not work I promisse!

this is because 192 + 48 is 240 which is in ASCII table = ð

so what to do ?

split 192 into 1 + 48 , 9 + 48 and 2 + 48 and output byte by byte ?

hmmm ok ...

so I created function

 lcdPrintIp(ip);

// which look like this:

void lcdPrintIp(byte ip_[])
{
    lcd.clear();
    lcd.print(ByteNA(ip_[0],3)); lcd.print(ByteNA(ip_[0],2)); lcd.print(ByteNA(ip_[0],1)); lcd.printIn(".");
    lcd.print(ByteNA(ip_[1],3)); lcd.print(ByteNA(ip_[1],2)); lcd.print(ByteNA(ip_[1],1)); lcd.printIn(".");
    lcd.print(ByteNA(ip_[2],3)); lcd.print(ByteNA(ip_[2],2)); lcd.print(ByteNA(ip_[2],1)); lcd.printIn(".");    
    lcd.print(ByteNA(ip_[3],3)); lcd.print(ByteNA(ip_[3],2)); lcd.print(ByteNA(ip_[3],1));        
}

// and another one

byte ByteN(byte in, int n)
{
   byte temp = in;
   int i;
   for(i = 1; i < n; i++){
       if(i == n) break; 
       temp = temp / 10;
   }  
   return (temp % 10);
}

// and one more

byte ByteNA(byte in, int n)
{
   return (ByteN(in,n) + 48);
}

// by giving byte array like ip[], netmask[], gateway[] you are able now to display this onto LCD as ASCII

is this the simplest way ??? there must be another solution ?? :-?

Take a look at the itoa (integer to ascii) function. It does exactly what you did, in an easy to use function call.

Or, you could use the sprintf function, to print all 4 bytes as a formatted string, into an array. Then, call lcd.print with that array.

char* itoa ( int __val,
char * __s,
int __radix
)

this is quite nasty plus forces me to include all library for this one function. Why this cannot just be char* itoa(int __val) ?

also it employs next variable char* __s

sprintf is a overkill :-/

Do yourself a favour, lose the old 4bit library. The included LiquidCrystal library works with 4 bits and is far superior. The standard Library has worked with 4 bit connections since Arduino 0016

Super sweet thank you LiquidCrystal does work ... I think it creates lcd object of class LiquidCrystal which is inheritance of class Print ... that is why it is easy to update my function with:

#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

byte ip[4] = { 192, 168, 0, 10 };

void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcdPrintIp(ip);
}

void lcdPrintIp(byte ip_[])
{
    lcd.print(ip_[0],DEC); lcd.print(".");
    lcd.print(ip_[1],DEC); lcd.print(".");
    lcd.print(ip_[2],DEC); lcd.print(".");
    lcd.print(ip_[3],DEC); 
}

next step would be to add Stream functionality and overload << operator

;D

Thank you so much ::slight_smile:

By copying Streaming.h into LiquidCrystal folder we can add #include <Streaming.h> in the top section of LiquidCrystal.h and then change this basic code to look like this :

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

byte ip[4] = { 192, 168, 0, 10 };

void setup() {
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("hello, world!");
}

void loop() {
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);
  // print the number of seconds since reset:
  lcdPrintIp(ip);
}

void lcdPrintIp(byte ip_[])
{
    lcd << _DEC(ip[0]) << "." << _DEC(ip[1]) << "." << _DEC(ip[2]) << "." << _DEC(ip[3]);  
}

:sunglasses: