C64 ROM switcher, Hidden cam viewer, Motorized fader pot and PCB sponsor

Lol, got an email from a PCB sponsor!

Deeply impressed by your blog content which means a lot to electronic enthusiasts.
I'd like to sponsor your project by providing free PCB prototyping,

ROM SWITCHER

I made a rom switcher in the past.
Now I’m using an Arduino to switch Kernal and Character rom.
(Partly idea from Adrian)

Where the F* is my schematic

Above right picture:

  • Tactile button (emulates restore key)
  • Red led – reset
  • Yellow led – Exrom
  • Blue leds, Address lines select ROM part in 27512 EPROM
  • Green leds, Address lines select ROM part Character ROM

Motorized Fader Potentiometer

I don’t trust some B&B’s so I made a camera detector.
(I always scan the wifi and Access Points)
This one lets you know if there are IR enabled camera’s.
(Night vision)

Picture 1:

  • 1 = org camera module, IR filter is hard to remove. (See pink color)
  • 2 = other module, IR filter is at bottom
  • 3 = IR Filter, I removed this.

Picture 2:

IR light blast from a “hidden” camera. (I need to adjust focus of lens)

Three display C64 audio monitor

While I made this for my Commodore C64, it is applicable for many things.

It started with some cheap displays from Ali, and some leftover Wemos D1 from my Pressure Lab project.

I Started measuring the audio output from sound devices and from my C64.
I soon discovered that I needed some way to get the offset and amplification correct for the analogue input of a Wemos. (0-3v3)

So a little op-amp circuit was born, but not without some struggles.
I forgot many things about amplifiers. It was one of the first school books I got rid of. (Sorry mister Rafaela)

After searching the internet and posting a question on Reddit I ended up with the following.

R1 and R2 are 100M. The potentiometer P1 allows me to set the offset.
R3 is 1M
C1 is 100nF to decouple the audio signal from the RCA.

R4 is 47K and C2 is 330nF (thanks tycho205)
Cimportant=1/(2πfR2)
where f is the lowest frequency of interest. In this case Cimportant should be about 330nF

LM324 is a quad amplifier, leftover from another project.
Note, the SINGLE RAIL power.

P2 potentiometer is 2M (leftover) and gives me a variable amplifying opportunity.


A = Audio input

B = Setting the offset with P1

C = Setting the amplification

Below input signal (note negative values) above amplified signal with offset!

The displays are 3 Wemos controllers with a cheap I2C display.
These are just fast enough to do FFT.

Analogue in is the output from the OP-amp offsetter ..

CODE

Needs cleaning up, and a better stabilize routine.

Signal generator and Midi progress

Yesterday I got my new signal generator (FY6900), my DIY version was missing functions.
Now I can test my op-amp schematic I’ve been posting about.

MIDI Controller

Next, for my YM2203 player, I wanted to make this Midi Controllable.
But I don’t have a Midi Controller which has enough knobs and keys.
Besides that, I thought it was cool to build my own.

  • Teensy 4.0 (because I needed multiple analogue inputs, I used another controller before, with an analogue multiplexer. But I wanted to use the easy method to use USB as midi also.
    The board will also have midi connectors, but not populated yet.
    So you can use both.
  • SSD1306 display (for now)
    Showing note being played and two potentiometer values.
  • Two potentiometers (for now) I can use these separately. But when pressing the last key on the key matrix, it will change the CC Channel of the first pot. (Using the value of the second)
  • 4×4 Matrix keyboard being read by a MCP23017 I2C 16-bit GPIO Expander. Both display and GPIO expander are on the same bus.

MCP23017 pinout

I used some pullups on : /RESET and GPA0-3
Pullups not needed on SDA/CLK because these are on the display board.

Midi control YM2203 and Analog AMP stuff

While watching TV, I drew some schematics for the YM2203 player.

For another project, I was researching the best way to get the voltage levels perfect for below analogue input.

(See the little red breadboard in the right picture above! )

Damn, I couldn’t do this stuff in school. Tried to forget it all … now I need it!

Top of this image shows what I want to accomplish. Audio or other input which has negative values also, convert to another voltage range to be read by analog read on an Wemos. These can only read 0-3v3

YM2203 – next part – Midi

I took yesterday’s setup and added polyphonic Midi.

Schematic same as previous post, just added a Midi Shield.

I can use my QY100 as midi keyboard. But playing midi files is also fun!

Because it isn’t using the right instrument and not all channels are being used.

I wanted to make a register replacer, which utilizes a sdcard reader and music dump to play songs.
But I think I’m going to make a full-blown Midi song player for the YM2203.

YM2203 Player

UPDATE: FM using the DAC is also working

At the hackercamp I mentioned a few posts ago, I met a guy who was into synths and we started talking.
We discovered we have much in common.

I showed him my AY-3-8910 player, but he had some other sound chips he wanted to play with.

After we found out which ones, I decided to buy some.
And last week I started building a player for it.

Ultimate goal is to make this midi enabled.

The chip in question is a YM2203 from Yamaha. It has three channels and can do FM sounds.

Today the first sounds! (2 channels)

  • Arduino UNO (clone)
  • YM2203
  • YM3014 DAC
  • LM324 Amplifier
  • 1Mhz crystal (that’s what I could find)

Below is the schematic, code will follow. (Needs a lot of cleanup)

I used A1 for reset signal, and have not used the complete amplifying part

I think I’m going to make some kind of library/class.
For easy programming.

FM via DAC

CODE FOR PSG (Programmable Sound Generator)
(FM code will follow)

// --- Pin definitions for Arduino Uno ---
#define YM_D0   2   // D0–D7 on Arduino D2–D9
#define YM_A0   10  // Address select
#define YM_WR   11  // Write
#define YM_RD   12  // Read
#define YM_CS   13  // Chip Select
#define YM_RST  A1  // Reset

// CLK is 1Mhz
#define CLK_FREQ  1000000UL

struct Note {
  uint16_t freq; // Hz
  uint16_t dur;  // ms
  uint16_t vol;  // ms
};

// --- Simple melody table (frequencies in Hz) ---
Note melody[] = {
  {440, 400, 15}, {494, 400, 15}, {523, 400, 15}, {587, 400, 15}, // A4, B4, C5, D5
  {659, 400, 15}, {698, 400, 15}, {784, 800, 15},             // E5, F5, G5
  {0, 400, 0} // rest
};

const int melodyLength = sizeof(melody) / sizeof(Note);

// --- Setup I/O pins for YM2203 ---
void setupPins() {
  pinMode(YM_CS, OUTPUT);
  pinMode(YM_WR, OUTPUT);
  pinMode(YM_RD, OUTPUT);
  pinMode(YM_A0, OUTPUT);
  pinMode(YM_RST, OUTPUT);

  for (int i = 0; i < 8; i++) {
    pinMode(YM_D0 + i, OUTPUT);
  }

  digitalWrite(YM_CS, HIGH);
  digitalWrite(YM_WR, HIGH);
  digitalWrite(YM_RD, HIGH);
  digitalWrite(YM_RST, HIGH);
}

// --- Put 8-bit value on D0–D7 bus ---
void setDataBus(uint8_t val) {
  for (int i = 0; i < 8; i++) {
    digitalWrite(YM_D0 + i, (val >> i) & 1);
  }
}

// --- Write register/data to YM2203 ---
void ymWrite(uint8_t reg, uint8_t val) {
  digitalWrite(YM_CS, LOW);

  // Send register address
  digitalWrite(YM_A0, LOW);
  setDataBus(reg);
  digitalWrite(YM_WR, LOW); delayMicroseconds(1);
  digitalWrite(YM_WR, HIGH);

  // Send data
  digitalWrite(YM_A0, HIGH);
  setDataBus(val);
  digitalWrite(YM_WR, LOW); delayMicroseconds(1);
  digitalWrite(YM_WR, HIGH);

  digitalWrite(YM_CS, HIGH);
}

// --- Set PSG Channel A frequency ---
void setChannelAFreq(uint16_t freq) {
  if (freq == 0) {  // rest
    ymWrite(0x08, 0x00); // volume 0 (mute)
    return;
  }

  // YM2203 PSG frequency formula: Fout = clock / (16 * N)
  // N = 12-bit value
  uint16_t N = CLK_FREQ / (16UL * freq);

  ymWrite(0x00, N & 0xFF);         // Freq LSB
  ymWrite(0x01, (N >> 8) & 0x0F);  // Freq MSB
}

// --- Set PSG Channel B frequency ---
void setChannelBFreq(uint16_t freq) {
  if (freq == 0) {  // rest
    ymWrite(0x09, 0x00); // volume 0 (mute)
    return;
  }

  // YM2203 PSG frequency formula: Fout = clock / (16 * N)
  // N = 12-bit value
  uint16_t N = CLK_FREQ / (16UL * freq);

  ymWrite(0x02, N & 0xFF);         // Freq LSB
  ymWrite(0x03, (N >> 8) & 0x0F);  // Freq MSB
}

// --- Set PSG Channel C frequency ---
void setChannelAFreq(uint16_t freq) {
  if (freq == 0) {  // rest
    ymWrite(0x0A, 0x00); // volume 0 (mute)
    return;
  }

  // YM2203 PSG frequency formula: Fout = clock / (16 * N)
  // N = 12-bit value
  uint16_t N = CLK_FREQ / (16UL * freq);

  ymWrite(0x04, N & 0xFF);         // Freq LSB
  ymWrite(0x05, (N >> 8) & 0x0F);  // Freq MSB
}

// --- Set PSG Channel A volume ---
void setChannelAVol(uint8_t vol) {
  ymWrite(0x08, vol);             
}
// --- Set PSG Channel B volume ---
void setChannelAVol(uint8_t vol) {
  ymWrite(0x09, vol);             
}
// --- Set PSG Channel C volume ---
void setChannelAVol(uint8_t vol) {
  ymWrite(0x0A, vol);             
}

// --- Arduino setup ---
void setup() {
  setupPins();

  // Reset YM2203
  digitalWrite(YM_RST, LOW);
  delay(100);
  digitalWrite(YM_RST, HIGH);
  delay(100);

  // Enable PSG Channel A tone, disable noise
  ymWrite(0x07, 0b11111110); // bit0=0 enables tone A
//  ymWrite(0x07, 0b11111101); // bit1=0 enables tone B
//  ymWrite(0x07, 0b11111011); // bit2=0 enables tone C
}

// --- Play melody in loop ---
void loop() {
  for (int i = 0; i < melodyLength; i++) {
    setChannelAFreq(melody[i].freq);
    setChannelAVol(melody[i].vol);
    delay(melody[i].dur);
  }
}

Retro stuff

A new “old” book, printed via Lulu

Plexiglass case for my collection of motherboards (8088,8086,386 and 486)
See this post:

A Ben Eater 6502 add-on, A bus monitor using ULN2803A.

Not all green/yellow wires are drawn. You can figure out where to add them.

I made these on a breadboard long ago, these will be made on permboards. (Like my Clock module on steroids.

ULN2803 will draw nearly no power from your bus, but they invert the signal, that’s why I rotated the ledbars and attached them to VCC.

UPDATE: Added other modules

Little Oled audio monitors.

UPDATE : Better waveform display

I wanted to make a SID monitor to display the 3 Channels of a C64 SID chip. This requires 3 SID chips, so this is a work-in-progress.

I bought several display I2C 128*32 in China, for cheap .. to have some stock .. So much for having stock.

But monitoring works! I’ve made 3 setups using a Wemos D1

Monitoring, scrolling monitoring and FFT analysis.

When mode selector using a button works, I’ll post the code.

UPDATE : New waveform display, better centered.

Meanwhile, practice SMD soldering.

Mini midi monitor

Two versions of a mini monitor

A version using a Arduino and a Midi shield (Yellow wires are for display)
D0 (RX) is used for the Midi IN signal.

10K pullups SDA/CLK

Above a Teensy 4.0 version. This one uses MIDI over USB.

Next to add: Rotary encoders, to select a CC Channel and display values graphically

CODE for Teensy version

#include <U8g2lib.h>
#include <Wire.h>
#include <MIDIUSB.h>   // Teensy's built-in USB MIDI

// SH1106 128x64 I2C constructor
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

void setup() {
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x12_tf);
  u8g2.drawStr(0,12,"MIDI Monitor Ready");
  u8g2.sendBuffer();
}

void loop() {
  // Check for incoming MIDI

  while (usbMIDI.read()) {
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_6x12_tf);
  u8g2.drawStr(0,12,"MIDI Monitor Ready");
  u8g2.sendBuffer();
    byte type = usbMIDI.getType();
    byte channel = usbMIDI.getChannel();
    byte data1 = usbMIDI.getData1();
    byte data2 = usbMIDI.getData2();

    int y = 24;

    if (type == usbMIDI.NoteOn && data2 > 0) {
      u8g2.setCursor(0, y);      u8g2.print("Note ON     "); // pad
      u8g2.setCursor(0, y+12);   u8g2.printf("Ch:%-3d", channel);  // pad width 3
      u8g2.setCursor(0, y+24);   u8g2.printf("Note:%-3d", data1);
      u8g2.setCursor(0, y+36);   u8g2.printf("Vel:%-3d", data2);
    } 
    else if (type == usbMIDI.NoteOff || (type == usbMIDI.NoteOn && data2 == 0)) {
      u8g2.setCursor(0, y);      u8g2.print("Note OFF    "); // pad
      u8g2.setCursor(0, y+12);   u8g2.printf("Ch:%-3d", channel);
      u8g2.setCursor(0, y+24);   u8g2.printf("Note:%-3d", data1);
    } 
    else if (type == usbMIDI.ControlChange) {
      u8g2.setCursor(0, y);      u8g2.print("Control Chg ");
      u8g2.setCursor(0, y+12);   u8g2.printf("Ch:%-3d", channel);
      u8g2.setCursor(0, y+24);   u8g2.printf("CC#:%-3d", data1);
      u8g2.setCursor(0, y+36);   u8g2.printf("Val:%-3d", data2);
    } 
    else {
      u8g2.setCursor(0, y);      u8g2.print("Other MIDI  ");
      u8g2.setCursor(0, y+12);   u8g2.printf("Type:%-3d", type);
    }

    u8g2.sendBuffer();
  }
}

CODE for Arduino plus shield

#include <U8g2lib.h>
#include <Wire.h>
#include <MIDI.h>   // FortySevenEffects MIDI library

// SH1106 128x64 I2C (page buffer, low RAM)
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

// MIDI on hardware Serial (RX=D0)
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI);

char line[12];  // small buffer for formatting

void setup() {
  u8g2.begin();
  u8g2.setFont(u8g2_font_6x12_tf); // proportional font, small size

  // Initial message
  u8g2.firstPage();
  do {
    u8g2.setCursor(0, 12);
    u8g2.print("MIDI Monitor Ready");
  } while (u8g2.nextPage());

  MIDI.begin(MIDI_CHANNEL_OMNI);  // listen to all channels
}

void loop() {
  if (MIDI.read()) {
    byte type    = MIDI.getType();
    byte channel = MIDI.getChannel();
    byte data1   = MIDI.getData1();
    byte data2   = MIDI.getData2();

    // Page buffer redraw
    u8g2.firstPage();
    do {
      // Title
      u8g2.setCursor(0, 12);
      u8g2.print("MIDI Monitor");

      int y = 24; // start lower down

      if (type == midi::NoteOn && data2 > 0) {
        u8g2.setCursor(0, y);      
        u8g2.print("Note ON   ");

        snprintf(line, sizeof(line), "Ch:%-3d", channel);
        u8g2.setCursor(0, y+12);   u8g2.print(line);32

        snprintf(line, sizeof(line), "Note:%-3d", data1);
        u8g2.setCursor(0, y+24);   u8g2.print(line);

        snprintf(line, sizeof(line), "Vel:%-3d", data2);
        u8g2.setCursor(0, y+36);   u8g2.print(line);
      } 
      else if (type == midi::NoteOff || (type == midi::NoteOn && data2 == 0)) {
        u8g2.setCursor(0, y);      
        u8g2.print("Note OFF  ");

        snprintf(line, sizeof(line), "Ch:%-3d", channel);
        u8g2.setCursor(0, y+12);   u8g2.print(line);

        snprintf(line, sizeof(line), "Note:%-3d", data1);
        u8g2.setCursor(0, y+24);   u8g2.print(line);
      } 
      else if (type == midi::ControlChange) {
        u8g2.setCursor(0, y);      
        u8g2.print("Control Chg");

        snprintf(line, sizeof(line), "Ch:%-3d", channel);
        u8g2.setCursor(0, y+12);   u8g2.print(line);

        snprintf(line, sizeof(line), "CC#:%-3d", data1);
        u8g2.setCursor(0, y+24);   u8g2.print(line);

        snprintf(line, sizeof(line), "Val:%-3d", data2);
        u8g2.setCursor(0, y+36);   u8g2.print(line);
      } 
      else {
        u8g2.setCursor(0, y);      
        u8g2.print("Other MIDI");

        snprintf(line, sizeof(line), "Type:%-3d", type);
        u8g2.setCursor(0, y+12);   u8g2.print(line);
      }
    } while (u8g2.nextPage());
  }
}

