How to create the illusion of a fireflies in a jar

Zápisník experimentátora

Hierarchy: Svätojánska muška v pohári

Lucky coincidence helped me to complete the project of the fireflies illusion. I bought a vase that was made of glass and had an original red stain motif. It was easy to place the whole electronics inside vase that created the resulting illusion.

Used parts

The list of parts in the video. The attached photos are from the testing phase when the illusion was not blinking to give a better picture.

  • Arduino Pro Mini (link) - Small and inexpensive Arduino.
  • Mini Breadboard (link) - I used two pieces as seen on the video.
  • Converter CP2102 USB to Serial (link) - To program Arduino.
  • Double-Side Prototype PCB Universal Printed Circuit Board (link) - I used the smallest 20x80 mm board because there was no problem to place three resistors next to each other, and there was no problem placing three triplets above each other to optimally fill the space in the vase.
  • Single-Core Tinned Copper Wire (link) - From it I created connecting wires between Arduino and LEDs.
  • 8x resistor 330R - When using a 5 V voltage, this is the optimum to have the maximum light intensity of the diodes.
  • 8x LED red diode - I used the red superbright LED to match the vase's color.
  • Own module for 74HC595 (link) - So I can use it comfortably on a breadboard.

Production

The whole illusion is on a two-sided PCB. It has to be used on both sides because the LEDs are fed from one side or the other to be shaped like a cylinder where the imaginary walls of the cylinder are LEDs. There are three lines with 2, 3 and 3 LEDs. I placed them so that they did not turn vertically on the wall of the vase, but they were almost parallel to the walls. It is visible in the video where I pick PCBs from a vase. It was also necessary to take into account the entrance to the vase.

I measured the wires in a sufficient length of 8 pieces and twisted them into one bundle. Because the LEDs are blinking randomly, it does not matter how you connect them to the 74HC595 outputs. These wires form anodes. In addition, I used one more wire and it forms a cathode. I have it separately to know exactly where to connect this wire at both ends.

Program (sketch)

The program is a slight modification of the previous codes that I published a few months ago. The​ ShiftPWM library is used again, and a couple of changes are in the program for filming.

You can set up four different degrees of flicker. For normal use, I recommend the first activity. I've used the third activity for filming, and if you feel it's not fast enough, then there's a fourth option.

//#define ACTIVITY_NORMAL 20
//#define ACTIVITY_FAST   100
#define ACTIVITY_MACHINE_GUN 200
//#define ACTIVITY_CAFFEINE 1000

#if defined(ACTIVITY_NORMAL)
  #define TIRED_TIME 10000
#elif defined(ACTIVITY_FAST)
  #define TIRED_TIME 6000
#elif defined(ACTIVITY_MACHINE_GUN)
  #define TIRED_TIME 3000
#elif defined(ACTIVITY_CAFFEINE)
  #define TIRED_TIME 600
#endif

const int ShiftPWM_latchPin=10;
const bool ShiftPWM_invertOutputs = false;
const bool ShiftPWM_balanceLoad = false;

#include <ShiftPWM.h>   // include ShiftPWM.h after setting the pins!
#include "light.h"
#include "pattern.h"
#include "firefly.h"

const unsigned char maxBrightness = 255;
const unsigned char pwmFrequency = 75;
const int numRegisters = 1;
const int ffCount = numRegisters*8;
const int flyActivity = ACTIVITY_MACHINE_GUN;

And, in the main loop function, the flyActivity and TIRED_TIME values are used to adjust the wake-up speed and to set the time for the relaxing fly.

void loop() {
  mil=millis();
  for(int i=0;i<ffCount;i++)
  {
    switch(f[i].state)
    {
    case ffIdle:
      r=random(2000);
      if(r<flyActivity)
        {
        f[i].state=ffActive;
        r=random(MAX_PT);
        printActive(i,r,mil);
        f[i].pattern=pt[r].pattern;
        f[i].pos=0;
        f[i].length=pt[r].length;
        f[i].repeat=1+random(3);
        }
      break;
    case ffActive:
      value=pgm_read_byte(f[i].pattern + f[i].pos);
      value=pgm_read_byte(&table[value]);
      ShiftPWM.SetOne(i,value);
      f[i].pos++;
      if(f[i].pos==f[i].length)
        {
        f[i].repeat--;
        if(f[i].repeat)
          f[i].pos=0;
        }
      if(f[i].pos==f[i].length)
        {
        ShiftPWM.SetOne(i,0);
        f[i].state=ffTired;
        f[i].tired=mil+500+random(TIRED_TIME);
        printTired(i);
        }
      break; 
    case ffTired:
      if(f[i].tired<mil)
        {
        f[i].state=ffIdle;
        printIdle(i,mil);
        }
      break; 
    }
  }
  delay(DELAY_MS);
}

Source code

The source code is located on the​ GitHub server.

Video

The video shows a flash of absolute darkness and a gradual discovery of the illusion to see that what is not seen does not necessarily have to be perfect.


09.07.2017


Menu