Odkazy:
Heart beat je technologie práce s LED diodou, kdy poblikáváním této diody dává zařízení najevo, že je v pořádku.
Můžeme samozřejmě obyčejně blikat led, ale často potřebujeme lepší efekt než pouhé blikání, a navíc toto musíme zaintegrovat do aplikace. Inspirován podobnou funkcí v 40.8.10.1 – „Arduino AVR ISP programátor“ a ... jsem se rozhodl vyřešit problém trochu jinak. Výchozí myšlenka je že chci aby se jas LED diody měnil podel funkce sin
, případně podle jiné. Další podmínkou je, že si funkce sama musí hlídat čas a nemá tedy používat delay. Přišel jsem s řešením, kdy hodnoty funkce jasu je uložena v poli heartbeat_array
. To mi dovolí si předem připravit libovolnou funkci a v průběhu volání heartbeat
jinž neztrácím čast výpočty v plovoucí řádové čárce. Dalším prvkem řešení je hlídání času. Funkce ji třeba volat rozumě často a ona sama rozhodně jestli již uběhl požadovaný čas STEP
.
#define STEP 50 unsigned long lastTime; uint8_t heartbeat_array[] = { #include "sintable.h" }; void heartbeat(int led) { unsigned long now = millis(); static uint8_t table_index=0; /* Check if time is enough, return else */ if (now < lastTime + STEP) { return; } analogWrite(led, heartbeat_array[table_index++]); if (table_index >= sizeof(heartbeat_array)) { table_index = 0; } lastTime += STEP; }
Hodnoty pole heartbeat_arra
vytvářím krátkým programem v Ruby. Jednoduchou úpravou kdy se funkce sin
zamění za jinou, dosáhneme požadovaného průběhu.
#!/usr/bin/env ruby # This program creates table of output signal for function heart beat. def generate_table steps, minvalue, maxvalue puts "/* * Sin x-PI/2 table in #{steps} steps with minumum at #{minvalue} and maximum at #{maxvalue}. * Generated with commad: * ./generate_table #{steps} #{minvalue} #{maxvalue} */" puts (0..steps-1) \ .collect{|deg| (deg.to_f * 2.0 * Math::PI) /steps} \ .collect{|r| (Math::sin(r - Math::PI/2)+1)/2 * (maxvalue-minvalue) +minvalue} \ .collect{|n| "%3d" % n.round} \ .each_slice(8).collect{ |row| "\t" + row.join(', ') }.join ",\n" end if $0 == __FILE__ then generate_table ARGV[0].to_i, ARGV[1].to_i, ARGV[2].to_i end
Pokud nebude funkce heartbeat
volána dostatečně často, vznikne rozdíl v čas lastTime a aktuálním čase. To způsobý zrychlené "dohánění" času.
Bylo by hezké, kdyby buďto sama funkce poznala že nebyla dlouhý čas volána a toto ošetřila.
Bylo by hezké kdybych vyřešil náběh LED z nuly při prvním cyklu, případně doběh po posledním cyklu. Klidová poloha by nemusela být nula ale plný jas.