Chat


How can I help you?

Explain project
Write a project description
Find schematic issues

Final Firmware & Flashing Instructions — Modern Distortion Effect Pedal V1
Final Firmware & Flashing Instructions — ATtiny212 Relay Bypass Distortion Pedal

1. Overview
This is the final base firmware for the ATtiny212 used in a distortion pedal with relay bypass switching.
Functions:
  • PA3 reads the footswitch.
  • PA1 controls relay K2 through Q2.
  • PA2 controls the LED.
  • PA6 controls U4 mute / anti-pop photorelay.
  • One footswitch click toggles the pedal ON/OFF.
  • In distortion mode: relay ON, LED ON.
  • In bypass mode: relay OFF, LED OFF.
  • PA6 turns mute ON only briefly during relay switching, then returns LOW so it does not mute EFFECT_OUT.

2. ATtiny212 Pin Mapping

ATtiny212 Pin Mapping

Text


PA3 / PIN_PA3 = footswitch input
PA1 / PIN_PA1 = relay control output
PA2 / PIN_PA2 = LED indicator
PA6 / PIN_PA6 = anti-pop mute / photorelay control
Logic:

Text


Relay PA1:
LOW  = bypass / relay OFF
HIGH = distortion / relay ON

LED PA2:
HIGH = LED OFF
LOW  = LED ON

Mute PA6:
LOW  = mute OFF / normal audio
HIGH = mute ON / EFFECT_OUT muted

3. Expected Behavior
At power-up:

Text


Effect OFF / bypass
PA1 = LOW
LED OFF
PA6 = LOW
First footswitch click:

Text


Effect ON / distortion
PA1 = HIGH
Relay ON
LED ON
PA6 briefly HIGH during switching, then LOW
Next footswitch click:

Text


Effect OFF / bypass
PA1 = LOW
Relay OFF
LED OFF
PA6 briefly HIGH during switching, then LOW

4. Required Software
Windows / macOS
  1. Install Arduino IDE 2.x.

    image

  2. Install megaTinyCore.
  3. Prepare Arduino Uno or Nano as a jtag2updi programmer.

5. Installing megaTinyCore
Open Arduino IDE:

Text


File → Preferences
On macOS:

image

Text


Arduino IDE → Settings
In:

Text


Additional Boards Manager URLs

image

add:

Text


http://drazzy.com/package_drazzy.com_index.json

image

Then open:

Text


Tools → Board → Boards Manager
Search for:

Text


megaTinyCore

image

Install:

Text


megaTinyCore by Spence Konde

6. Preparing Arduino Uno/Nano as jtag2updi
  1. Download or open the jtag2updi project.
  2. In Arduino IDE, select the programmer board.
For Uno:

Text


Tools → Board → Arduino AVR Boards → Arduino Uno
For Nano:

Text


Tools → Board → Arduino AVR Boards → Arduino Nano
Tools → Processor → ATmega328P or ATmega328P Old Bootloader
  1. Select the correct port:

Text


Tools → Port
  1. Open jtag2updi.ino.
  2. Press the normal Upload button.
  3. Wait for:

Text


Done uploading
After this, the Arduino Uno/Nano works as a UPDI programmer.

7. Wiring the Programmer to ATtiny212
Connection:

Text


Arduino D6  → 4.7 kΩ → PA0 / UPDI ATtiny212
Arduino GND → target board GND
Arduino 5V  → target board +5V

image

For the first programming test, it is better not to connect the pedal 9V supply. Power the target board from the Arduino programmer 5V.
If the Arduino resets during programming, add a capacitor:

Text


10 µF between RESET and GND on Arduino
capacitor + → RESET
capacitor - → GND

8. Arduino IDE Settings for ATtiny212

image

Select:

Text


Tools → Board → megaTinyCore → ATtiny412/402/212/202
Tools → Chip → ATtiny212
Tools → Clock → 16 MHz internal
Tools → Programmer → jtag2updi
Tools → Port → Arduino programmer port

image

Do not use the normal Upload button.
Use:

Text


Sketch → Upload Using Programmer

image

On Windows:

Text


Ctrl + Shift + U
On macOS:

Text


Command + Shift + U
A successful upload should finish without red avrdude errors.

9. Final Firmware Code
Save the following code as:

Text


distortion_relay_bypass_attiny212.ino

Cpp


/*
  Final Distortion Pedal Relay Bypass Firmware
  MCU: ATtiny212
  Core: Arduino IDE + megaTinyCore

  Footswitch type:
  - Latching / maintained footswitch
  - One physical click toggles effect ON/OFF once

  Pin mapping:
  PA3 = footswitch input
  PA1 = relay driver output, active HIGH
  PA2 = LED indicator, active LOW
  PA6 = anti-pop mute / photorelay control

  Logic:
  Effect OFF / bypass:
    PA1 LOW
    LED OFF
    PA6 LOW

  Effect ON / distortion:
    PA1 HIGH
    LED ON
    PA6 LOW

  PA6 HIGH is used only briefly during relay switching for anti-pop mute.
*/

#include <Arduino.h>

// Pins
constexpr uint8_t FOOTSWITCH_PIN = PIN_PA3;
constexpr uint8_t RELAY_PIN      = PIN_PA1;
constexpr uint8_t LED_PIN        = PIN_PA2;
constexpr uint8_t MUTE_PIN       = PIN_PA6;

// Relay logic
constexpr uint8_t RELAY_ON  = HIGH;
constexpr uint8_t RELAY_OFF = LOW;

// LED is active LOW
constexpr uint8_t LED_ON  = LOW;
constexpr uint8_t LED_OFF = HIGH;

