Professional Front End Engineer. Unprofessional tinkerer.

Lantern

11 Feb 2022

A really quick bodge-job project that turned out better (and worse) than I expected.

You pick up the lantern and it lights up! No switch or anything.. just human contact. Light enough to walk upstairs like an old candle holder.

Ingredients

  • Attiny85
  • RGB LED Ring 16Bit WS2812 5050 (similar to NeoPixel but loads cheaper)
  • TTP223 Capacitive Touch Sensor
  • Wemos Battery Shield (essentially a TP4056 charger and 5V boost)
  • 26650 Li-ion Battery
  • Old spice jar
  • Solar garden lamp bulb

Total cost, around £10 (in 2021)

Method

Solder it all up, bosh it in a jar. Easy! Oh, programme the Attiny85 beforehand or better yet, use little female machine pins so it can be removed. I added an aerial, essentially, to the capacitive touch module and fed that out down over the surface of the jar then wrapped it in some rather pleasant fabric tape.

Code

It’s super simple, and yet was actually quite tricky to get right, as the capacitive sensor is so sensitive it randomly triggers itself which if isn’t taken into account, makes it seem .. haunted.

If you’re building something similar, you’ll no doubt figure out your own version but it might be helpful to see this, as it has a nice red fading in animation as it lights up (trying to look a little like a flame).

#include <Adafruit_NeoPixel.h>
#include <Arduino.h>
#define pinPixels 0
#define pinTouch 3
const uint8_t numOfLeds = 16;
bool flameOn = false;
uint8_t areYouSure = 0;
uint8_t areYouSures = 4;
Adafruit_NeoPixel pixels =
    Adafruit_NeoPixel(numOfLeds, pinPixels, NEO_GRB + NEO_KHZ800);
void setup() {
  pinMode(pinTouch, INPUT);
  pixels.begin();
  pixels.clear();
  pixels.setBrightness(255); // 1 -> 255
  pixels.fill(0, 0, 0);
  pixels.show();
}
void loop() {
  // Test
  // if (digitalRead(pinTouch)) {
  //   pixels.fill(pixels.Color(0, 255, 0));
  // } else {
  //   pixels.fill(pixels.Color(0, 10, 10));
  // }
  // pixels.show();
  // delay(10);
  //
  if (digitalRead(pinTouch)) {
    areYouSure = 0;
    if (!flameOn) {
      for (double i = 0; i <= 1; i += .02) {
        pixels.fill(pixels.Color(round(255 * i), round(20 * i), 0));
        delay(10);
        pixels.show();
      }
      for (double i = 0; i <= 1; i += .02) {
        pixels.fill(
            pixels.Color(255, round(20 + (170 - 20) * i), round(20 * i)));
        delay(10);
        pixels.show();
      }
      flameOn = true;
    }
    // JIC
    pixels.fill(pixels.Color(255, 170, 20));
    pixels.show();
  } else {
    areYouSure = areYouSure < areYouSures ? areYouSure + 1 : areYouSure;
    if (areYouSure >= areYouSures) {
      areYouSure = 0;
      if (flameOn) {
        for (double i = 1; i >= 0; i -= .015) {
          pixels.fill(
              pixels.Color(round(255 * i), round(170 * i), round(20 * i)));
          delay(10);
          pixels.show();
        }
      }
      // JIC
      pixels.fill(0, 0, 0);
      pixels.show();
      flameOn = false;
    }
  }
  delay(1000);
}

Conclusion, or Burning the candle at both ends

It works great, until it doesn’t.

I did some back-of-an-envelope calculations and thought it should last for weeks if used sparingly. Turns out very not the case - it lasts just a few days. My theory is just that the capacitive touch sensor is constantly sapping more power than I expected. Such a shame as using the tricky little Attiny85 et al was all for battery life. Then again these LED rings are power hungry as heck too.

TL;DR I love it but immediately want to make a second version - with a physical lifting switch mechanic (no power use otherwise) and more economic LEDs (non-RGB). No reason it shouldn’t last proper months if it’s right.

© MichaelCook.tech 2023