I've assembled 12 modules into a 4 x 3 configuration, and it's just the bomb. I put the 1.4beta firmware onto one of the chips, and have it wired up so that the lower-right corner is where my power goes in, and that is where the only push-button was installed. All the switch lines are connected on the back of the board with some fine wire (#30 or #28 I think.)

I had been thinking about installing a simple on/off switch, but then I realized I wanted something that could be controlled without having to reach up and touch it. I'm planning to frame it and hang it up on the wall over a sofa, so it would have been awkward to reach up at it. I could have put a switch inline with the power, but then I got the idea to control it with an IR "tv remote".
What I've done is use an IR sensor (with built-in 38kHz filtering) to capture input from any IR controller. I used a PN2222 NPN transistor across the push-button, and in the middle I've used an ATtiny. The signal line from the IR sensor goes to INT0 on the Tiny. The Tiny, on catching activity on INT0, signals the NPN transistor for about 250ms which is the equivalent of pressing the switch for a moment. Then the Tiny starts a 2-hour countdown.
At the end of the countdown, the Tiny signals the NPN for 3500ms which equates holding the GoL button long enough to switch off the GoL. During the time that the Tiny is doing its 2-hour count, an additional green LED blinks once per second as a 'heartbeat' so I know the Tiny is running.
The IR sensor & ATtiny are not configured to watch for any code in particular, so any button on any IR remote will turn it on. Once it is on, it ignores any further input. I did put the ATtiny in a socket so I can remove & reprogram it later if I want to make any changes.
Here's a closeup of the controll circuits, which I mounted directly ontop of one of the GoL modules:

And finally, here's the code I used on the ATtiny:
- Code: Select all
/* IR switch, based on ATTiny
/reset 1 8 Vcc
n/c 2 7 Int0 (output from IR detector)
n/c 3 6 PB1 (to NPN transistor to GoL sw1)
Ground 4 5 PB0 (to indicator LED)
*/
#define MCU_FREQ 1000000UL
#include <avr/interrupt.h>
#include <avr/io.h>
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~(_BV(bit)))
uint16_t delay = 0;
void delayMS( uint16_t milliseconds ) {
uint16_t i;
for ( i = 0; i < milliseconds; i++ ) {
// tweaked for this application
register uint16_t loop_count = 240;
__asm__ volatile (
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" ( loop_count )
: "0" ( loop_count )
);
}
}
void golON() {
sbi(PORTB, PB1); // turn on NPN
delayMS(250); // wait 1/10 sec
cbi(PORTB, PB1); // turn off NPN
}
void golOFF() {
sbi(PORTB, PB1); // turn on NPN
delayMS(3500); // wait 3.5 sec
cbi(PORTB, PB1); // turn off NPN
}
ISR(INT0_vect) {
cli(); // turn off interrupts
if(delay==0) {
delay=3600*2; // 2 hour delay
golON(); // turn on the GoL panel
}
sbi(PORTB, PB0); // turn on indicator
delayMS(100); // wait 1/10 sec
cbi(PORTB, PB0); // turn off indicator
sei(); // enable interrupts
}
int main(void) {
sbi(DDRB, PB0); // set pb0 as output
sbi(DDRB, PB1); // set pb1 as output
cbi(PORTB, PB0); // set indicator off
cbi(PORTB, PB1); // set NPN off
delayMS(1000);
MCUCR = (1<<ISC01) | (1<<ISC00); // configure int0
GIMSK |= (1<<INT0); // enable int0
sei(); // enable interrupts
golON(); // turn on the GoL panel
delay=15; // small startup test
// go into regular routine
while(1) {
if(delay) {
delay--; // decrement delay counter
if(delay<1) { // if delay is over....
golOFF(); // turn off the GoL panel
} else {
sbi(PORTB, PB0); // heartbeat
}
}
delayMS(100); // brief delay
cbi(PORTB, PB0); // make sure indicator is off
delayMS(900); // finish the 1 second delay
}
}
Cheers!
p.s. I never really learned to code in c so if my coding is harsh or naive please be gentle.

