all | audio | badgelife | breakout | clocks | displays | experiments | feather | handhelds | home automation | howto | LED art | misc | props | robots | sewing | software | tools | no_category

sloth badge

I guess I can't stop doing badges. Really love the @pimoroni #bearables - but they don't have sloths :(

there are some nifty tricks hidden in the bearables badges, a cool menu etc. I want to replicate the behaviour with an ATTINY13A.

sloth badge | new design!

2018-02-20 23:59:57

After a fallout with pimoroni I'm no longer allowed to use the sloth badge design. So here is the new design:

Just kidding! I've bought a soic8 adapter that I will solder into place and make this a dedicated SOIC8 programmer for the kit chips! I haven't heard from pimoroni in a while though, need to ping them in a tweet some time.

https://cdn.hackaday.io/images/9720301519167480164.png

sloth badge | new design!

2018-02-20 23:59:57

After a fallout with pimoroni I'm no longer allowed to use the sloth badge design. So here is the new design:

Just kidding! I've bought a soic8 adapter that I will solder into place and make this a dedicated SOIC8 programmer for the kit chips! I haven't heard from pimoroni in a while though, need to ping them in a tweet some time.

https://cdn.hackaday.io/images/9720301519167480164.png

sloth badge | current code, anyone any ideas to save space?

2018-02-19 11:28:26

I won't lie, this feels messy. This currently features 5 animations, where 2 of them are just "played accelerating" . 

Some things I'm not happy with:

 - the button does not work within the animations, so you need to push the button until the animation cycle is over

#include <avr/sleep.h>
#define nop() asm volatile("nop")
boolean leds_on = true;

byte badly_programmed_counter = 0;
byte animation_counter_max = 5;
byte animation_counter = 0;

// we need two frames with 8 bits for 12 LEDs
byte frame1 = 0;
byte frame2 = 0;

// animation where every third LED is glowing
// I could shift that continuosly and drop 4 bytes
const byte three_apart_length = 6;
const byte three_apart[three_apart_length] PROGMEM = {
  0b10010010, 0b01000000,
  0b01001001, 0b00100000,
  0b00100100, 0b10010000,
};

// this one is huge
// is there a math function to do that instead?
const byte updown_length = 14;
const byte updown[updown_length] PROGMEM = {
  0b00100000, 0b00000000,
  0b01010000, 0b00000000,
  0b10001000, 0b00000000,
  0b00000100, 0b00010000,
  0b00000010, 0b00100000,
  0b00000001, 0b01000000,
  0b00000000, 0b10000000,
};

// that's just blinking each led 
// maybe inverting the data bitwise does the trick
const byte two_apart_length = 4;
const byte two_apart[two_apart_length] PROGMEM = {
  0b10101010, 0b10100000,
  0b01010101, 0b01010000,
};

// should have taken a switch, sleep stuff is huge
ISR(INT0_vect) {
  sleep_disable();
  leds_on = true;
}

void setup()
{
  // this is for the button setup
  PORTB |= (1 << PB1);
  DDRB &= ~(1 << PB1);

  shutdown_chip();
}

void loop()
{
  if (leds_on)
  {
    cli();
    leds_on = false;

    // I call it that, because the millis stuff
    // and the interrupts collided and broke
    badly_programmed_counter = 0;
  }

  // fancy way of checking the button state
  if (!(PINB & (1 << PB1)))
  {
    badly_programmed_counter++;
    my_100ms_delay();

    // check if button was released before time
    // so animation index can be incremented
    // maybe a modulo with animation_counter_max
    // safes space
    if ( (PINB & (1 << PB1)) )
    {
      badly_programmed_counter = 0;
      animation_counter++;
      if (animation_counter == animation_counter_max)
      {
        animation_counter = 0;
      }
      charlie(animation_counter);

      // calling a function instead of writing it down
      // 5 times helps already
      for (byte b = 0; b < 5; b++) my_100ms_delay();
    }

    if (badly_programmed_counter >= 7)
    {
      // blink when shutdown is immanent
      for (byte b = 0; b < 5; b++) blip();
      shutdown_chip();
    }
  }
  else
  {
    animate_leds();
    badly_programmed_counter = 0;
  }
}

// this is probably already at it's best
void charlie (byte var) {
  leds_off();

  switch (var) {
    case 0: // 1
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 1: // 2
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 2: // 3
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 3: // 4
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 4: // 5
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 5: // 6
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    case 6: // 7
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 7: // 8
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 8: // 9
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 9: // 10
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    case 10: // 11
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 11: // 12
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    default:
      ;

      nop();
  }
}

void shutdown_chip()
{
  animation_counter = 0;
  leds_off();

  /* Clear WDRF in MCUSR */
  MCUSR &= ~(1 << WDRF);
  /* Write logical one to WDCE and WDE */
  /* Keep old prescaler setting to prevent unintentional time-out */
  WDTCR |= (1 << WDCE) | (1 << WDE);
  /* Turn off WDT */
  WDTCR = 0x00;

  ADCSRA &= ~(1 << ADEN); // turn off adc

  GIMSK |= (1 << INT0);
  GIMSK |= (1 << PCIE);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei(); // Enable global interrupts
  sleep_cpu();
  sleep_disable();
}

void animate_leds()
{
  switch (animation_counter)
  {
    case 0:
      animate_frames(
        three_apart_length,
        three_apart,
        512
      );
      break;

    case 1:
      for (byte acc_counter = 1; acc_counter < 64; acc_counter += 2)
      {
        animate_frames(
          three_apart_length,
          three_apart,
          acc_counter * 8
        );
      }
      break;

    case 2:
      animate_frames(
        updown_length,
        updown,
        512
      );
      break;

    case 3:
      animate_frames(
        two_apart_length,
        two_apart,
        2048
      );
      break;

    case 4:
      for (byte acc_counter = 1; acc_counter < 64; acc_counter += 2)
      {
        animate_frames(
          updown_length,
          updown,
          (63-acc_counter) * 4
        );
      }
      break;

    default:
      leds_off();
      break;
  }
}

void animate_frames(
  byte animation_length,
  const byte* animation_array,
  uint16_t frame_duration
) {
  for (byte i = 0; i < animation_length; i += 2)
  {
    // save the last time you blinked the LED
    frame1 = pgm_read_byte_near(animation_array + i);
    frame2 = pgm_read_byte_near(animation_array + i + 1);
    show_frame(frame_duration);
  }
}

// this just looks ugly, but needs to be done
// for loop through frame bytes to set the LEDs with 
// the charlie plex function
void show_frame(uint16_t byteframe_length)
{
  for (uint16_t j = 0; j < byteframe_length; j++)
  {
    //iterate through bit mask
    for (byte i = 0; i < 12; i++)
    {
      // if bitwise AND resolves to true
      if (
        (
          i < 8 &&
          1 << i & frame1
        ) ||
        (
          i > 7 &&
          1 << (i - 4) & frame2
        )
      )
      {
        charlie(i);
      }
      else
      {
        charlie(255);
      }
    }
  }
}

void leds_off()
{
  DDRB &= ~(0b00011101);
  PORTB &= ~(0b00011101);
}

void blip()
{
  charlie(11);
  // delay(100);
  my_100ms_delay();
  charlie(255);
  // delay(100);
  my_100ms_delay();
}

void my_100ms_delay()
{
  for (uint32_t i=0;i<40000;i++) nop();
}

sloth badge | current code, anyone any ideas to save space?

2018-02-19 11:28:26

I won't lie, this feels messy. This currently features 5 animations, where 2 of them are just "played accelerating" . 

Some things I'm not happy with:

 - the button does not work within the animations, so you need to push the button until the animation cycle is over

#include <avr/sleep.h>
#define nop() asm volatile("nop")
boolean leds_on = true;

byte badly_programmed_counter = 0;
byte animation_counter_max = 5;
byte animation_counter = 0;

// we need two frames with 8 bits for 12 LEDs
byte frame1 = 0;
byte frame2 = 0;

// animation where every third LED is glowing
// I could shift that continuosly and drop 4 bytes
const byte three_apart_length = 6;
const byte three_apart[three_apart_length] PROGMEM = {
  0b10010010, 0b01000000,
  0b01001001, 0b00100000,
  0b00100100, 0b10010000,
};

// this one is huge
// is there a math function to do that instead?
const byte updown_length = 14;
const byte updown[updown_length] PROGMEM = {
  0b00100000, 0b00000000,
  0b01010000, 0b00000000,
  0b10001000, 0b00000000,
  0b00000100, 0b00010000,
  0b00000010, 0b00100000,
  0b00000001, 0b01000000,
  0b00000000, 0b10000000,
};

// that's just blinking each led 
// maybe inverting the data bitwise does the trick
const byte two_apart_length = 4;
const byte two_apart[two_apart_length] PROGMEM = {
  0b10101010, 0b10100000,
  0b01010101, 0b01010000,
};

// should have taken a switch, sleep stuff is huge
ISR(INT0_vect) {
  sleep_disable();
  leds_on = true;
}

void setup()
{
  // this is for the button setup
  PORTB |= (1 << PB1);
  DDRB &= ~(1 << PB1);

  shutdown_chip();
}

void loop()
{
  if (leds_on)
  {
    cli();
    leds_on = false;

    // I call it that, because the millis stuff
    // and the interrupts collided and broke
    badly_programmed_counter = 0;
  }

  // fancy way of checking the button state
  if (!(PINB & (1 << PB1)))
  {
    badly_programmed_counter++;
    my_100ms_delay();

    // check if button was released before time
    // so animation index can be incremented
    // maybe a modulo with animation_counter_max
    // safes space
    if ( (PINB & (1 << PB1)) )
    {
      badly_programmed_counter = 0;
      animation_counter++;
      if (animation_counter == animation_counter_max)
      {
        animation_counter = 0;
      }
      charlie(animation_counter);

      // calling a function instead of writing it down
      // 5 times helps already
      for (byte b = 0; b < 5; b++) my_100ms_delay();
    }

    if (badly_programmed_counter >= 7)
    {
      // blink when shutdown is immanent
      for (byte b = 0; b < 5; b++) blip();
      shutdown_chip();
    }
  }
  else
  {
    animate_leds();
    badly_programmed_counter = 0;
  }
}

// this is probably already at it's best
void charlie (byte var) {
  leds_off();

  switch (var) {
    case 0: // 1
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 1: // 2
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 2: // 3
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 3: // 4
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 4: // 5
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 5: // 6
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    case 6: // 7
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 7: // 8
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      break;
    case 8: // 9
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB2); // HIGH
      break;
    case 9: // 10
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    case 10: // 11
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB0); // HIGH
      break;
    case 11: // 12
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      break;
    default:
      ;

      nop();
  }
}

void shutdown_chip()
{
  animation_counter = 0;
  leds_off();

  /* Clear WDRF in MCUSR */
  MCUSR &= ~(1 << WDRF);
  /* Write logical one to WDCE and WDE */
  /* Keep old prescaler setting to prevent unintentional time-out */
  WDTCR |= (1 << WDCE) | (1 << WDE);
  /* Turn off WDT */
  WDTCR = 0x00;

  ADCSRA &= ~(1 << ADEN); // turn off adc

  GIMSK |= (1 << INT0);
  GIMSK |= (1 << PCIE);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei(); // Enable global interrupts
  sleep_cpu();
  sleep_disable();
}

void animate_leds()
{
  switch (animation_counter)
  {
    case 0:
      animate_frames(
        three_apart_length,
        three_apart,
        512
      );
      break;

    case 1:
      for (byte acc_counter = 1; acc_counter < 64; acc_counter += 2)
      {
        animate_frames(
          three_apart_length,
          three_apart,
          acc_counter * 8
        );
      }
      break;

    case 2:
      animate_frames(
        updown_length,
        updown,
        512
      );
      break;

    case 3:
      animate_frames(
        two_apart_length,
        two_apart,
        2048
      );
      break;

    case 4:
      for (byte acc_counter = 1; acc_counter < 64; acc_counter += 2)
      {
        animate_frames(
          updown_length,
          updown,
          (63-acc_counter) * 4
        );
      }
      break;

    default:
      leds_off();
      break;
  }
}

void animate_frames(
  byte animation_length,
  const byte* animation_array,
  uint16_t frame_duration
) {
  for (byte i = 0; i < animation_length; i += 2)
  {
    // save the last time you blinked the LED
    frame1 = pgm_read_byte_near(animation_array + i);
    frame2 = pgm_read_byte_near(animation_array + i + 1);
    show_frame(frame_duration);
  }
}

// this just looks ugly, but needs to be done
// for loop through frame bytes to set the LEDs with 
// the charlie plex function
void show_frame(uint16_t byteframe_length)
{
  for (uint16_t j = 0; j < byteframe_length; j++)
  {
    //iterate through bit mask
    for (byte i = 0; i < 12; i++)
    {
      // if bitwise AND resolves to true
      if (
        (
          i < 8 &&
          1 << i & frame1
        ) ||
        (
          i > 7 &&
          1 << (i - 4) & frame2
        )
      )
      {
        charlie(i);
      }
      else
      {
        charlie(255);
      }
    }
  }
}

void leds_off()
{
  DDRB &= ~(0b00011101);
  PORTB &= ~(0b00011101);
}

void blip()
{
  charlie(11);
  // delay(100);
  my_100ms_delay();
  charlie(255);
  // delay(100);
  my_100ms_delay();
}

void my_100ms_delay()
{
  for (uint32_t i=0;i<40000;i++) nop();
}

sloth badge | everything ready for a small run

2018-01-01 14:41:50

After a little email exchange with Paul from pimoroni we agreed on me doing a small run of badges on @Tindie  is alright with everyone, including their designer, so I will finally do a batch run with @oshpark for the first time.

The code has some potential, needs some cleaning up and some options for animations like I have added to my #K.I.T.T. - KNIGHT RIDER badge/brooch. I should use a higher value of resistors for the LEDs, they blink quite bright.

Part wise I'm all set, everything is ordered so I can sell them as kits, but might add soldered up options like I did with Kitt. 

sloth badge | everything ready for a small run

2018-01-01 14:41:50

After a little email exchange with Paul from pimoroni we agreed on me doing a small run of badges on @Tindie  is alright with everyone, including their designer, so I will finally do a batch run with @oshpark for the first time.

The code has some potential, needs some cleaning up and some options for animations like I have added to my #K.I.T.T. - KNIGHT RIDER badge/brooch. I should use a higher value of resistors for the LEDs, they blink quite bright.

Part wise I'm all set, everything is ordered so I can sell them as kits, but might add soldered up options like I did with Kitt. 

sloth badge | ahhh... I need help, I don't see it

2017-12-09 23:53:17

Somewhere along I had it go to sleep just fine, but it didn't wake up. Now it wakes up fine, but doesn't want to go to sleep. Seems like I don't have the millis stuff right anymore, I don't get to where the comment "// HOW DO I GET HERE?" is. Too tired to see it, gonna go to bed.

#include <avr/sleep.h>

boolean leds_on = true;

unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long interval = 1000;

ISR(INT0_vect) {
  sleep_disable();
  leds_on = true;
}

void setup() {
  // put your setup code here, to run once:
  PORTB |= (1 << PB1); // input
  DDRB &= ~(1<<PB1);

  shutdown_chip();
}

void loop() {
  
  
  if (leds_on)
  {
    cli();
    leds_on = false;
  }

  currentMillis = millis();
  if ( !(PINB & (1 << PB1)) )
  {
    charlie(3);
    
    if (currentMillis - previousMillis >= interval)
    {
      // HOW DO I GET HERE?
      charlie(5);
      delay(2000);
      shutdown_chip();
    }
    else
    {
      charlie(2);
    }
  }
  else
  {
    animate_leds();
    previousMillis = currentMillis;
  }
}

void shutdown_chip()
{
  leds_off();

  /* Clear WDRF in MCUSR */
  MCUSR &= ~(1 << WDRF);
  /* Write logical one to WDCE and WDE */
  /* Keep old prescaler setting to prevent unintentional time-out */
  WDTCR |= (1 << WDCE) | (1 << WDE);
  /* Turn off WDT */
  WDTCR = 0x00;

  ADCSRA &= ~(1 << ADEN); // turn off adc

  GIMSK |= (1 << INT0);
  GIMSK |= (1 << PCIE);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei(); // Enable global interrupts
  sleep_cpu();
  sleep_disable();
}

void animate_leds()
{
  for (int i = 0; i < 12; i++) {
    charlie(i);
    delay(50);
  }
  for (int i = 0; i < 12; i++) {
    charlie(11 - i);
    delay(50);
  }
}

void leds_off()
{
  DDRB &= ~(
            (1 << PB0) |
            (1 << PB2) |
            (1 << PB3) |
            (1 << PB4)
          );
  PORTB &= ~(
             (1 << PB0) |
             (1 << PB2) |
             (1 << PB3) |
             (1 << PB4)
           );
}

