Pages: [1]   Go Down
Author Topic: Geocaching with morse code  (Read 534 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I hope this is something that someone will find usefull.

I am building a Geocache that will send the final cache location coordinates via morse code. I used a bare bones Attiny45 programmed with the Arduino ISP to accomplish my design.

The circuit have two LED's, one for "dit" and one for "dah" as well as one tone output and a serial output for reading the EEPROM. There is one input that will decide whether the coordinates will be pulsed out or the EEPROM byte will be pulses and send out via serial. The EEPROM byte is incremented each time the circuit is powered on. A magnetic switch will be used for switching the morse flasher on or off.
After a set amount of repeats, the Attiny will go into a sleep mode until the next restart just in case some cacher forget to remove the magnet.

I don't have a circuit diagram yet, not anything useable on this forum in any case. The box is an electrical outlet box, with a dummy front. The two LEDS is hot-glued unto to holes, this I have an opaque waterproof LED view holes. I can add pictures, but I think most folks will be happy with just seeing the code.
Perhaps there is some tweaks I can do to the code to make it work better.

I planned to post the code, but the forum said I am past the 9500 character limit. So I only add the main block.
If interested, I will try and make a plan to add more code.
Regards

Quote
/*
Morse code generator by Jacques Bayman
Will be used in a puzzle geocache where the final
coordinates will be send via morse code to the geocacher
Coordinates will be stored in a constant array.
 >> Add possible battery monitor on analogue to check for low battery 
 >> need hardware V-ref  -- unsure if worth it, will play with it though
 
*/


#define dotPeriod 250
#define dashPeriod (dotPeriod*3)
#define relaxTime (dotPeriod)
//#define letterSpace (dotPeriod*2)
#define wordSpace (dotPeriod*6)
#define ledPin_dot 1           //an LED on Attiny pin 1 or physical pin 6
#define ledPin_dash 2          //an LED on Attiny pin 2 or physical pin 7
#define freq 987        
#define tonePin 0             //a speaker on Attiny pin 0 or physical pin 5
#define ROM_Pin 4             //this is used to check if serial comms is required to read EEPROM
                              //physical pin 3. This order so can be initialised in loop
#define serial_out 3         //the serial TX pin physical pin 2
#define timeToStop 1        //used to stop LED's and speaker if the someone forget to remove the magnet.
                             //set a max for how many time the loop must run. This is to save some battery life

#include <EEPROM.h>
#include <avr/sleep.h>  //used to reduce power on the AVR - this where timeToStop comes in.
int romByte;
int stopCounter = 0;
const int phrase[] = {3,4};//,2,3}  //enter a numerical code here. Only
                              //numbers allowed
  
void setup() {
  Serial.begin(9600);
// The loop below set all pins except ROM_Pin as outputs. Hopefully shorter code  
  for(int i = 0; i < 4; i++) {
    pinMode(i, OUTPUT);
    digitalWrite(i, HIGH);
  }
  digitalWrite(tonePin, LOW);  // used to lower the tone pin back to low - not absolutely neccesarry
  pinMode(ROM_Pin, INPUT);     // this pin check if its the ROM being read. Active high means yes its the ROM
  
  warble();   //call a tone function to let user know the system is working. Also add a convenient delay
              //to the system making sure power switch is in correct place before attempting to increment the
              // ROM
              
//Increment the rom with every power up.  
 romByte = EEPROM.read(0);
  if (romByte != 255) {    //at 255, the ROM should go back to zero
    romByte++;
  } else {
    romByte = 0;
  }
  EEPROM.write(0, romByte);
}

void loop() {
  int i = 0;
                   
 //play thecoordinates in morse code while the ROM_Pin is low
  while (digitalRead(ROM_Pin) == LOW) {
    playLetter(phrase);
    delay(wordSpace);
    i++;

    // sizeof() return the number of bytes in an array, thus to get the correct number in an array, divide by
    //the sizeof an int. An int is two bytes. Also see serialOn function where it is also used to read ROM size.
    if (i >= sizeof(phrase) / sizeof(int)) {   //begin all over if there is something going on
      i = 0;
      stopCounter++;
      if (stopCounter >= timeToStop) {
   digitalWrite(tonePin, LOW);  //strictly not needed, but I like to make sure...
 //  Below code refers to this page http://www.gammon.com.au/forum/?id=11497 it is used to reduce power in case
 //  someone forgets to remove the magnet from the switch
   ADCSRA = 0;    // this will turn of the ADC - it does use quite a bit of power
   set_sleep_mode(SLEEP_MODE_PWR_DOWN); 
   sleep_enable();
   sleep_cpu();
      }
    }
  }
  serialOn();   // will only execute when the ROM_Pin is HIGH
}


Logged

Pages: [1]   Go Up
Jump to: