Simulácia svätojánskej mušky

Zápisník experimentátora

Translations: SK EN

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

Minulý rok som trochu načal tému svätojánskych mušiek. V tomto článku sa pozrieme na to, ako tento hmyz vytvára svetlo a ako ho môžeme napodobniť pomocou Arduina. Simulovať budeme pomocou obvodu 74HC595 a knižnice ShiftPWM.

V prírode

Svätojánska muška je ľudový názov pre Svetlušku svätojánsku. To je hmyz, ktorý v noci dokáže svietiť pomocou javu nazývaného bioluminiscencia. Vďaka tomu svetlu majú ľudia pocit, že to bude krásny chrobáčik s lampičkou, ale v skutočnosti je to dosť škaredý hmyz. Našťastie to v noci nevidno a tak môžeme občas sledovať podivné svetielka na lúke a nechať sa unášať na vlne našej predstavivosti.

V prírode existuje niekoľko druhov svetlušiek a od seba sa líšia vzorom, podľa ktorého blikajú. Niekto si dal námahu so zozbieraním týchto vzorov. Z nasledovnej tabuľky som vychádzal pri simulovaní zábleskov.

Okrem tejto tabuľky som mal ešte jednu, ale už nedokážem nájsť, kde na webe bola. Ale výsledné blikanie mušiek som nejako skombinoval z oboch zdrojov.

Príprava vzoriek

Ku tabuľke nebolo žiadne vysvetlenie, tak som pri tvorbe podkladových údajov postupoval voľne. Približne som odhadol, že autori tabuliek zaznamenali vývoj vzorky v čase a jej intenzitu. Na základe toho som napísal jednoduchý program, ktorý na miestach vzoriek vykreslil elipsy s maximálnou výškou 255 bodov a potom som si do poľa hodnôt poznačil najvyššiu hodnotu v každom stĺpci. Takto som postupoval pri každej vzorke a výsledkom je pole niekoľkých vzoriek.

Hardvér

Budeme potrebovať nasledovné súčiastky:

  • Arduino UNO - Ja vo videu používam Arduino Pro Mini a programované je v IDE 1.6.7.
  • 74HC595 - Posuvný register. Používam vo videu moju dosku, ktorá je určená do skúšobného poľa.
  • Sadu 8x LED s príslušným rezistorom minimálne 330R - Používam moju dosku, ktorá je určená do skúšobného poľa.

Program

Zadefinoval som si nasledovné správanie:

  • Určil som si, že medzi jednotlivými stĺpcami uplynie čas 10 ms a tomu som prispôsobil výsledný program.
  • Použil som jeden posuvný register 74HC595 a 8 LED. V prípade potreby sa jednoduchou úpravou zapojenia a kódu môže pridať viac LED.
  • Nastavenie jasu každej LED diódy zabezpečuje knižnica ShiftPWM, čo je veľmi pohodlný spôsob pre programovanie.
  • Každú mušku predstavuje jeden stavový automat, kde sa muška pohybuje medzi stavmi čakajúca, blikajúca a unavená.
    • Čakajúca muška nebliká a môže byť v náhodnom okamihu prepnutá do blikajúceho stavu.
    • Blikajúca muška každých 10 ms vykreslí svoju vzorku. Vzorku môže aj niekoľkokát zopakovať. Keď dobliká, prepne sa do stavu unavená.
    • Unavená muška nebliká a nie je možné ju rozblikať. Keď uplynie nastavený čas, prepne sa do stavu čakajúca.
  • Aby bolo blikanie lepšie rozoznateľné ľudským okom, jas diódy sa prispôsobuje nelineánemu vnímaniu oka.

Program je rozdelený na niekoľko častí:

  • pattern.h - Definície vzoriek jednotlivých mušiek.
  • light.h - Definície nelineárneho jasu LED diód.
  • firefly.h - Definície stavov svätojánskej mušky a štruktúra, v ktorej je možné ukladať všetky údaje pre ňu.
  • hc595_led_shiftpwmfirefly01.ino - Hlavný program.

Definície vzoriek

