11/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*-
22
3- G35: An Arduino library for GE Color Effects G-35 holiday lights.
4- Copyright © 2011 The G35 Authors. Use, modification, and distribution are
5- subject to the BSD license as described in the accompanying LICENSE file.
3+ G35: An Arduino library for GE Color Effects G-35 holiday lights.
4+ Copyright © 2011 The G35 Authors. Use, modification, and distribution are
5+ subject to the BSD license as described in the accompanying LICENSE file.
66
7- Ticon2011.ino is the code that I used for Christmas 2011 at my home. It's yet
8- another demonstration of working code.
7+ Ticon2011.ino is the code that I used for Christmas 2011 at my home. It's yet
8+ another demonstration of working code.
99
10- By Mike Tsao <github.com/sowbug>. See README for complete attributions.
10+ By Mike Tsao <github.com/sowbug>. See README for complete attributions.
1111*/
1212
1313// If defined, then a 38KHz IR receiver is supplying data on pin 11. I didn't
1414// really use this much; if it detects any recognized remote code, it skips to
1515// the next program. So in theory people driving by my house who happen to have
1616// a TV remote in their car could stop and change the program.
17+ //
18+ // Pretty much any of these IR receivers will work. I used a Vishay Semi
19+ // TSOP58038 (http://octopart.com/partsearch#search/requestData&q=TSOP58038).
1720#define USE_REMOTE 1
1821
1922// If defined, then the hardware is an Arduino. If not, then it's a Teensy.
20- // More described below. I used this because I had an Arduino in the house
21- // when I was writing new programs, then ran outside in the cold with my
23+ // More described below. I used this switch because I had an Arduino in the
24+ // house when I was writing new programs, then ran outside in the cold with my
2225// laptop to reprogram the Teensy that was running the real lights.
2326#define ARDUINO 1
2427
2831#include <StockPrograms.h>
2932#include <PlusPrograms.h>
3033#ifdef USE_REMOTE
34+ // Get at https://github.com/shirriff/Arduino-IRremote
3135#include <IRremote.h>
3236#endif
3337
3438#ifdef ARDUINO
3539// A regular Arduino. First string on pin 13, second on 12.
3640G35String lights_1 (13 , 50 , 50 , 0 , false);
3741G35String lights_2 (12 , 41 );
42+
3843#ifdef USE_REMOTE
39- IRrecv ir (11 );
44+ IRrecv ir (11 ); // IR receiver on pin 11.
4045decode_results ir_results ;
4146#endif
47+
4248#else
4349// A Teensy 2.0 that's been flashed with the Arduino Leonardo bootloader (thus
4450// permanently destroying the HalfKay bootloader that ships with the Teensy).
45- // The first string is connected to D6, and the second to B4.
51+ // The first string is connected to D6, and the second to B4.
4652G35String lights_1 (12 , 50 , 50 , 0 , false);
4753G35String lights_2 (8 , 41 );
4854#endif
@@ -55,13 +61,12 @@ PlusProgramGroup plus_programs;
5561G35StringGroup string_group ;
5662
5763LightProgram * CreateProgram (uint8_t program_index ) {
58- randomSeed (rand () + analogRead (0 ));
59- program_index = rand () % PROGRAM_COUNT ;
64+ program_index = random () % PROGRAM_COUNT ;
6065
61- if (program_index < StockProgramGroup ::ProgramCount ) {
62- return stock_programs .CreateProgram (string_group , program_index );
63- }
64- program_index -= StockProgramGroup ::ProgramCount ;
66+ if (program_index < StockProgramGroup ::ProgramCount ) {
67+ return stock_programs .CreateProgram (string_group , program_index );
68+ }
69+ program_index -= StockProgramGroup ::ProgramCount ;
6570
6671 if (program_index < PlusProgramGroup ::ProgramCount ) {
6772 return plus_programs .CreateProgram (string_group , program_index );
@@ -76,9 +81,31 @@ LightProgram* CreateProgram(uint8_t program_index) {
7681
7782ProgramRunner runner (CreateProgram , PROGRAM_COUNT , PROGRAM_DURATION_SECONDS );
7883
84+ // http://www.utopiamechanicus.com/77/better-arduino-random-numbers/
85+ // We assume A0 and A1 are disconnected.
86+ uint32_t seedOut (unsigned int noOfBits ) {
87+ uint32_t seed = 0 , limit = 99 ;
88+ int bit0 = 0 , bit1 = 0 ;
89+ while (noOfBits -- ) {
90+ for (int i = 0 ; i < limit ; ++ i ) {
91+ bit0 = analogRead (0 ) & 1 ;
92+ bit1 = analogRead (1 ) & 1 ;
93+ if (bit1 != bit0 )
94+ break ;
95+ }
96+ seed = (seed << 1 ) | bit1 ;
97+ }
98+ return seed ;
99+ }
100+
79101void setup () {
80- randomSeed (analogRead (0 ));
81- Serial .begin (57600 );
102+ uint32_t seed = seedOut (32 );
103+ randomSeed (seed );
104+ seed &= 0xff ;
105+ // random() isn't very random. But this seed generator works quite well.
106+ while (seed -- ) {
107+ random ();
108+ }
82109
83110#ifdef USE_REMOTE
84111 ir .enableIRIn ();
@@ -87,7 +114,6 @@ void setup() {
87114 delay (50 );
88115 lights_1 .enumerate ();
89116 lights_2 .enumerate ();
90- delay (50 );
91117
92118 lights_1 .do_test_patterns ();
93119 lights_2 .do_test_patterns ();
@@ -101,7 +127,6 @@ void loop() {
101127
102128#ifdef USE_REMOTE
103129 if (ir .decode (& ir_results )) {
104- Serial .println (ir_results .value , HEX );
105130 runner .switch_program ();
106131 ir .resume ();
107132 }
0 commit comments