ESPHome HA notification helper

A while ago I made a little notify thingy using an LCD display, LED, button and a buzzer.

Some friends of mine made one also, and today I was talking to a new guy.
I could not find this project on my site .. again .. so I’ll post it now.

Some things it does right now

  • Front door opens
  • Door bell rings (because my lab is in the garden)
  • Girlfriend is 10Km away, so let’s start cooking
  • Garage door opens (friend of mine uses this to know when kids arrive)
  • More .. because it’s very easy to customize in Home Assistant

Doorbell pressed: Led starts blinking, backlight LCD enabled, text displayed on LCD, Buzzer sounds (or plays a RTTTL ringtone)
LCD backlight on and buzzer beep until acknowledge button pressed.

Heating for brewing: temperature on display, led on when temperature reached. Press acknowledge to start timer.

….. etc

CODE:

esphome:
  name: lcdalarm
  friendly_name: LCDAlarm
  on_boot:
    priority: -100.0
    then:
      - lambda: 'id(lcddisplay).no_backlight();'

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "OOpDzMu0VvfWAnJXXXXXXXXXXXXXXXXXXXXXXXXKNDa74OJ1Cc="

ota:
   - platform: esphome
     password: "627992017XXXXXXXXXXXXXXX738c2a3"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lcdalarm Fallback Hotspot"
    password: "z9dZXXXXXXXX7a"

