Ako vytvoriť ilúziu svätojánskej mušky v pohári

Zápisník experimentátora

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

Šťastná náhoda napomohla tomu, aby som dokončil projekt ilúzie svätojánskej mušky. Vo výpredaji som kúpil vázu, ktorá bola zo skla a mala originálny motív z červených škvŕn. Do nej bolo jednoduché umiestniť celú elektroniku, ktorá vytvorila výslednú ilúziu.

Použité súčiastky

Zoznam súčiastok vo videu. Priložené fotografie sú z fázy testovania, kedy celá ilúzia neblikala, aby sa dala lepšie fotografovať.

  • Arduino Pro Mini (link) - Malé a lacné Arduino.
  • Mini Breadboard (link) - Použil som dva kusy, ako je vidno na videu.
  • Prevodník CP2102 USB to Serial (link) - Na programovanie Arduina.
  • Double-Side Prototype PCB Universal Printed Circuit Board (link) - Použil som z toho tú najmenšiu dosku 20x80 mm, pretože sa na ňu bez problémov zmestili tri rezistory vedľa seba a nebol problém tam rozmiestniť tri trojice nad sebou, aby sa optimálne vyplnil priestor vo váze.
  • Single-Core Tinned Copper Wire (link) - Z neho som vytvoril prepojovacie vodiče medzi Arduinom a LED diódami.
  • 8x rezistor 330R - Pri použití napätia 5 V je toto optimum na maximálnu svietivosť diód.
  • 8x LED dióda červená - Použil som červenú supersvietivú LED, aby čo najlepšie splynula s farbou vázy.
  • Vlastný modul pre 74HC595 (link) - Aby som ho mohol pohodlne použiť na breadboarde.

Výroba

Celá ilúzia je na jednej obojstrannej PCB. Treba použiť obojstrannú, pretože LED diódy sa prispájkujú z jednej alebo druhej strany, aby sa dali potom vytvarovať do podoby valca, kde pomyselné steny valca tvoria LED diódy. Sú tam tri riadky s 2, 3 a 3 LED diódami. Umiestňoval som ich tak, aby nesvietili kolmo na stenu vázy, ale boli skoro rovnobežné so stenami. Najlepšie je to vidno vo videu, kde vyberám PCB z vázy. Bolo potrebné zohľadniť aj vstupný otvor na váze.

Vodiče som si odmeral v dostatočnej dĺžke v počte 8 kusov a skrútil som ich do jedného zväzku. Pretože LED diódy blikajú náhodne, je úplne jedno, v akom poradí ich pripojíte k výstupom 74HC595. Tieto vodiče tvoria anódy. Okrem toho som použil ešte jeden vodič a ten tvorí katódu. Mám ho samostatne, aby som presne vedel, kam mám tento vodič pripájkovať na oboch koncoch.

Program

Program je miernou úpravou predchádzajúcich kódov, ktoré som zverejnil pred pár mesiacmi. Opäť je využitá knižnica ShiftPWM a pre potreby filmovania je v programe pár zmien.

Možno si nastaviť štyri rôzne stupne blikania. Pre normálne využitie odporúčam prvú aktivitu. Tretiu aktivitu som využil na filmovanie a ak máte pocit, že to nie je dosť rýchle, potom je tu štvrtá možnosť.

//#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 hlavnej funkcii loop sa potom využívajú hodnoty flyActivity a TIRED_TIME na nastavovanie rýchlosti prebúdzajúcich sa mušiek a nastavenie času pre oddychujúcu 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 sa nachádza na serveri GitHub.

Video

Vo videu je ukážka blikania v absolútnej tme a postupné rozoberanie ilúzie, aby bolo vidno, že to čo nie je vidno, nemusí byť nutne dokonalé.


23.05.2017


Menu