Saviour A safety system with SOS signaling, Morse code converter and GPS tracking for your next trip to a remote location
919 1
Avijit Das

Saviour A safety system with SOS signaling, Morse code converter and GPS tracking for your next trip to a remote location

The countless stories and movies like the Lord of the Flies, Robinson Crusoe, Titanic, Cast Away,...

Description:-

The countless stories and movies like the Lord of the Flies, Robinson Crusoe, Titanic, Cast Away, Six Days Seven Nights, etc. where the protagonist gets stuck on an island, even though it sounds very adventurous, but nonetheless the dangerous probability of it happening in real to people still remains. The idea behind Saviour was to create a hack that allows people to travel to remote locations without having to worry about getting lost or getting stuck there. ##What it does Saviour is an emergency tool that is very powerful, in times of real juncture. Saviour can do radio signalings like the popular SOS signal or any emergency signaling. If one gets stuck in a deserted area, say on an island or some mountain, where the Mobile gets useless, due to no network coverage, radios are still there, which can be a very effective way of communication in that scenario, and still, they are used all way. Saviour uses Morse Code signaling via a radio transmitter, also with a LED. It also has an OLED display, that can translate any sentence to its Morse Code, and display that code on the OLED simultaneously transmitting the code over the air, and also flashing it via a LED. It also has a buzzer to sound, how the Code will sound. Now, it also contains a GPS that can get your direct coordinates. Since GPS satellites revolve all around the world, they can connect and get your current location. So with that not only Savior can send the SOS signal using radio, but Saviour sends the location details i.e. the latitude and longitude of the signal's origin location using the GPS. This will make it a lot easier for the search party to find the lost individual thus speeding up the process of the rescue operation. This hack is not only a very important tool that will come in handy for people going on a vacation or traveling because of work purposes but it can also be used as an educational tool for learning Morse code since it has a Morse Code translator. ##Challenges we ran into Making the interface was a bit tricky. Stopping abnormal flow or increment of button pushes using flags. Getting ready with the GPS. Since the GPS works best over open air. Printing the translated Morse Code on the OLED was a bit tricky too. ##Accomplishments that we're proud of We were in a bit of a time crunch since a lot had to be done, but we decided to work on one aspect at a time and finish that first. We are really proud to have overcome all the challenges like making the interface, making the FM transmitter. Displaying the morse code and listening to the buzzer to beep in accordance was a very proud moment. Thus bringing a mere project idea into life and that too in very little time is what we are very happy about. Saviour is a hack that we are very proud of building this tool because it can really help people in times of emergency. ##What we learned We learned with help of simple components, such as the potentiometer and button we can create such a good graphical interface. We learned how to drive OLED displays. Learned about Morse Codes, speed. Learned a bit about GPS and the NMEA protocol. ##What's next for Saviour We are thinking of adding a digital compass, and an altimeter by which it can be used as a very powerful and absolute emergency item, and a normal human must-have.

Project Used Hardware

ARDUINO UNO REV3 x 1 GPS-16329 SparkFun Electronics x 1 1.3 Inch Oled Display Module x 1 Switch Tactile Push Button Switches x 1 KY-006 Passive Piezoelectric Buzzer Alarm Sensor Module x 1

Project Used Software

Arduino IDE

Project Hardware Software Selection

Saviour has four main parts - one is the Morse Code translator, indicator, transmitter, and the GPS. Firstly we created a menu-driven Graphics Interface for choosing the mode, whether the Morse Code or the GPS. This is done by a potentiometer to scroll, and a button to select. The Morse code translator is built by parsing the String sentence character by character and creating its Morse equivalent. According to the supported Characters, the program translates it to a Morse String. To create a sentence, we reused the same button and the potentiometer. The potentiometer, scrolls through the characters, and the button increments the cursor. Next, the Indicator was built using a small Buzzer and a LED which can also be used for signaling, and it is still considered to be an effective way. The buzzer plays the Morse Code with a Farnsworth speed of 10 in sync with the LED flashes. After that, a simple single transistor FM transmitter was built using a coil, capacitor, and transistor. Its job is to transmit the Morse code over open Air. Last but not least, the life saviour, the GPS. As the name suggests, this part contains a GPS, through which the NMEA data is received as packets. Those get parsed and fetch the coordinates and finally get transmitted via the transmitter. Now all these interfaces are displayed over an OLED display, and all of them get controlled by the Arduino. ArduinoIDE was used to develop Firmware.

Circuit Diagram

Safety System Circuit

Code

#include <Arduino.h>
#include <U8x8lib.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

#define morse (String[]){"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "---...", "---...", "-...-", "-...-", "-...-", "..--..", ".--.-.", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."}

#define led 7

#define buzz 5

U8X8_SSD1306_128X64_NONAME_SW_I2C u8x8(SCL, SDA, U8X8_PIN_NONE);

SoftwareSerial ss(4, 3);
TinyGPSPlus gps;

int fran = 233;

int dit = 80;
int dah = 200;

char l = ' ';
String sent = "";
int x = 0, y = 0, ch=0, lch=-1;
boolean f = false, cursor = false, goMenu = true;
long ps = 0, out;

//static const String morse[] PROGMEM = {"-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----.", "---...", "---...", "-...-", "-...-", "-...-", "..--..", ".--.-.", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--.."};

String lati="0.00000",lngt="0.00000";


void setup() {
  pinMode(2, INPUT);
  pinMode(buzz, OUTPUT);
  pinMode(led, OUTPUT);

  u8x8.begin();
  u8x8.setFlipMode(0);
  u8x8.setBusClock(100000);
  u8x8.setFont(u8x8_font_chroma48medium8_r);
  ss.begin(9600);
  Serial.begin(115200);
}

 

void loop()
{

  while (!goMenu)
  {
      if(ch==0)
        Morse();
        
      else if(ch==1)
      GPS();
     
  }
      
    
    

  selectMenu();

    
 
}

 


void selectMenu()
{
  ch=map(analogRead(A0), 0,1020,0,3);
  Serial.println(ch);
  x=0;
  y=0;
 
if(lch!=ch)
{
  if(ch==0)
  {
   u8x8.clearDisplay();
   u8x8.setCursor(4,3);
   u8x8.print("Morse");
   u8x8.setCursor(4,4);
   u8x8.print("Code");
   u8x8.setCursor(3,6);
   u8x8.print("-.-.-.-");
  }

  else if(ch==2)
  {
   u8x8.clearDisplay();
   u8x8.setCursor(4,3);
   u8x8.print("Compass");
  }

  else if(ch==1)
  {
   u8x8.clearDisplay();
   u8x8.setCursor(4,3);
   u8x8.print("GPS");
  }

  else if(ch==3)
  {
   u8x8.clearDisplay();
   u8x8.setCursor(4,3);
   u8x8.print("Altitude");
  }
 
  lch=ch;
}


if(digitalRead(2)==1)
{
  u8x8.clearDisplay();
  goMenu=false;
  delay(100);  
}


out=millis();
}

 


boolean Morse()
{
  l = (char)(90 - map(analogRead(A0), 0, 1021, 0, 26));

    if (l == 64)
      l = ' ';

    u8x8.setCursor(x, y);
 
  if (digitalRead(2))
  {
    if (f)
    {
      sent += l;
      x++;
      f = false;
      u8x8.print(l);
      if (x == 16)
      {
        y++;
        x = 0;
        u8x8.setCursor(x, y);
      }
      Serial.println(sent);
    }

    if (millis() - out > 3000)
    {
      String z = morseTranslate(sent);
      Serial.println(z);
      out = millis();
      printMorse(z);
      spitMorse(z);
      goMenu = true;
      while(true)
      {
        if(digitalRead(2))
        {
          goMenu = true;
          delay(100);
          lch=-1;
          return !f;  
        }          
      }
      
    }
  }

  else
  {
    f = true;
    out = millis();
  }

  if (millis() - ps >= 500)
    {
      cursor = !cursor;
      ps = millis();
    }

    if (cursor)
      u8x8.print(l);
    else
      u8x8.print('_');

  return !f;
}


String morseTranslate(String line)
{

  String res = "";

  for (int i = 0; i < line.length() - 1; i++)
  {
    char x = line.charAt(i);
    if (x == ' ')
      res += '|';
    else if (x == '.')
      res += ".-.-.-";

    else
      res += morse[x - 48] + ' ';

  }

  return res;
}

void printMorse(String line)
{
  u8x8.clearDisplay();
  for (int i = 0; i < line.length(); i++)
  {
    u8x8.setCursor(i % 16, i / 16);
    u8x8.print(line.charAt(i));
    x = i % 16 + 1;
    y = i / 16;
  }
  sent = "";
}


void spitMorse(String s)
{
  for (int i = 0; i < s.length(); i++)
  {

    char x = s.charAt(i);

    if (x == ' ')
    {
      digitalWrite(led, 0);
      analogWrite(buzz, 0);
      delay(200);
    }

    else if (x == '.')
    {
      analogWrite(buzz, fran);
      digitalWrite(led, 1);
      delay(dit);
      analogWrite(buzz, 0);
      digitalWrite(led, 0);
    }

    else if (x == '-')
    {
      analogWrite(buzz, fran);
      digitalWrite(led, 1);
      delay(dah);
      analogWrite(buzz, 0);
      digitalWrite(led, 0);
    }

    else
    {
      analogWrite(buzz, 0);
      digitalWrite(led, 0);
      delay(500);
    }

    delay(50);
  }
}


void GPS()
{
 
   while (ss.available() > 0)
  {
    if (gps.encode(ss.read()))
      displayGpsData();

      long cs=millis();
      while(digitalRead(2))
      {
        Serial.println(millis()-cs);
        if(millis()-cs>3000)
        {
          String li=morseTranslate(lati.substring(0,8));
          String lg=morseTranslate(lngt.substring(0,8));
          printMorse(li);
          spitMorse(li);
          printMorse(lg);
          spitMorse(lg);
          goMenu = true;
          while(true)
          {
            if(digitalRead(2))
            {
              goMenu=true;
              delay(100);
              lch=-1;
              return;
            }
          }
        }
      }
      
  }
}


void displayGpsData()
{
  Serial.print(F("Location: "));
  if (gps.location.isValid())
  {
    lati = "lat:"+String(gps.location.lat(), 6);
    lngt = "lng:"+String(gps.location.lng(), 6);

    u8x8.refreshDisplay();
    
    u8x8.setCursor(0,1);
    u8x8.print(lati);
    u8x8.setCursor(0,3);
    u8x8.print(lngt);
    
    Serial.print(lati);
    Serial.print(F(","));
    Serial.print(lngt);
    
  }
  else
  {
    Serial.print(F("INVALID"));
    
    u8x8.setCursor(0,1);
    u8x8.print("NO FIX");
    
    u8x8.refreshDisplay();
  }

  Serial.println();
}