Compiling errors - lcd I2C

trying to display realtime info onLCD screen from PH probe. expanding capabilities in the future. I gained a sample code but just having difficulties tweaking it to fit my 20x4.

when I compile ‘lcd’ does not name type - error
Using library - NewliquidCrystal

arduido mega - 20x4 LCD I2C

I’ve done alot of reading and trying to no avail… I am new so IM sure its something simple…

thank you for all your insight in advance.

//Base code from Atlas i2c example available here: https://www.atlas-scientific.com/_files/code/ph-i2c.pdf
//rewritten by Carl Recktenwald Jr. Recks Design and Fabrication
//for use with the WhiteBox Labs Tentacle shield https://www.whiteboxes.ch/tentacle/
//and the Atlas EZO PH Stamp connected via i2c

//**THIS CODE WILL WORK ON ANY ARDUINO**
//This code has intentionally has been written to be overly lengthy and includes unnecessary steps.
//Many parts of this code can be truncated. This code was written to be easy to understand.
//Code efficiency was not considered. Modify this code as you see fit.
//This code will output data to the Arduino serial monitor. Type commands into the Arduino serial monitor to control the EZO pH Circuit in I2C mode.


#include <Wire.h>                //enable I2C.
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define address 99 //default I2C ID number for EZO pH Circuit.
#define I2C_0x3f
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address


byte code = 0;                   //used to hold the I2C response code.
char ph_data[20];                //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0;                //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0;                      //counter used for ph_data array.
int time_ = 2000;                 //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
float ph_float;                  //float var used to hold the float value of the pH.


void setup() {
  Wire.begin();                 //enable I2C port.
  // set the LCD type
  lcd.begin(20, 4, LCD_5x8DOTS); // initialize the lcd
  lcd.setBacklight(HIGH);

  lcd.setCursor(0, 2);
  lcd.print("Tentacle Shield");
  lcd.setCursor(1, 0);
  lcd.print("Temp:");
  lcd.setCursor(1, 10);
  lcd.print("˚F");
  lcd.setCursor(2, 0);
  lcd.print("PH:");
  lcd.setCursor(3, 0);
  lcd.print("Salinity:");
  delay(2500);
  lcd.clear();
  delay(100);
}

void loop() { //the main loop.

  Wire.beginTransmission(99);  //call the circuit by its ID number.
  Wire.write('r');                    //transmit r - this reads from the ph stamp
  Wire.endTransmission();          //end the I2C data transmission.
  delay(time_);                    //wait the correct amount of time for the circuit to complete its instruction.
  //this wait time allows it time to read a correct value

  Wire.requestFrom(99, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
  code = Wire.read();             //the first byte is the response code, we read this separately.

  while (Wire.available()) {        //are there bytes to receive.
    in_char = Wire.read();           //receive a byte.
    ph_data = in_char;            //load this byte into our array.
    i += 1;                          //incur the counter for the array element.
    if (in_char == 0) {             //if we see that we have been sent a null command.
      i = 0;                      //reset the counter i to 0.
      Wire.endTransmission();     //end the I2C data transmission.
      break;                      //exit the while loop.
    }
  }
}
//Print the PH to the LCD screen
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_data);

//take the pH value and convert it into floating point number so ph reads 7.00 instead of 7.000
ph_float = atof(ph_data);
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_float);

//Wait before asking for the PH again
delay(5000);
}

Using library - NewliquidCrystal

What is the name of the library folder, where is it located and what are the names of the files in it ?

You have a stray bracket which places some of your code outside of loop.
There are also errors in your reading of the ph device.
You are missing an index for ph_data, and the terminating null character is ‘\0’

//Base code from Atlas i2c example available here: https://www.atlas-scientific.com/_files/code/ph-i2c.pdf
//rewritten by Carl Recktenwald Jr. Recks Design and Fabrication
//for use with the WhiteBox Labs Tentacle shield https://www.whiteboxes.ch/tentacle/
//and the Atlas EZO PH Stamp connected via i2c

//**THIS CODE WILL WORK ON ANY ARDUINO**
//This code has intentionally has been written to be overly lengthy and includes unnecessary steps.
//Many parts of this code can be truncated. This code was written to be easy to understand.
//Code efficiency was not considered. Modify this code as you see fit.
//This code will output data to the Arduino serial monitor. Type commands into the Arduino serial monitor to control the EZO pH Circuit in I2C mode.


#include <Wire.h>                //enable I2C.
//#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define address 99 //default I2C ID number for EZO pH Circuit.
#define I2C_0x3f
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address


byte code = 0;                   //used to hold the I2C response code.
char ph_data[20];                //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0;                //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0;                      //counter used for ph_data array.
int time_ = 2000;                 //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
float ph_float;                  //float var used to hold the float value of the pH.


void setup() {
  Wire.begin();                 //enable I2C port.
  // set the LCD type
  lcd.begin(20, 4, LCD_5x8DOTS); // initialize the lcd
  lcd.setBacklight(HIGH);

  lcd.setCursor(0, 2);
  lcd.print("Tentacle Shield");
  lcd.setCursor(1, 0);
  lcd.print("Temp:");
  lcd.setCursor(1, 10);
  lcd.print("˚F");
  lcd.setCursor(2, 0);
  lcd.print("PH:");
  lcd.setCursor(3, 0);
  lcd.print("Salinity:");
  delay(2500);
  lcd.clear();
  delay(100);
}

void loop() { //the main loop.

  Wire.beginTransmission(99);  //call the circuit by its ID number.
  Wire.write('r');                    //transmit r - this reads from the ph stamp
  Wire.endTransmission();          //end the I2C data transmission.
  delay(time_);                    //wait the correct amount of time for the circuit to complete its instruction.
  //this wait time allows it time to read a correct value

  Wire.requestFrom(99, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
  code = Wire.read();             //the first byte is the response code, we read this separately.

  while (Wire.available()) {        //are there bytes to receive.
    in_char = Wire.read();           //receive a byte.
    ph_data[i] = in_char;            //load this byte into our array.
    i += 1;                          //incur the counter for the array element.
    if (in_char == '\0') {             //if we see that we have been sent a null command.
      i = 0;                      //reset the counter i to 0.
      Wire.endTransmission();     //end the I2C data transmission.
      break;                      //exit the while loop.
    }
  }
//} //eliminate stray bracket

//Print the PH to the LCD screen
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_data);

//take the pH value and convert it into floating point number so ph reads 7.00 instead of 7.000
ph_float = atof(ph_data);
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_float);

//Wait before asking for the PH again
delay(5000);
}

UKHeliBob: What is the name of the library folder, where is it located and what are the names of the files in it ?

folder name: newliquidcrystal located:documents/arduino/libraries/newliquidcrystal Names of files: there are many files named LiquidCrystal with different endings "_I2C.cpp _SI2Ccpp etc. with extensions of .cpp and.h

cattledog:
You have a stray bracket which places some of your code outside of loop.
There are also errors in your reading of the ph device.
You are missing an index for ph_data, and the terminating null character is ‘\0’

OK, I think I found the stray bracket, thank you.
Still not sure of the PH reading issue about the index. – still learning… does that get defined at the beginning or at the end where sends the information to the LCD?

//Base code from Atlas i2c example available here: https://www.atlas-scientific.com/_files/code/ph-i2c.pdf
//rewritten by Carl Recktenwald Jr. Recks Design and Fabrication
//for use with the WhiteBox Labs Tentacle shield https://www.whiteboxes.ch/tentacle/
//and the Atlas EZO PH Stamp connected via i2c

//**THIS CODE WILL WORK ON ANY ARDUINO**
//This code has intentionally has been written to be overly lengthy and includes unnecessary steps.
//Many parts of this code can be truncated. This code was written to be easy to understand.
//Code efficiency was not considered. Modify this code as you see fit.
//This code will output data to the Arduino serial monitor. Type commands into the Arduino serial monitor to control the EZO pH Circuit in I2C mode.


#include <Wire.h>                //enable I2C.
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define address 99 //default I2C ID number for EZO pH Circuit.
#define I2C_0x3f
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address


