Zápisník experimentátora
Hierarchy: Svätojánska muška v pohári
Last year I started a topic about a fireflies. In this article we look at how this insect produces light and how can we imitate light using Arduino. We will simulate the circuit using the 74HC595 and library ShiftPWM.
Firefly is a popular name for lampyris noctiluca. This is an insect that can glow in the night by a phenomenon called bioluminescence. Thanks to light, people feel that it would be nice Bug with a lamp, but in fact it's pretty ugly insects. Fortunately, it is not visible at night so we can sometimes watch strange lights in the meadow and ride the wave of our imagination.
In nature, there are several species of fireflies with unique pattern of flashing. Someone collected these patterns. From the following table I created the patterns.
At the table there was no explanation, so I modified the data freely. I estimated roughly that the table is development of intensity in time. I wrote a simple program that places the samples portrayed ellipse with a maximum of 255 points, and then I had to calculate the highest value in each column. I proceeded this way for each sample and the result is an array of several samples.
We will need the following components:
I defined the following behavior:
Program is split into few parts.
Example of one sample is in the following code. Each number represents one luminance sample at a time. Every 10 ms a new value is sent to the LEDs.
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},
};
Each state is defined in enum.
enum ffstate {
ffIdle=0,ffActive,ffTired};
The firefly is defined through the following structure. It allows you to save the state, randomly selected pattern of flies, the position when playing the sample, length of the sample, the time during which the firefly is tired and number of repetitions of the patterns.
struct firefly
{
ffstate state;
const unsigned char *pattern;
int pos;
int length;
long tired;
int repeat;
};
The main program is then defined array of fireflies, corresponding to the number of LEDs with defined init state ffIdle, which means that each position is shot ready for flashing.
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}
};
Main program calculates transitions between states and animation of patterns. Light level is modified to compensate nonlinear characteristic of human eyes.
In function setup we must set few parameters of ShiftPWM library. We must setup random number seed from noise of unconnected analog input.
void setup() {
Serial.begin(9600);
ShiftPWM.SetAmountOfRegisters(numRegisters);
ShiftPWM.SetPinGrouping(1);
ShiftPWM.Start(pwmFrequency,maxBrightness);
ShiftPWM.PrintInterruptLoad();
randomSeed(analogRead(0));
}
In function loop we switch between states of the firefly. Firefly can be created on any free LED.
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);
}
Source code of generator, which creates file firefly.h.
In the video you can see as flies blinks.
Now we can create fireflies in a jar. Hay, few wires and electronics in a glass jar.
19.01.2016