Príklad jednej vzorky je v nasledovnom kóde. Každé jedno číslo predstavuje vývoj jasu vzorky v čase. Každých 10 ms sa odošle nová hodnota na LED diódu.

PROGMEM const unsigned char carolinus[31]={
25, 99, 133, 159, 177, 193, 206, 206, 215, 224,
231, 237, 242, 246, 248, 250, 248, 246, 243, 238,
232, 224, 215, 206, 193, 178, 178, 159, 133, 100,
26};

#define MAX_PT 11
struct pt
{
  int length;
  const unsigned char *pattern;
  const char *name;
  int dela;
}
pt[MAX_PT]={
  {41,marginellus,"Marginellus",230},
  {21,sabulosus,"Sabulosus",350},
  {91,pyralis,"Pyralis",480},
  {61,umbratus,"Umbratus",590},
  {61,collustrans,"Collustrans",180},
  {31,ignitus,"Ignitus",470},
  {81,consanguineus,"Consanguineus",470},
  {181,greeni,"Greeni",370},
  {231,macdermotti,"Macdermotti",320},
  {21,consimillis,"Consimillis",20},
  {31,carolinus,"Carolinus",30},
};

Definície mušiek

​Jednotlivé stavy mušky sú definované cez enum.

enum ffstate {
  ffIdle=0,ffActive,ffTired};

Samotná muška je definovaná cez nasledovnú štruktúru. Tá umožňuje uložiť jej stav, konkrétnu náhodne vybranú vzorku mušky, pozíciu pri prehrávaní vzorky, dĺžku vzorky, čas počas ktorého je muška unavená a počet opakovaní vzoriek.

struct firefly
{
  ffstate state;
  const unsigned char *pattern;
  int pos;
  int length;
  long tired;
  int repeat;
};

V hlavnom programe je potom definované pole mušiek, ktoré zodpovedá počtu LED diód s definovaným počiatočným stavom ffIdle, čo znamená, že na každej pozíci je muška pripravená na blikanie.

firefly f[8]={
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0},
  {ffIdle,NULL,0,0,0,0}
};

Hlavný program

Hlavný program musí potom ovládať už len prechody medzi jednotlivými stavmi a postupné animovanie vzoriek. Každá vzorka je pred odoslaním na LED upravená tak, aby sa kompenzovala nelinearita ľudského oka.

Vo funkcii setup sa nastavuje správanie knižnice ShiftPWM a nastaví sa úvodný stav pre náhodné čísla podľa aktuálnej hodnoty analógového vstupu, ktorý nie je nikam pripojený. Preto je tam k dispozícii náhodné číslo s hodnotou aktuálneho šumu v okolí.

void setup() {
  Serial.begin(9600);

  ShiftPWM.SetAmountOfRegisters(numRegisters);
  ShiftPWM.SetPinGrouping(1);
  ShiftPWM.Start(pwmFrequency,maxBrightness);
  ShiftPWM.PrintInterruptLoad();

  randomSeed(analogRead(0));
}

Vo funkcii loop už len prepíname jednotlivé stavy mušky, ktorá je náhodne vytvorená na hociktorej voľnej dióde.

void loop() {
  mil=millis();
  for(int i=0;i<8;i++)
  {
    switch(f[i].state)
    {
    case ffIdle:
      r=random(2000);
      if(r<10)
        {
        f[i].state=ffActive;
        r=random(MAX_PT);
        printActive(i);
        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(10000);
        printTired(i);
        }
      break;  
    case ffTired:
      if(f[i].tired<mil)
        {
        f[i].state=ffIdle;
        printIdle(i);
        }
      break;  
    } 
  } 
  delay(10);
}

Github

Zdrojový kód generátora na prípravu súboru firefly.h.

Video

Vo videu je vidno, ako jednotlivé mušky blikajú.

Ako ďalej

Program je vyvinutý, teraz sa môže prikročiť k záverečnej fáze. Tou je vytvorenie výslednej kombinácie skleného pohára, vloženého sena a elektroniky, ktoré navodia dojem reálnych mušiek v prírode.



Download

19.01.2016


Menu