byte code = 0;                   //used to hold the I2C response code.
char ph_data[20];                //we make a 20 byte character array to hold incoming data from the pH circuit.
byte in_char = 0;                //used as a 1 byte buffer to store in bound bytes from the pH Circuit.
byte i = 0;                      //counter used for ph_data array.
int time_ = 2000;                 //used to change the delay needed depending on the command sent to the EZO Class pH Circuit.
float ph_float;                  //float var used to hold the float value of the pH.


void setup() {
  Wire.begin();                 //enable I2C port.
  // set the LCD type
  lcd.begin(20, 4, LCD_5x8DOTS); // initialize the lcd
  lcd.setBacklight(HIGH);

  lcd.setCursor(0, 2);
  lcd.print("Tentacle Shield");
  lcd.setCursor(1, 0);
  lcd.print("Temp:");
  lcd.setCursor(1, 10);
  lcd.print("˚F");
  lcd.setCursor(2, 0);
  lcd.print("PH:");
  lcd.setCursor(3, 0);
  lcd.print("Salinity:");
  delay(2500);
  lcd.clear();
  delay(100);
}

void loop() { //the main loop.

  Wire.beginTransmission(99);  //call the circuit by its ID number.
  Wire.write('r');                    //transmit r - this reads from the ph stamp
  Wire.endTransmission();          //end the I2C data transmission.
  delay(time_);                    //wait the correct amount of time for the circuit to complete its instruction.
  //this wait time allows it time to read a correct value

  Wire.requestFrom(99, 20, 1); //call the circuit and request 20 bytes (this may be more then we need).
  code = Wire.read();             //the first byte is the response code, we read this separately.

  while (Wire.available() {        //are there bytes to receive.
    in_char = Wire.read();           //receive a byte.
    ph_data = in_char;            //load this byte into our array.
    i += 1;                          //incur the counter for the array element.
    if (in_char == 0) {             //if we see that we have been sent a null command.
      i = 0;                      //reset the counter i to 0.
      Wire.endTransmission();     //end the I2C data transmission.
      break;                      //exit the while loop.
    }
  }
}
//Print the PH to the LCD screen
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_data);

//take the pH value and convert it into floating point number so ph reads 7.00 instead of 7.000
ph_float = atof(ph_data);
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_float);

//Wait before asking for the PH again
delay(5000);
}

folder name: newliquidcrystal
located:documents/arduino/libraries/newliquidcrystal

In that case I am surprised that either

#include <LCD.h>

or

#include <LiquidCrystal_I2C.h>

find the library files.

Have you posted the full text of the error message(s) that you receive ?

UKHeliBob: Error message

Arduino: 1.6.9 (Mac OS X), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

ph_LCD_anth:66: error: incompatible types in assignment of 'byte {aka unsigned char}' to 'char [0]'     ph_data = in_char;            //load this byte into our array.             ^ /Users/AnthonyGenovese/Documents/Arduino/ph_LCD_anth/ph_LCD_anth.ino: At global scope: ph_LCD_anth:76: error: 'lcd' does not name a type lcd.setCursor(2, 0); ^ ph_LCD_anth:77: error: 'lcd' does not name a type lcd.print("PH:"); ^ ph_LCD_anth:78: error: 'lcd' does not name a type lcd.setCursor(2, 3); ^ ph_LCD_anth:79: error: 'lcd' does not name a type lcd.print(ph_data); ^ ph_LCD_anth:82: error: 'ph_float' does not name a type ph_float = atof(ph_data); ^ ph_LCD_anth:83: error: 'lcd' does not name a type lcd.setCursor(2, 0); ^ ph_LCD_anth:84: error: 'lcd' does not name a type lcd.print("PH:"); ^ ph_LCD_anth:85: error: 'lcd' does not name a type lcd.setCursor(2, 3); ^ ph_LCD_anth:86: error: 'lcd' does not name a type lcd.print(ph_float); ^ ph_LCD_anth:89: error: expected constructor, destructor, or type conversion before '(' token delay(5000);      ^ ph_LCD_anth:90: error: expected declaration before '}' token } ^ Using library Wire at version 1.0 in folder: /Applications/Arduino.app/Contents/Java/hardware/arduino/avr/libraries/Wire Using library NewliquidCrystal in folder: /Users/AnthonyGenovese/Documents/Arduino/libraries/NewliquidCrystal (legacy) exit status 1 incompatible types in assignment of 'byte {aka unsigned char}' to 'char [0]'

