Archived Geocache GC3CT62 (Night Cache)

"In geheimer Mission"

 

The technical stages of this geocache disappeared several times I decided to archive this cache.

Because there has been a lot of effort in developing this cache I thought it might be interesting for the croud to see what's inside the box.

 

First assembling on the breadboard

The first step was to put everything together on the breadboard and check if I realize what I had in mind.

The goal was to put a LED as Input and monitor if a light source is lighting on it or not.

Additionally I put some more colored LEDs to show if the light is detected or not.

 

Drawing the PCB for the project

This was my very first project ever. I used a breadboard to wire it the hard way.

 

Putting everything in a nice frame

After the PCB was ready and the breadboard constellation worked, it was time to put everything in a nice frame.

Driling some holes for the 5 LEDs and everything was done.

 

Writing the code

With programming the ATMega168 the parts would not do a thing.

As power supply I used a 9V battery.

Here you can see the tiny and simple code which I used for that cache.

Additionally you can watch the video below to see how it worked in action.

 

Main Program

View source
// morse_code.c
// for NerdKits with ATmega168
 
#define F_CPU 14745600
 
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
 
#include "../libnerdkits/lcd.h"
#include "../mylibs/morsedb.h"
#include "../mylibs/morsedb.c"
 
// PIN DEFINITIONS:
//
// PB4 -- LED (Lichtsensor) Kathode 
// PB3 -- LED (Lichtsensor) Anode 
// PC4 -- LED (Morse) Anode
// PC2 -- LED (Status LED Light) Anode
// PC1 -- LED (Status LED Dark) Anode
// PB5 -- LED (Reset LED) Anode
 
 
unsigned char i;
unsigned char led_abfrage(unsigned char zeit) {
 
	PORTB &= ~(1<<PB3); // Portb.3 auf Masse schalten
	PORTB |= (1<<PB4); // Portb.4 auf +Ub schalten, um die LED zu 'laden'
	_delay_us(10); // Ladezeit 10 (1) µs, kann ggf. noch verkleinert werden
 
	DDRB &= ~(1<<PB4); // Portb.4 nun zwecks Abfrage der LED-Ladung auf 'Eingang' schalten
	PORTB &= ~(1<<PB4); // Pullup abschalten, sonst geht's nicht!
 
	_delay_ms(zeit); // Entladezeit zeit_ms (1500 µs) - je kleiner, je unempfindlicher
 
	i = (PINB & (1<<PINB4)); // Ladezustand einlesen
 
	DDRB |= (1<<PB4); // Portb.4 wieder auf Ausgang schalten
	PORTB &= ~(1<<PB4); // Portb.4 auf Masse schalten
 
	return i;
}
 
volatile int32_t lightcounter;
volatile int32_t darkcounter;
volatile int32_t lightduration;
volatile int32_t signal1;
volatile int32_t signal2;
volatile int32_t signal3;
 
int main(void) {
 
	// start up the LCD
	lcd_init();
	lcd_home();
 
	DDRB  = 0b00011000; // Pinb.3 und .4 auf 'Ausgang', Rest auf 'Eingang' schalten
	DDRC |= (1<<PC4);  // Yellow LED (Morse) as output
	DDRC |= (1<<PC2);  // Small Green as Output (For Showing if Light is on)
	DDRC |= (1<<PC1);  // Small Red as Output (For Showing if Light is off)
	DDRB |= (1<<PB5);  // Small Blue as Output (For Showing Reset Status)
	PORTB = 0b11100111; // Pullups zuschalten, außer für Pinb.3 und .4
 
  while(1) {
	if (led_abfrage(6) == 0) { 				// Abfrage ob Licht AN ist
 
		PORTC |= (1<<PC2);
		PORTC &= ~(1<<PC1);
 
		lightcounter++;
		lightduration = lightcounter;
		darkcounter=0;
 
		lcd_home();
		lcd_write_string(PSTR("Light: "));
		lcd_write_int16(lightduration);
	}
	else{										// Abfrage ob Licht AUS ist
 
		lcd_line_two();
		lcd_write_string(PSTR("Dark: "));
		lcd_write_int16(darkcounter);
 
		if (signal1==0 && signal2==0 && signal3==0){
 
			PORTB |= (1<<PB5);
		}
 
		else{
 
			PORTB &= ~(1<<PB5);
		}
 
		PORTC |= (1<<PC1);
		PORTC &= ~(1<<PC2);
 
		darkcounter++;	
		lightcounter = 0;
 
		if (darkcounter>=4000){					// Zurücksetzen aller Signalerkennungen wenn der Zähler den Wert 4000 (circa 30 Sekunden) erreicht.
 
			signal1=0;							// 0 bedeutet nicht erkannt.
			signal2=0;							// 0 bedeutet nicht erkannt.
			signal3=0;							// 0 bedeutet nicht erkannt.
		}
 
		else{
 
			if((lightduration >=1 && lightduration <=8) && signal1==0){				// kurzes Signal
 
				signal1=1;						// 1 bedeutet, dass das Signal erkannt wurde.
			}
 
			else if((lightduration >=12 && lightduration <=35) && signal1==1){		// langes Signal
 
				signal2=1;						// 1 bedeutet, dass das Signal erkannt wurde.
			}
 
			else if((lightduration >=1 && lightduration <=8) && signal2==1){			// kurzes Signal
 
				signal3=1;						// 1 bedeutet, dass das Signal erkannt wurde.
			}
 
 
			while(signal1==1 && signal2==1 && signal3==1){
 
					PORTC &= ~(1<<PC1);	// Turn Off Dark LED
 
					morse_digit('N');
					_delay_ms(1500);
					morse_digit('4');
					_delay_ms(1500);
					morse_digit('7');
					_delay_ms(1500);
					morse_digit('.');
					_delay_ms(1500);
					morse_digit('1');
					_delay_ms(1500);
					morse_digit('6');
					_delay_ms(1500);
					morse_digit('.');					
					_delay_ms(1500);
					morse_digit('1');					
					_delay_ms(1500);
					morse_digit('5');					
					_delay_ms(1500);
					morse_digit('9');					
					_delay_ms(1500);
 
					morse_digit('E');
					_delay_ms(1500);
					morse_digit('1');
					_delay_ms(1500);
					morse_digit('1');
					_delay_ms(1500);
					morse_digit('.');
					_delay_ms(1500);	
					morse_digit('1');
					_delay_ms(1500);
					morse_digit('8');
					_delay_ms(1500);
					morse_digit('.');					
					_delay_ms(1500);
					morse_digit('8');					
					_delay_ms(1500);
					morse_digit('9');					
					_delay_ms(1500);
					morse_digit('1');					
					_delay_ms(1500);
 
					// END
 
					PORTC |= (1<<PC2);		// Turn On Light LED
					PORTC |= (1<<PC1);		// Turn On Dark LED
					PORTB |= (1<<PB5);		// Turn On Reset LED
 
					_delay_ms(1500);
 
					PORTC &= ~(1<<PC1);	// Turn Off Dark LED
					PORTC &= ~(1<<PC2);	// Turn Off Light LED
					PORTB &= ~(1<<PB5);	// Turn Off Reset LED
 
					_delay_ms(1500);					
			}	
		}
	}	
  }
  return 0;
}