/* Extracted from turret program of 11/25/17
  Program demonstrates/uses:

  PROGMEM for display text and custom character retrieval
  LCD custom character generation

  Version on IDE 2.2.1

*/
/*  ======  Library sources
*/
#include <LiquidCrystal.h>  // 1602 display

LiquidCrystal lcd(6, 7, 5, 4, A1, A0);  // define I/O pins for 1602 LCD (4-bit mode)
// 6=rs, 7=en, 5=d4, 4=d5, A1=d6, A0=d7

typedef struct {
  byte pixelDef[8];
} oneCustomChr;

const byte customChr_s = sizeof(oneCustomChr);

enum { ramUp_custom,
       ramLd_custom,
       ramDn_custom,
       rotateLeft_custom,
       rotateRight_custom,
       customA,
       customM
     };

const oneCustomChr customGrfx[] PROGMEM = {
  { 0x1f, 0x1f, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe },     // ram at top
  { 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1f, 0xe, 0xe },     // ram at load
  { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1f },     // ram at bottom
  { 0x3, 0x4, 0x8, 0x8, 0x8, 0x5, 0x3, 0x7 },       // arrow CCW
  { 0x18, 0x4, 0x2, 0x2, 0x2, 0x14, 0x18, 0x1c },   // arrow CW
  { 0x15, 0x0, 0xe, 0x11, 0x1f, 0x11, 0x0, 0x15 },  // custom chr 'A'
  { 0x15, 0x0, 0x11, 0x1b, 0x15, 0x11, 0x0, 0x15 }  // custom chr 'M'
};

const byte customChr_qty = sizeof(customGrfx) / sizeof(customGrfx[0]);  // establish the number of custom characters

/*
    END VARIABLE DECLARATIONS  --  SETUP ROUTINE
*/
void setup() {

  //Serial.begin(115200); // for debug only
  lcd.begin(16, 2);  // open comms. with 1602 display unit
  /*
       Initialize custom LCD graphic characters from PROGMEM
       - Each character's data is successively copied from PROGMEM to print
       - buffer where lcd.createChar does its work guided by i.
  */

  uint8_t lcdPrintBufr[8];  // establish a buffer for delivery & pickup of custom char data
  for (byte i = 0; i < customChr_qty; i++) {
    memcpy_P(lcdPrintBufr, &customGrfx[i], customChr_s);
    lcd.createChar(i, lcdPrintBufr);
  }

  lcd.clear(); // required to let LCD work after create chr
  lcd.print("  custom chars");
  lcd.setCursor(0, 2);

  for (byte i = 0; i < customChr_qty; i++) {
    lcd.write((byte)i);
    lcd.write(' ');
  }

}  // end of setup

//
void loop() {}