// Isak Hendrikse made small changes to code from user Adrian Jones to work in Wokwi
//**************************************************************************************************
// 3-line and 4-line LCD NUMBERS
// Adrian Jones, March 2015
//
//**************************************************************************************************
// Build 1
// r1 150306 - initial build
//********************************************************************************************
#define build 1
#define revision 1
//********************************************************************************************
#include <avr/pgmspace.h> // for memory storage in program space
#include <Wire.h>
#include <LiquidCrystal_I2C.h> // library for I@C interface
#define I2C_ADDR 0x27 // address found from I2C scanner
LiquidCrystal_I2C lcd(I2C_ADDR,20, 4);
//LiquidCrystal_I2C lcd(0x27,20,4); // set the LCD address to 0x27 for a 16 chars and 2 line display
//Pins for the LCD are SCL A5, SDA A4
const char custom[][8] PROGMEM = {
{0x01, 0x07, 0x0F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, // char 1: bottom right triangle
{0x00, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x1F, 0x1F}, // char 2: bottom block
{0x10, 0x1C, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F}, // char 3: bottom left triangle
{0x1F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00}, // char 4: top right triangle
{0x1F, 0x1E, 0x1C, 0x10, 0x00, 0x00, 0x00, 0x00}, // char 5: top left triangle
{0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x00}, // char 6: upper block
{0x1F, 0x1F, 0x1E, 0x1C, 0x18, 0x18, 0x10, 0x10}, // char 7: full top right triangle
{0x01, 0x07, 0x0F, 0x1F, 0x00, 0x00, 0x00, 0x00} // char 8: top right triangle
};
const char bn3[][30] PROGMEM = { // 3-line numbers
// 0 1 2 3 4 5 6 7 8 9
{0x01,0x06,0x03, 0x08,0xFF,0xFE, 0x08,0x06,0x03, 0x08,0x06,0x03, 0xFF,0xFE,0xFF, 0xFF,0x06,0x06, 0x01,0x06,0xFE, 0x06,0x06,0xFF, 0x01,0x06,0x03, 0x01,0x06,0x03},
{0xFF,0xFE,0xFF, 0xFE,0xFF,0xFE, 0x01,0x06,0x06, 0xFE,0x06,0xFF, 0x06,0x06,0xFF, 0x06,0x06,0xFF, 0xFF,0x06,0x03, 0xFE,0x01,0x07, 0xFF,0x06,0xFF, 0x04,0x06,0xFF},
{0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x06,0x06,0x06, 0x04,0x06,0x05, 0xFE,0xFE,0x06, 0x04,0x06,0x05, 0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x04,0x06,0x05, 0xFE,0xFE,0x06}
};
const char bn4[][30] PROGMEM = { // 4-line numbers
// 0 1 2 3 4 5 6 7 8 9
{0x01,0x06,0x03, 0x08,0xFF,0xFE, 0x08,0x06,0x03, 0x08,0x06,0x03, 0xFF,0xFE,0xFF, 0xFF,0x06,0x06, 0x01,0x06,0x03, 0x06,0x06,0xFF, 0x01,0x06,0x03, 0x01,0x06,0x03},
{0xFF,0xFE,0xFF, 0xFE,0xFF,0xFE, 0x02,0x02,0xFF, 0xFE,0x02,0xFF, 0xFF,0x02,0xFF, 0xFF,0x02,0x02, 0xFF,0x02,0x02, 0xFE,0x01,0x07, 0xFF,0x02,0xFF, 0xFF,0x02,0xFF},
{0xFF,0xFE,0xFF, 0xFE,0xFF,0xFE, 0xFF,0xFE,0xFE, 0xFE,0xFE,0xFF, 0xFE,0xFE,0xFF, 0xFE,0xFE,0xFF, 0xFF,0xFE,0xFF, 0xFE,0xFF,0xFE, 0xFF,0xFE,0xFF, 0xFE,0xFE,0xFF},
{0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x06,0x06,0x06, 0x04,0x06,0x05, 0xFE,0xFE,0x06, 0x04,0x06,0x05, 0x04,0x06,0x05, 0xFE,0x06,0xFE, 0x04,0x06,0x05, 0x04,0x06,0x05}
};
byte col,row,nb=0,bc=0; // general0xFE,0x01,0x07
byte bb[8]; // byte buffer for reading from PROGMEM
//*****************************************************************************************//
// Initial Setup
//*****************************************************************************************//
void setup() {
//lcd.begin(20, 4);
lcd.init(); // initialize the lcd
lcd.backlight();
for (nb=0; nb<8; nb++ ) { // create 8 custom characters
for (bc=0; bc<8; bc++) bb[bc]= pgm_read_byte( &custom[nb][bc] );
lcd.createChar ( nb+1, bb );
}
lcd.clear();
lcd.setCursor(4, 0);
lcd.print(F("3&4 Line BIG"));
lcd.setCursor(4, 1);
lcd.print(F("NUMERALS"));
lcd.setCursor(5, 3);
lcd.print(F("V"));
lcd.print(build);
lcd.print(F("."));
lcd.print(revision);
lcd.print(F(" "));
lcd.print(freeRam());
lcd.print(F("B"));
printNum4(random(0,10), 0);
printNum4(random(0,10),17);
delay(5000);
lcd.setCursor(4, 0);
lcd.print(F("3&4 Line BIG "));
}
//*****************************************************************************************//
// MAIN LOOP
//*****************************************************************************************//
void loop() {
printNum4(random(0,10), 0);
printNum3(random(0,10),17,1);
delay(500);
}
// ********************************************************************************** //
// SUBROUTINES
// ********************************************************************************** //
void printNum3(byte digit, byte leftAdjust, byte topAdjust) {
for(row=0; row<3; row++) {
lcd.setCursor(leftAdjust,row+topAdjust);
for(byte num=digit*3; num <digit*3+3; num++) {
lcd.write(pgm_read_byte( &bn3[row][num]) );
}
}
}
void printNum4(byte digit, byte leftAdjust) {
for(row=0; row<4; row++) {
lcd.setCursor(leftAdjust,row);
for(byte num=digit*3; num <digit*3+3; num++) {
lcd.write(pgm_read_byte( &bn4[row][num]) );
}
}
}
void printColon(byte leftAdjust, byte topAdjust) {
for(row=0; row<(4-topAdjust); row++) {
lcd.setCursor(leftAdjust,row+topAdjust);
if(topAdjust == 1) {
if(row == 0 || row == 1) lcd.print(F(".")); else lcd.print(F(" "));
} else {
if(row == 1 || row == 2) lcd.print(F(".")); else lcd.print(F(" "));
}
}
}
// ********************************************************************************** //
// OPERATION ROUTINES
// ********************************************************************************** //
// FREERAM: Returns the number of bytes currently free in RAM
int freeRam(void) {
extern int __bss_end, *__brkval;
int free_memory;
if((int)__brkval == 0) {
free_memory = ((int)&free_memory) - ((int)&__bss_end);
}
else {
free_memory = ((int)&free_memory) - ((int)__brkval);
}
return free_memory;
}