Alexis Gimeno Martínez
Published © CC BY-NC-ND

ATtiny LED Letter Keychain

Little LED programmable keychain to show off your soldering skills.

BeginnerFull instructions provided1 hour1,360
ATtiny LED Letter Keychain

Things used in this project

Hardware components

Custom PCB
Custom PCB
You can find the complete kit here https://www.tindie.com/products/alexisgm/attiny-led-letter-keychain/
×1
ATtiny85
Microchip ATtiny85
It can also be an ATtiny13
×1
1206 SMD LED
You can choose any colour!
×15
Tact switch
×1
Battery Holder, Coin Cell
Battery Holder, Coin Cell
CR1220
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Code

Keychain code

Arduino
#include <avr/io.h>
#include <avr/eeprom.h> 
#include <avr/sleep.h>

void loop(void);
void delay_ms(uint16_t ms);

void flash(void);
void fade(void);
void pwm(void);
void allOn(void);


#define MAX_PROGRAMS 5
uint8_t EEMEM ProgramConfig = 0;
int program = 0;
unsigned long clock = 0;

void setup() {
  DDRB = 255; // all output
  PORTB = 0;
  
  program = eeprom_read_byte(&ProgramConfig);
  if (program >= MAX_PROGRAMS) {
    program = 0;
  }

  eeprom_write_byte(&ProgramConfig, program + 1);
  while (1) {
    loop();
  }
}

const uint8_t states[] = {
  0b00010000, 
  0b00001000,
  0b00000100,
  0b00000010,
  0b00000001,
};

void loop() {
  switch (program) {
  case 0:
    allOn(2);
    break;
  case 1:
    allOn(2500);
    break;
  case 2:
    fade();
    break;
  case 3:
    flash();
    break;  
  case 4:
    sleep();
    break;
  default:
    allOn(2);
  }
}

void sleep() {
  if (clock > 100000) {
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    sleep_mode();
  }
}



uint8_t blinkState = 0;
unsigned long lastBlink = 0; 

uint8_t flashState = 0;

void flash() {
  if (clock - lastBlink > 3000) {
    flashState = 1 - flashState;
    lastBlink = clock;
  }

  if (flashState) {
    blinkState++;
    if (blinkState > 4) {
      blinkState = 0;
    }

    PORTB=states[blinkState];
  } else {
    PORTB = 0;
  }

  clock++;
}

uint8_t level = 0;
uint8_t pwmCount = 0;
uint8_t dir = 1;

void fade() {
  if (clock - lastBlink > 20) {
    lastBlink = clock;

    level += dir;
    if (level == 0 || level >= 200) {
      dir = -1 * dir;
    }
  }

  pwm();

  clock++;
}

void pwm() {
  static uint8_t pwmCnt = 0;
  static uint8_t which = 0;

  pwmCnt++;

  if (level > pwmCnt) {
    PORTB = states[which];
    which++;
    if (which > 4) {
      which = 0;
    }
  } else {
    PORTB = 0;
  }
}

void allOn(int interval) {
  if (clock - lastBlink > interval) {
    blinkState++;
    if (blinkState > 4) {
      blinkState = 0;
    }
    lastBlink = clock;
  }

  PORTB = states[blinkState];

  clock++;
}

Credits

Alexis Gimeno Martínez

Alexis Gimeno Martínez

2 projects • 5 followers
Electronic hobbyist but translator in real life. I love to tinker around and I'm never afraid of learning something new

Comments