#include <LiquidCrystal_I2C.h>

#define SCALE_CLEAR   5    // Radio dial scale

int i;
byte needleChar[8];
float frequency = 91;

// Dial scale background
byte scaleChar[8] = {
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00000,
  0b00100,
  0b10101,
  0b10101
};

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() 
{
  // put your setup code here, to run once:
  lcd.init();
  lcd.backlight();

  // Create custom character to represent all (5) possible needle´s position
  for(int j = 0; j < 5; j++) {
    for(i = 0; i < 8; i++)
      needleChar[i] = scaleChar[i] | (0b10000 >> j);
      lcd.createChar(j, needleChar);
  }
  
  // Draw the dial scale´s background
  lcd.createChar(SCALE_CLEAR, scaleChar);
  lcd.setCursor(0, 1);
  for(i = 0; i < 16; i++){
    lcd.write(SCALE_CLEAR);
  }

  lcd.setCursor(2,0);
  lcd.print("FM  99.9 MHz");

}

void loop() {
  // put your main code here, to run repeatedly:
  updateScale();
}

/*******************************************\
 *             updateScale()               *
 * Moves the "needle" over the radio scale *
\*******************************************/
void updateScale() {
  int lcdBase = (frequency  - 88) * 4;  // LCD column pixel index (0 <= lcdBase <= (16 * 5))
  if(lcdBase > 79) lcdBase = 79;
  
  int lcdMajor = lcdBase / 5;    // LCD character index (0 <= lcdMajor <= 15)
  int lcdMinor = lcdBase % 5;    // LCD pixel column index within the character (0 <= lcdMinor <= 4)
  
  if(lcdMajor > 0) {
    // The radio dial needle is not at the leftmost position:
    // clean the character on the left (to erase previous neddle position)
    lcd.setCursor(lcdMajor  - 1, 1);
    lcd.write(SCALE_CLEAR);
  } else
    lcd.setCursor(lcdMajor, 1);
  lcd.write(lcdMinor);
  
  if(lcdMajor < 15)
    // Not at rightmost position: clear the character on the right
    lcd.write(SCALE_CLEAR);
}