@ UK Heli Bob

I think that at some point the IDE was changed to recognize both #include<user_added_library.h> or #include “user_added_library.h”.

Either syntax appears to work for libraries packaged with the IDE or user added libraries.

The code I posted in reply #2 compiles.

I “think” got it. at lest to compile…

//Base code from Atlas i2c example available here: https://www.atlas-scientific.com/_files/code/ph-i2c.pdf
//rewritten by Carl Recktenwald Jr. Recks Design and Fabrication
//for use with the WhiteBox Labs Tentacle shield https://www.whiteboxes.ch/tentacle/
//and the Atlas EZO PH Stamp connected via i2c

//**THIS CODE WILL WORK ON ANY ARDUINO**
//This code has intentionally has been written to be overly lengthy and includes unnecessary steps.
//Many parts of this code can be truncated. This code was written to be easy to understand.
//Code efficiency was not considered. Modify this code as you see fit.
//This code will output data to the Arduino serial monitor. Type commands into the Arduino serial monitor to control the EZO pH Circuit in I2C mode.


#include <Wire.h>                //enable I2C.
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define address 99 //default I2C ID number for EZO pH Circuit.
#define I2C_0x3f
LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Set the LCD I2C address
//LiquidCrystal_I2C lcd(i2c_addr, en, rw, rs, d4, d5, d6, d7, BACKLIGHT_PIN, POSITIVE); // Set the LCD I2C address


char computerdata[20];           //we make a 20 byte character array to hold incoming data from a pc/mac/other.   
byte received_from_computer=0;   //we need to know how many characters have been received.    
byte serial_event=0;             //a flag to signal when data has been received from the pc/mac/other. 
byte code=0;                     //used to hold the I2C response code. 
char ph_data[20];                //we make a 20 byte character array to hold incoming data from the pH circuit. 
byte in_char=0;                  //used as a 1 byte buffer to store in bound bytes from the pH Circuit.   
byte i=0;                        //counter used for ph_data array. 
int time_=1800;                   //used to change the delay needed depending on the command sent to the EZO Class pH Circuit. 
float ph_float;                  //float var used to hold the float value of the pH. 


void setup() {
  Wire.begin();                 //enable I2C port.
  // set the LCD type
  lcd.begin(20, 4, LCD_5x8DOTS); // initialize the lcd
  lcd.setBacklight(HIGH);

  lcd.setCursor(0, 2);
  lcd.print("Tentacle Shield");
  lcd.setCursor(1, 0);
  lcd.print("Temp:");
  lcd.setCursor(1, 10);
  lcd.print("˚F");
  lcd.setCursor(2, 0);
  lcd.print("PH:");
  lcd.setCursor(3, 0);
  lcd.print("Salinity:");
  delay(2500);
  lcd.clear();
  delay(100);
}

void loop() { //the main loop.

  if(serial_event){            //if the serial_event=1.
        if(computerdata[0]=='c'||computerdata[0]=='r')time_=1800; //if a command has been sent to calibrate or take a reading we wait 1800ms so that the circuit has time to take the reading.  
       else time_=300;         //if any other command has been sent we wait only 300ms.
       
    
    Wire.beginTransmission(99); //call the circuit by its ID number.  
    Wire.write(computerdata);        //transmit the command that was sent through the serial port.
    Wire.endTransmission();          //end the I2C data transmission. 
    
    
    delay(time_);                    //wait the correct amount of time for the circuit to complete its instruction. 
    
    Wire.requestFrom(99,20,1); //call the circuit and request 20 bytes (this may be more than we need)
    code=Wire.read();               //the first byte is the response code, we read this separately.  
 
  while(Wire.available()){          //are there bytes to receive.  
   in_char = Wire.read();           //receive a byte.
   ph_data[i]= in_char;             //load this byte into our array.
   i+=1;                            //incur the counter for the array element. 
    if(in_char==0){                 //if we see that we have been sent a null command. 
        i=0;                        //reset the counter i to 0.
        Wire.endTransmission();     //end the I2C data transmission.
        break;                      //exit the while loop.
//Print the PH to the LCD screen
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_data);

//take the pH value and convert it into floating point number so ph reads 7.00 instead of 7.000
ph_float = atof(ph_data);
lcd.setCursor(2, 0);
lcd.print("PH:");
lcd.setCursor(2, 3);
lcd.print(ph_float);

//Wait before asking for the PH again
delay(5000);{
    }  }   } } }
  }  }   } } }
  }
      }
    }
  }
}

