Jak vytvořit iluzi svatojánské mušky ve sklenici

Zápisník experimentátora

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

Šťastná náhoda napomohla tomu, abych dokončil projekt iluze svatojánské mušky. Ve výprodeji jsem koupil vázu, která byla ze skla a měla originální motiv z červených skvrn. Do ní bylo snadné umístit celou elektroniku, která vytvořila výslednou iluzi.

Použité součástky

Seznam součástek ve videu. Přiložené fotografie jsou z fáze testování, kdy celá iluze neblikala, aby se dala lépe fotografovat.

  • Arduino Pro Mini (link) - Malé a lacné Arduino.
  • Mini Breadboard (link) - Použil jsem dva kusy, jak je vidět na videu.
  • Převodník CP2102 USB to Serial (link) - Na programování Arduina.
  • Double-Side Prototype PCB Universal Printed Circuit Board (link) - Použil jsem z toho tu nejmenší desku 20x80 mm, protože se na ni bez problémů vešly tři rezistory vedle sebe a nebyl problém tam rozmístit tři trojice nad sebou, aby se optimálně vyplnil prostor ve váze.
  • Single-Core Tinned Copper Wire (link) - Z něho jsem vytvořil propojovací vodiče mezi Arduinem a LED diodami.
  • 8x rezistor 330R - Při použití napětí 5 V je toto optimum na maximální svítivost diod.
  • 8x LED dioda červená - Použil jsem červenou supersvítivou LED, aby co nejlépe splynula s barvou vázy.
  • Vlastní modul pro 74HC595 (link) - Abych ho mohl pohodlně použít na breadboardu.

Výroba

Celá iluze je na jedné oboustranné PCB. Třeba použít oboustrannou, protože LED diody se prispájkují z jedné nebo druhé strany, aby se daly pak vytvarovat do podoby válce, kde pomyslné stěny válce tvoří LED diody. Jsou tam tři řádky s 2, 3 a 3 LED diodami. Umisťoval jsem je tak, aby nesvítila kolmo na stěnu vázy, ale byly skoro rovnoběžné se stěnami. Nejlépe je to vidět ve videu, kde vybírám PCB z vázy. Bylo třeba zohlednit i vstupní otvor na váze.

Vodiče jsem si změřil v dostatečné délce v počtu 8 kusů a zkroutil jsem je do jednoho svazku. Protože LED diody blikají náhodně, je úplně jedno, v jakém pořadí je připojíte k výstupům 74HC595. Tyto vodiče tvoří anody. Kromě toho jsem použil ještě jeden vodič a ten tvoří katodu. Mám ho samostatně, abych přesně věděl, kam mám tento vodič připájet na obou koncích.

Program

Program je mírnou úpravou předchozích kódů, které jsem zveřejnil před pár měsíci. Opět je využita knihovna​ ShiftPWM a pro potřeby filmování je v programu pár změn.

Lze si nastavit čtyři různé stupně blikání. Pro normální využití doporučuji první aktivitu. Třetí aktivitu jsem využil na filmování a pokud máte pocit, že to není dost rychlé, pak je tu čtvrtá možnost.

//#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;

A v hlavní funkci loop se pak využívají hodnoty flyActivity a TIRED_TIME na nastavování rychlosti probouzejících se mušek a nastavení času pro odpočívající mušku.

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);
}

Zdrojový kód

Zdrojový kód se nachází na serveru​ GitHub.

Video

Ve videu je ukázka blikání v absolutní tmě a postupné rozebírání iluze, aby bylo vidět, že to co není vidět, nemusí být nutně dokonalé.


09.07.2017


Menu