Go Down

Topic: Using LiquidCrystal.h within a library. (Read 958 times) previous topic - next topic

BigusDickus

Hi,

I've been working (successfully) with the LiquidCrystal.h library, and I now want to incorporate it into a library of my own (a library that will include some custom characters beyond the normal ascii stuff).

I'm having a couple of problems building my new library because
1)   I'm not sure how to handle constructors that require parameters, and
2)   I don't understand how the 'begin' method defined in the LiquidCrystal.h library seems to be defined with three parameters, but works happily with two. (is charsize = LCD_5x8DOTS a default for the 3rd parameter?)

I've attached my library files....
LCDvario.h
Code: [Select]
#ifndef LCDvario_h                         // These lines (together with the #endif at the end of the file) prevent
#define LCDvario_h                         // any problems occuring if this library should be included twice.

extern "C" {
  #include <string.h>
}

#include <stdlib.h>                        // needed for 'free'
#include "WProgram.h"                      // needed for 'Serial'
#include <avr/pgmspace.h>                  // Needed for PROGMAN stuff
#include <ProgmemConst.h>                  // Global progmem constants
#include <Wire.h>                          // Needed for I2C comms.
#include <LiquidCrystal.h>                 // Drives the LCD screen
#include <inttypes.h>



class LCDvario
{
  public:
    LCDvario(uint8_t rs, uint8_t enable,uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);                                   // Constructor
    //void begin();                                 
    void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);// initialise stuff

  private:
    // Member variables

    LiquidCrystal _lcd;       // This would work if the constructor didn't require parameters
    //LiquidCrystal _lcd(rs, enable, d0,  d1,  d2, d3);
    //LiquidCrystal * _lcd;
    //LiquidCrystal _lcd(uint8_t rs, uint8_t enable,uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
    //LiquidCrystal _lcd(rs, enable, d0,  d1,  d2, d3);

};
#endif


LCDvario.cpp
Code: [Select]
extern "C" {
  #include <string.h>
}

#include <stdlib.h>                        // needed for 'free'
#include "WProgram.h"                      // needed for 'Serial'
#include <avr/pgmspace.h>                  // Needed for PROGMAN stuff
#include <ProgmemConst.h>
#include <Wire.h>
#include <math.h>                          // needed for log functions
#include "LCDvario.h"                      // Header for this library
#include <LiquidCrystal.h>                 // Drives the LCD screen
#include <inttypes.h>


LCDvario::LCDvario(uint8_t rs,uint8_t enable,uint8_t d0,uint8_t d1,uint8_t d2,uint8_t d3)
{
  //_lcd(rs,enable,d0,d1,d2,d3);
  //_lcd=new LiquidCrystal(rs,enable,d0,d1,d2,d3);
  _lcd._lcd(rs,enable,d0,d1,d2,d3);
  //_lcd::_lcd(rs,enable,d0,d1,d2,d3);
}

//void LCDvario::begin()
//{
//  // initailise the LCD
//  //_lcd.begin(16, 2);
//}
//
void LCDvario::begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS)
{
  _lcd.begin(cols, rows);
}



And the very basic sketch to test this
Code: [Select]

#include <stdlib.h>                        // needed for 'free'
#include "WProgram.h"                      // needed for 'Serial'
#include <Wire.h>                          // Library to control I2C comunications
#include <avr/pgmspace.h>                  // Needed for PROGMAN stuff
#include <ProgmemConst.h>                  // Global progmem constants
#include <LiquidCrystal.h>                 // Controls access to the LCD display
#include <LCDvario.h>                      // LCD screen customised for vario use.

const int rs=8,en=9,d4=10,d5=11,d6=12,d7=13;  // Pin definitions for LCD

LCDvario lcd(rs, en, d4, d5, d6, d7);    // Display

void setup()
{
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);

}

void loop()
{
}


As you can see from all the commented-out lines, I've several different methods of invoking the constructor, all of which give a slightly different error, but "no matching function for call to 'LiquidCrystal::LiquidCrystal()'" seems to be the most frequent one.

Any help appreciated.

dc42

#1
Oct 11, 2012, 10:24 am Last Edit: Oct 11, 2012, 10:26 am by dc42 Reason: 1
Your .h file looks OK to me. You need to make at least two changes to your .cpp file:

1. Change:

Code: [Select]
LCDvario::LCDvario(uint8_t rs,uint8_t enable,uint8_t d0,uint8_t d1,uint8_t d2,uint8_t d3)

to:

Code: [Select]
LCDvario::LCDvario(uint8_t rs,uint8_t enable,uint8_t d0,uint8_t d1,uint8_t d2,uint8_t d3) : _lcd(rs,enable,d0,d1,d2,d3)

That's how you initialize a member variable of a type that doesn't have a default constructor.

2. Change:

Code: [Select]
void LCDvario::begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS)

to:

Code: [Select]
void LCDvario::begin(uint8_t cols, uint8_t rows, uint8_t charsize)

Default parameter values are declared only in the prototype, not in a separate implementation.

It's not essential, but in the .h file I would replace:

Code: [Select]

extern "C" {
 #include <string.h>
}

#include <stdlib.h>                        // needed for 'free'


by:

Code: [Select]

#include <cstring>
#include <cstdlib>                        // needed for 'free'


Finally, I strongly advise against calling 'free' or doing any other sort of dynamic memory allocation & freeing in embedded software, other than (if needed) allocations during the startup phase that are never freed. See http://eschertech.com/articles/items/art100730.html for why.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

BigusDickus

Thanks dc42,

Clear, concise and complete - that worked just fine, if only all responses could be like that!

Kind Regards

Go Up