You need to get into the habit of running Tools > Auto Format or (control + T) on your code. It will place the brackets on their own line, and related to its leading bracket.

cattledog:
@ UK Heli Bob

I think that at some point the IDE was changed to recognize both #include<user_added_library.h> or #include “user_added_library.h”.

Either syntax appears to work for libraries packaged with the IDE or user added libraries.

The code I posted in reply #2 compiles.

What surprised me was that the library folder does not have the same name as the .h and .cpp files as I was under the impression that they had to be the same, but then again I am still using an ancient version of the IDE (1.5.6-r2) and I believe that later versions have library management functions that may alter how library files are found.

UKHeliBob:
What surprised me was that the library folder does not have the same name as the .h and .cpp files as I was under the impression that they had to be the same, but then again I am still using an ancient version of the IDE (1.5.6-r2) and I believe that later versions have library management functions that may alter how library files are found.

The IDE has never required that the name of the directory with the library files match the basename name of any of the files. Not in the past all the way back to way before 1.0 and still not now.

The IDE does a massive search looking for each header file.

Some libraries actually take advantage of this like fm’s LiquidCrystal library.
That is how it can find files like LiquidCrystal_I2C.h

The only change that has been made recently is that if the basename of a header file being included matches a directory name of a directory in one of the directories searched looking for the header then that directory takes precedence.

i.e. if there are two directories with LiquidCrystal.h and one is named LiquidCrystal then the library in LiquidCrystal wins and takes precedence.

There is a search order of directories when looking for headers,
and then this latest check bumps the priority of that directory.
Then each of the directories where a library header file was found is added to the compiler include search path.

This is a horrible way of handling libraries and the reason is that there can be “silent” collisions as there is no way to be ensured that you get the header file from the library you want in the case where there are name collisions and the directory name is not the basename of the header file.

For example suppose you have two libraries:

foo and bar
And you have
foo/foo.h
foo/bar.h

bar/bar.h

If the sketch uses just foo.h you get the foo library. If it uses just bar.h you get the bar directory.
But if the skech uses both, then it becomes possible that you end up getting
foo.h from foo and bar.h from bar which can break things.

In fact this can and does happen with fm’s library when fm’s library is installed in the user’s sketchbook, or when another LiquidCrystal_I2C library is installed. You can get part of one library and part of another, and then be linking in both which creates problems either during compiling or linking.

Over the years I have unsuccessfully lobbied the Arduino developers for an alternate way to handle includes that would allow sketches to better specify their libraries and headers.

What I wanted was to add the parent directory to the include path and allow sketches to do:

#include <dirname/filename.h>

That way in the typical case you might see something like:

#include <Wire/Wire.h>

The key is that now the sketch could be very explicit about which library it wants so there wouldn’t be be any name collision between libraries.
But each time it comes up, people don’t seem to understand the full scope of the problem for complex libraries that use sub libraries and I lose.

— bill

cattledog:
@ UK Heli Bob

I think that at some point the IDE was changed to recognize both #include<user_added_library.h> or #include “user_added_library.h”.

Either syntax appears to work for libraries packaged with the IDE or user added libraries.

The code I posted in reply #2 compiles.

using <> or “” on includes has nothing to do with this as the Arduino IDE has no requirement that the header file basename have any relationship with the directory name where the code resides.
(see my previous post)

Years ago the two types of includes were treated distinctly differently by the compiler in terms of include path processing than they are today.
But over the past few decades there is now very little difference between them and in fact “” will fall down into using the <> include path.
This was not the case years ago.

— bill

Thanks for the detailed explanation. For me this is the key fact

if the basename of a header file being included matches a directory name of a directory in one of the directories searched looking for the header then that directory takes precedence.