void charlie (int var) {
  leds_off();

  switch (var) {
    case 0: // 1
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 1: // 2
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    case 2: // 3
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 3: // 4
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 4: // 5
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 5: // 6
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 6: // 7
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 7: // 8
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    case 8: // 9
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 9: // 10
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 10: // 11
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 11: // 12
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    default:
      ;
  }
}

sloth badge | ahhh... I need help, I don't see it

2017-12-09 23:53:17

Somewhere along I had it go to sleep just fine, but it didn't wake up. Now it wakes up fine, but doesn't want to go to sleep. Seems like I don't have the millis stuff right anymore, I don't get to where the comment "// HOW DO I GET HERE?" is. Too tired to see it, gonna go to bed.

#include <avr/sleep.h>

boolean leds_on = true;

unsigned long previousMillis = 0;
unsigned long currentMillis = 0;
const long interval = 1000;

ISR(INT0_vect) {
  sleep_disable();
  leds_on = true;
}

void setup() {
  // put your setup code here, to run once:
  PORTB |= (1 << PB1); // input
  DDRB &= ~(1<<PB1);

  shutdown_chip();
}

void loop() {
  
  
  if (leds_on)
  {
    cli();
    leds_on = false;
  }

  currentMillis = millis();
  if ( !(PINB & (1 << PB1)) )
  {
    charlie(3);
    
    if (currentMillis - previousMillis >= interval)
    {
      // HOW DO I GET HERE?
      charlie(5);
      delay(2000);
      shutdown_chip();
    }
    else
    {
      charlie(2);
    }
  }
  else
  {
    animate_leds();
    previousMillis = currentMillis;
  }
}

void shutdown_chip()
{
  leds_off();

  /* Clear WDRF in MCUSR */
  MCUSR &= ~(1 << WDRF);
  /* Write logical one to WDCE and WDE */
  /* Keep old prescaler setting to prevent unintentional time-out */
  WDTCR |= (1 << WDCE) | (1 << WDE);
  /* Turn off WDT */
  WDTCR = 0x00;

  ADCSRA &= ~(1 << ADEN); // turn off adc

  GIMSK |= (1 << INT0);
  GIMSK |= (1 << PCIE);

  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_enable();
  sei(); // Enable global interrupts
  sleep_cpu();
  sleep_disable();
}

void animate_leds()
{
  for (int i = 0; i < 12; i++) {
    charlie(i);
    delay(50);
  }
  for (int i = 0; i < 12; i++) {
    charlie(11 - i);
    delay(50);
  }
}

void leds_off()
{
  DDRB &= ~(
            (1 << PB0) |
            (1 << PB2) |
            (1 << PB3) |
            (1 << PB4)
          );
  PORTB &= ~(
             (1 << PB0) |
             (1 << PB2) |
             (1 << PB3) |
             (1 << PB4)
           );
}

void charlie (int var) {
  leds_off();

  switch (var) {
    case 0: // 1
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 1: // 2
      DDRB |= (1 << PB0) | (1 << PB2); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    case 2: // 3
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 3: // 4
      DDRB |= (1 << PB2) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 4: // 5
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 5: // 6
      DDRB |= (1 << PB3) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 6: // 7
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB3); // LOW
      break;
    case 7: // 8
      DDRB |= (1 << PB0) | (1 << PB3); // output
      PORTB |= (1 << PB3); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    case 8: // 9
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB2); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 9: // 10
      DDRB |= (1 << PB2) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB2); // LOW
      break;
    case 10: // 11
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB0); // HIGH
      PORTB &= ~(1 << PB4); // LOW
      break;
    case 11: // 12
      DDRB |= (1 << PB0) | (1 << PB4); // output
      PORTB |= (1 << PB4); // HIGH
      PORTB &= ~(1 << PB0); // LOW
      break;
    default:
      ;
  }
}

sloth badge | bearables power consumption

2017-11-30 15:32:19

seems like they use 1.1mA in sleep mode, which isn't really good for a coin cell that has around 230mAh of power - 9 days of doing nothing o.O so with the right settings my sloth badge will already last a lot longer! nice :3

sloth badge | bearables power consumption

2017-11-30 15:32:19

seems like they use 1.1mA in sleep mode, which isn't really good for a coin cell that has around 230mAh of power - 9 days of doing nothing o.O so with the right settings my sloth badge will already last a lot longer! nice :3