I show you the complete drawing of the "car" since my tire is still flat 
The keypad PCB:
The LCD PCB:
The test sketch:
#ifndef ARDUINO_AVR_UNO
#error Must use a UNO card
#endif
#include <Board_4x4_keypad.h>
#include <Board_2x1602LCD.h>
const uint8_t keypadAdr = 0x38;
Board_4x4_keypad keypad(keypadAdr);
const uint8_t lcdAdr1 = 0x27;
const uint8_t lcdAdr2 = 0x26;
Board_2x1602LCD lcds(lcdAdr1, lcdAdr2);
void setup()
{
Serial.begin(9600);
Serial.println(F("\n\n\nInitialzing..."));
// Set up the LCD displays.
Serial.println(F("Initializing LCDs"));
lcds.setup();
lcds[0].print(F("Initializing"));
// Set up the keyboard.
lcds[0].setCursor(0, 1);
lcds[0].print(F("Keypad..."));
keypad.setup();
}
void loop()
{
char key = keypad.getKey();
if (key) {
lcds[0].setCursor(0, 1);
lcds[0].print(key);
}
}
Libraries:
#ifndef BOARD_2X1602LCD_H_INCLUDED
#define BOARD_2X1602LCD_H_INCLUDED
#include <Wire.h>
#include <MyLcd_I2C.h>
const uint8_t lcdLineLength = 16;
const uint8_t lcdColumnCount = 2;
class Board_2x1602LCD
{
private:
uint8_t m_adr1;
uint8_t m_adr2;
MyLcd_I2C *m_lcd[2];
public:
Board_2x1602LCD(const uint8_t adr1, const uint8_t adr2);
virtual ~Board_2x1602LCD();
void setup();
void backlight(const bool on);
MyLcd_I2C &operator [] (int i);
};
#endif
#include "Board_2x1602LCD.h"
Board_2x1602LCD::Board_2x1602LCD(const uint8_t adr1, const uint8_t adr2)
{
m_adr1 = adr1;
m_adr2 = adr2;
m_lcd[0] = new MyLcd_I2C(m_adr1, 16, 2);
m_lcd[1] = new MyLcd_I2C(m_adr2, 16, 2);
}
Board_2x1602LCD::~Board_2x1602LCD()
{
delete m_lcd[0];
delete m_lcd[1];
}
void Board_2x1602LCD::setup()
{
for (int i = 0; 2 > i; i++) {
m_lcd[i]->begin();
m_lcd[i]->backlight();
m_lcd[i]->setCursor(0, 0);
}
}
void Board_2x1602LCD::backlight(const bool on)
{
if (on) {
m_lcd[0]->backlight();
m_lcd[1]->backlight();
} else {
m_lcd[0]->noBacklight();
m_lcd[1]->noBacklight();
}
}
MyLcd_I2C &Board_2x1602LCD::operator [] (int i)
{
if (0 == i || 1 == i) {
return *(m_lcd[i]);
}
return *(m_lcd[0]);
}
#ifndef MY_LCD_I2C_INCLUDED
#define MY_LCD_I2C_INCLUDED
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
class MyLcd_I2C : public LiquidCrystal_I2C
{
private:
uint8_t m_cols;
uint8_t m_rows;
public:
MyLcd_I2C(uint8_t lcd_addr, uint8_t lcd_cols, uint8_t lcd_rows);
void clearLine(const int lineNumber, const bool firstPos = true);
size_t writeLine(const int lineNumber, const char *string);
size_t writeLine(const int lineNumber, const __FlashStringHelper* string);
void at(const int lineNumber, const int cursorPosition, const char *string);
void at(const int lineNumber, const int cursorPosition, const __FlashStringHelper *string);
uint8_t getCols() const {return m_cols;}
uint8_t getRows() const {return m_rows;}
};
#endif
#include <Arduino.h>
#include "MyLcd_I2C.h"
MyLcd_I2C::MyLcd_I2C(uint8_t lcd_addr, uint8_t lcd_cols, uint8_t lcd_rows)
: LiquidCrystal_I2C(lcd_addr, lcd_cols, lcd_rows)
{
m_cols = lcd_cols;
m_rows = lcd_rows;
}
void MyLcd_I2C::clearLine(const int lineNumber, const bool firstPos)
{
if (lineNumber < m_rows) {
setCursor(0, lineNumber);
for (int i = 0; m_cols > i; i++) {
write(' ');
}
if (firstPos) {
setCursor(0, lineNumber);
}
}
}
size_t MyLcd_I2C::writeLine(const int lineNumber, const char *string)
{
if (lineNumber < m_rows) {
clearLine(lineNumber);
return print(string);
}
return 0;
}
size_t MyLcd_I2C::writeLine(const int lineNumber, const __FlashStringHelper* string)
{
size_t n = 0;
if (lineNumber < m_rows) {
clearLine(lineNumber);
PGM_P p = reinterpret_cast<PGM_P>(string);
while (true) {
unsigned char c = pgm_read_byte(p++);
if (0 == c) {
break;
}
if (!write(c)) {
break;
}
++n;
}
}
return n;
}
void MyLcd_I2C::at(const int lineNumber, const int cursorPosition, const char *string)
{
if (lineNumber < m_rows) {
setCursor(cursorPosition, lineNumber);
print(string);
}
}
void MyLcd_I2C::at(const int lineNumber, const int cursorPosition, const __FlashStringHelper *string)
{
if (lineNumber < m_rows) {
setCursor(cursorPosition, lineNumber);
print(string);
}
}
#ifndef BOARD_4x4_KEYAPD_PCF8574A_H_INCLUDED
#define BOARD_4x4_KEYAPD_PCF8574A_H_INCLUDED
#include <Keypad_I2C.h>
class Board_4x4_keypad : public Keypad_I2C {
private:
uint8_t m_adr;
static char keys[4][4];
static byte colPins[4];
static byte rowPins[4];
public:
Board_4x4_keypad(const uint8_t adr);
~Board_4x4_keypad();
void setup();
};
#endif
#include "Board_4x4_keypad.h"
char Board_4x4_keypad::keys[4][4] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte Board_4x4_keypad::colPins[4] = {0, 1, 2, 3};
byte Board_4x4_keypad::rowPins[4] = {4, 5, 6, 7};
Board_4x4_keypad::Board_4x4_keypad(const uint8_t adr) : Keypad_I2C(makeKeymap(keys), rowPins, colPins, 4, 4, adr, W_PCF8574)
{
m_adr = adr;
}
Board_4x4_keypad::~Board_4x4_keypad()
{
}
void Board_4x4_keypad::setup()
{
Wire.begin();
begin(makeKeymap(keys));
}
So, why is my tire still flat? 