// U4 photorelay mute logic
// PA6 HIGH = mute ON
// PA6 LOW  = mute OFF / normal audio
constexpr uint8_t MUTE_ON  = HIGH;
constexpr uint8_t MUTE_OFF = LOW;

// Timing
constexpr unsigned long DEBOUNCE_MS = 50;
constexpr unsigned long LOCKOUT_MS  = 300;

// Anti-pop mute timing
constexpr unsigned long MUTE_BEFORE_RELAY_MS = 30;
constexpr unsigned long RELAY_SETTLE_MS      = 70;

// State
bool effectOn = false;

uint8_t lastRawSwitchState = HIGH;
uint8_t stableSwitchState  = HIGH;

unsigned long lastRawChangeTime = 0;
unsigned long lastToggleTime    = 0;

void applyStableState()
{
  if (effectOn) {
    digitalWrite(RELAY_PIN, RELAY_ON);
    digitalWrite(LED_PIN, LED_ON);
  } else {
    digitalWrite(RELAY_PIN, RELAY_OFF);
    digitalWrite(LED_PIN, LED_OFF);
  }

  // Important: mute must be OFF during normal audio operation
  digitalWrite(MUTE_PIN, MUTE_OFF);
}

void switchEffectWithMute()
{
  // Mute audio output briefly before relay switching
  digitalWrite(MUTE_PIN, MUTE_ON);
  delay(MUTE_BEFORE_RELAY_MS);

  // Toggle effect state
  effectOn = !effectOn;

  // Switch relay and LED
  if (effectOn) {
    digitalWrite(RELAY_PIN, RELAY_ON);
    digitalWrite(LED_PIN, LED_ON);
  } else {
    digitalWrite(RELAY_PIN, RELAY_OFF);
    digitalWrite(LED_PIN, LED_OFF);
  }

  // Wait for relay contacts to settle
  delay(RELAY_SETTLE_MS);

  // Release mute for normal audio operation
  digitalWrite(MUTE_PIN, MUTE_OFF);
}

void setup()
{
  // Configure outputs first
  pinMode(RELAY_PIN, OUTPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(MUTE_PIN, OUTPUT);

  // Safe startup state
  effectOn = false;
  digitalWrite(MUTE_PIN, MUTE_OFF);
  applyStableState();

  // Footswitch input
  pinMode(FOOTSWITCH_PIN, INPUT_PULLUP);

  // Initialize switch state
  lastRawSwitchState = digitalRead(FOOTSWITCH_PIN);
  stableSwitchState  = lastRawSwitchState;

  lastRawChangeTime = millis();
  lastToggleTime    = millis();
}

void loop()
{
  unsigned long now = millis();
  uint8_t rawSwitchState = digitalRead(FOOTSWITCH_PIN);

  // Raw state changed: restart debounce timer
  if (rawSwitchState != lastRawSwitchState) {
    lastRawSwitchState = rawSwitchState;
    lastRawChangeTime = now;
  }

  // Accept only stable state after debounce time
  if ((now - lastRawChangeTime) >= DEBOUNCE_MS) {

    // Latching footswitch:
    // toggle on any stable state change, not only LOW press
    if (rawSwitchState != stableSwitchState) {

      // Extra lockout prevents bounce/double toggle
      if ((now - lastToggleTime) >= LOCKOUT_MS) {
        stableSwitchState = rawSwitchState;
        switchEffectWithMute();
        lastToggleTime = now;
      }
    }
  }
}

10. Verification After Upload
Check with a multimeter:

Text


Effect OFF:
PA1 = 0V
PA2 = HIGH / LED OFF
PA6 = 0V
Relay OFF / bypass

Effect ON:
PA1 = 5V
PA2 = LOW / LED ON
PA6 = 0V after short mute pulse
Relay ON / distortion
During relay switching, PA6 should briefly go HIGH and then return LOW.

11. Important D2 Note
D2 near the relay must be installed correctly:

Text


D2 cathode / stripe side → +5V / relay pin 1
D2 anode / no-stripe side → RELAY_COIL_NEG / relay pin 12 / Q2 collector
Without D2, the relay can work, but Q2 and ATtiny212 are not protected from the relay coil flyback pulse.
If D2 is installed backwards, it can short the relay supply path when Q2 turns on. This can cause unstable behavior, voltage drop, heating, relay failure, or damage to the driver transistor.

12. Expected Final Result
After final firmware upload:

Text


1 footswitch click → distortion ON, relay ON, LED ON
next footswitch click → bypass ON, relay OFF, LED OFF
PA6 must not mute the audio continuously. It is used only briefly during relay switching for anti-pop mute.

13. Short Final Checklist
Before final testing, check:

Text


D2 stripe/cathode side → +5V
D2 anode side → RELAY_COIL_NEG / Q2 collector
PA6 LOW during normal audio
PA6 HIGH only briefly during switching
PA1 controls relay through Q2
PA2 LED logic is active LOW
Expected normal states:

Text


Bypass:
PA1 LOW
LED OFF
PA6 LOW

Distortion:
PA1 HIGH
LED ON
PA6 LOW after short mute pulse
  • 1. Overview

  • 2. ATtiny212 Pin Mapping

  • 3. Expected Behavior

  • 4. Required Software

  • Windows / macOS

  • 5. Installing megaTinyCore

  • 6. Preparing Arduino Uno/Nano as jtag2updi

  • 7. Wiring the Programmer to ATtiny212

  • 8. Arduino IDE Settings for ATtiny212

  • 9. Final Firmware Code

  • 10. Verification After Upload

  • 11. Important D2 Note

  • 12. Expected Final Result

  • 13. Short Final Checklist