captive_portal:
web_server:
  port: 80

i2c:
  sda: D2
  scl: D1
  scan: true
  frequency: 400kHz

light:
  - platform: binary
    name: "Status LED"
    output: light_output
    icon: "mdi:led-on"
    id: led


binary_sensor:
  - platform: gpio
    pin:
      inverted: true
      number: D5
      mode:
        input: true
        pullup: true
    name: "LCD Button"

text_sensor:
  # Create text input helper in homeassistant and enter id below
  - platform: homeassistant
    entity_id: input_text.lcd_display_text
    id: lcd_display_text

  - platform: wifi_info
    ip_address:
      id: ip_address
      name: IP address
    mac_address:
      id: mac_address
      name: Mac address
    ssid:
      id: connected_ssid
      name: Network SSID
    bssid:
      id: connected_
      name: Network Mac

sensor:
  - platform: wifi_signal
    id: wifisignal
    name: wifi-signal
    update_interval: 300s

globals:
  - id: backlight_on
    type: bool
    initial_value: 'false'
  - id: flash_beep_on
    type: bool
    initial_value: 'false'

switch:
  - platform: template
    name: "LCD Backlight"
    id: backlight
    restore_mode: RESTORE_DEFAULT_OFF
    turn_on_action:
      - globals.set:
          id: backlight_on
          value: 'true'
      - globals.set:
          id: flash_beep_on
          value: 'false'
      - lambda: |-
          id(lcddisplay).backlight();
      - delay: 5s
    turn_off_action:
      - globals.set:
          id: backlight_on
          value: 'false'
      - lambda: |-
            id(lcddisplay).no_backlight();
    lambda: |-
      return id(backlight_on);

  - platform: template
    name: "Flash and Beep"
    id: flash_beep
    restore_mode: RESTORE_DEFAULT_OFF
    turn_on_action:
      - globals.set:
          id: flash_beep_on
          value: 'true'
      - globals.set:
          id: backlight_on
          value: 'false'
      - lambda: |-
          id(lcddisplay).backlight();
      - lambda: |-
          id(buzzer).turn_on();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).no_backlight();
      - lambda: |-
          id(buzzer).turn_off();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).backlight();
      - lambda: |-
          id(buzzer).turn_on();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).no_backlight();
      - lambda: |-
          id(buzzer).turn_off();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).backlight();
      - lambda: |-
          id(buzzer).turn_on();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).no_backlight();
      - lambda: |-
          id(buzzer).turn_off();
      - delay: 0.75s
      - lambda: |-
          id(lcddisplay).backlight();
    turn_off_action:
      - globals.set:
          id: flash_beep_on
          value: 'false'
      - lambda: |-
            id(lcddisplay).no_backlight();
      - lambda: |-
          id(buzzer).turn_off();
    lambda: |-
      return id(flash_beep_on);


  - platform: restart
    name: "Restart ESPhome"

output:
  - platform: gpio
    pin: D3
    id: buzzer
  - platform: gpio
    pin: D6
    id: light_output

display:
  - platform: lcd_pcf8574
    id: lcddisplay
    dimensions: 16x2
    address: 0x27
    lambda: |-
      if(id(wifisignal).has_state()) {
        if (id(lcd_display_text).state != "") {
          it.print(0, 0, id(lcd_display_text).state.c_str());
        }
      } else {
        it.print("    ESPhome        booting...   ");
      }

CODE: RTTTL (Use passive buzzer!!!!)

esphome:
  name: lablcd
  friendly_name: LabLCD

esp8266:
  board: d1_mini

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "ga17mNCtxdiXXXXXXXXXXXXXXXXXXXXX70a5W0VPZR51Q="
  actions:
    - action: rtttl_play
      variables:
        song_str: string
      then:
        - rtttl.play:
            rtttl: !lambda 'return song_str;'

ota:
  - platform: esphome
    password: "84013b9XXXXXXXXXXXXXXX5401039f7c"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Lablcd Fallback Hotspot"
    password: "nnzXXXXXXXXXXXXXXXXXXXCb"

rtttl:
  output: rtttl_out
  on_finished_playback:
    - logger.log: 'Song ended!'


captive_portal:

i2c:
  sda: D2
  scl: D1
  scan: true
  frequency: 400kHz

light:
  - platform: status_led
    name: "Status LED"
    icon: "mdi:led-on"
    pin:
      number: D5
      inverted: true

binary_sensor:
  - platform: gpio
    name: "Push Button"
    pin: 
      number: D4
      inverted: true
      mode: 
        input: true
        pullup: true
    on_press:
      - homeassistant.service:
          service: homeassistant.toggle
          data:
            entity_id: input_boolean.esphome_notification_lcdlab_push_button

text_sensor:
  # Create text input helper in homeassistant and enter id below
  - platform: homeassistant
    entity_id: input_text.esphome_notification_lcdlcd_display_text
    id: lcd_display_text

  - platform: wifi_info
    ip_address:
      id: ip_address
      name: IP address
    mac_address:
      id: mac_address
      name: Mac address
    ssid:
      id: connected_ssid
      name: Network SSID
    bssid:
      id: connected_
      name: Network Mac

sensor:
  - platform: wifi_signal
    id: wifisignal
    name: wifi-signal
    update_interval: 300s

globals:
  - id: backlight_on
    type: bool
    initial_value: 'false'
  - id: flash_beep_on
    type: bool
    initial_value: 'false'

switch:
  - platform: template
    name: "LCD Backlight Lab"
    id: backlight
    restore_mode: RESTORE_DEFAULT_OFF
    turn_on_action:
      - globals.set:
          id: backlight_on
          value: 'true'
      - globals.set:
          id: flash_beep_on
          value: 'false'
      - lambda: |-
          id(lcddisplay).backlight();
    turn_off_action:
      - globals.set:
          id: backlight_on
          value: 'false'
      - lambda: |-
            id(lcddisplay).no_backlight();
    lambda: |-
      return id(backlight_on);

 
  - platform: restart
    name: "Restart ESPhome"

output:
  - platform: esp8266_pwm
    pin: D8
    id: rtttl_out

display:
  - platform: lcd_pcf8574
    id: lcddisplay
    dimensions: 16x2
    address: 0x27
    lambda: |-
      if(id(wifisignal).has_state()) {
        if (id(lcd_display_text).state != "") {
          it.print(0, 0, id(lcd_display_text).state.c_str());
        }
      } else {
        it.print("    ESPhome        booting...   ");
      }


"If something is worth doing, it's worth overdoing."