Båtlarm med GPS och GSM

Berätta om dina pågående projekt.
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Båtlarm med GPS och GSM

Inlägg av ojje »

Dags för nästa projekt.
Försäkringsbolaget sänker min båtpremie med ca 700 kronor per år om jag får ett meddelande var båten befinner sig om den blir stulen. För 700 kronor kan man handla en hel del elektronik så varför inte bygga ett båtlarm/tracker.

Det finns dock några saker jag oroar mig mer för än om båten blir stulen.
1. Att t.ex. en genomföring går sönder så att båten börjar ta in vatten och tillslut riskerar att sjunka
2. Att jag får ett gasläckage. Speciellt oroande om vi är ombord
3. Att batterierna laddas ur när jag inte är i båten
4. Att båten börjar dragga och driva iväg när vi ligger på svaj i någon vik

Förutom detta vore det praktiskt att:
1. Kunna slå på kylen eller till och med värmaren innan vi kommer till båten
2. Kontrollera vilken temperatur det är inne i båten och framförallt se vilken luftfuktighet det är

Om jag dessutom kan bli larmad om någon bryter sig in i båten eller ännu värre stjäl den så är det en bonus ;-)

Jag är ingen programmerare, men kommer ge mig i kast med en Arduinokrets och till den koppla ett antal tillbehör. Just nu tänker jag mig följande:
1. Ett GPRS-kort för att kunna få och skicka SMS och ev. kunna få telefonsamtal för medhörning
2. Ett GPS-kort för att få position, fart, riktning, mm
3. En temp och fuktgivare
4. En vattensensor
5. En propangivare för att detektera gasläckage
6. En summer för att få lokala larm när någon är ombord
7. En spänningsmätare
8. En PIR för att detektera rörelse i båten
9. Några reläer för att kunna styra t.ex. påslag av kyl eller möjligen en siren

Det hinner säkert bli fler in- och utgångar och det är ju därför bra att få tips och idéer från andra här på forumet.
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Vattengivare

Inlägg av ojje »

Vattengivare
Jag börjar med en sensor för att indikera vattenläckage. På Dx.com fann jag en enkel probe för att analogt mäta fuktighet. Hade varit mycket enkelt att bygga något själv, men för 24 kronor så…
http://dx.com/p/keyes-soil-moisture-con ... red-225594

Genom att montera givaren under durken i båten kan jag upptäcka ett tidigt vattenläckage. Jag har dessutom en ”balja” på ca 20 liter dit allt vatten rinner. Det är inte helt ovanligt att det blir ett läckage i båtens dricksvattensystem och det vatten som då rinner ut är rätt harmlöst samt att mängden är begränsad.

Jag har experimenterat lite och kommit fram till att vattnet i Östersjön (ca 5 – 10 gram salt per liter vatten) leder ström ungefär dubbelt så bra som vanligt dricksvatten. Vattnet på Västkusten (ca 30 gram salt per liter vatten) leder förstås ström ännu bättre, men inte linjärt bättre.

Efter en del kodknackande har jag nu en sketch som indikerar om:
1. Jag fått vatten i båten
2. Om det verkar vara saltvatten (om det är saltvatten från Västkusten så får man ett klart besked)
3. Tiden det har tagit för vattenstånd att stiga 2 cm (vilket innebär ca 1,5 liter för min del

Finns säkert en hel del att förbättra i min kod, men just nu ger den det jag önskar.

Kod: Markera allt

 //Vattenlarm som också varnar för saltvatten

int waterSensor = A0;   // Vattensensor på analog pin 0
int waterLevel = 0;     // Värde på vattennivån (vattenledningsförmåga)
int old_waterLevel = 0; // Tidigare värade på vattennivån
unsigned long firstWaterTime = 0; // Tid för första vattenindikationen
unsigned long secondWaterTime = 0; // Tid till andra vattennivån nås

void setup () {
   Serial.begin (19200);
}

void loop () {
  
 waterLevelCheck(); 
   delay (1000);
}

// ------- Funktion för att visa tid i sekunder, minuter och timmar ------- 
void showTime(){
byte showMinute = (secondWaterTime/1000/60);
int showSecond = ((secondWaterTime/1000) - (showMinute*60));
byte showHour = (showMinute/60); 

  if(showHour < 10) {
   Serial.print("0");
   Serial.print(showHour);
   }
  else{
   Serial.print(showHour);
   }   
Serial.print(":");
  if(showMinute < 10) {
   Serial.print("0");
   Serial.print(showMinute);
   }
  else{
   Serial.print(showMinute);
   }   
Serial.print(":");
  if(showSecond < 10) {
   Serial.print("0");      
   Serial.print(showSecond);
   }
  else{
   Serial.print(showSecond);
   }
Serial.println(" hh:mm:ss");
}
// ---------------


// ------- Funktion för undersöka vattennivån i kölsvinet ------- 
void waterLevelCheck() {

waterLevel = analogRead(waterSensor);  // Vattennivån får givarens värde
  
  if ((waterLevel > 50) && (old_waterLevel == 0)) {
   Serial.println("Vatten under durken, verkar ej vara saltvatten") ;
   firstWaterTime = millis();
  }
  
  if ((waterLevel > 500) && (old_waterLevel == 0)) {
   Serial.println("Vatten under durken, verkar vara saltvatten") ;
   firstWaterTime = millis();
  }

  if ((waterLevel > 600) && (old_waterLevel == 0)) {
   Serial.println("Saltvatten under durken!") ;
   firstWaterTime = millis();
  }  

  if ((old_waterLevel > 50) && (waterLevel > 630)) {
   secondWaterTime = (millis() - firstWaterTime);
   Serial.print("Vattnet har stigit med 2 cm efter ");
   showTime();
  }  
  
 if ((old_waterLevel > 500) && (waterLevel > 760)) {
   secondWaterTime = (millis() - firstWaterTime);
   Serial.print("Vattnet har stigit med 2 cm efter ");   
   showTime();
  }  

old_waterLevel = waterLevel;  // Vattennivåns värde sätts till att vara ett gammalt värde

 if ((old_waterLevel == 0) && (waterLevel == 0)) {
   Serial.println("Inget vatten under durken") ;
 }
}
// --------------- 
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Mäta batterispänning

Inlägg av ojje »

För att kunna mäta spänningen i båtens batteribank och även få varningar om en urladdning sker gjorde jag en liten spänningsdelare med två motstånd som kopplas till en analog ingång på Arduinokortet samt till plus och minus på batteribanken. Bifogar kod som testar funktionen.

Kod: Markera allt

const int batteryPin = A0;  // Spänningdelad spänning som skall mätas kopplas till A0
// R1 är på 40kOhm och R2 på 20 kOhm. Max inspänning blir då 15V
int voltIn;

void setup() {
  Serial.begin(19200); 
}

void loop() {
volt();
delay(1000);                    
}

void volt() {
  voltIn = analogRead(batteryPin);
  float voltUt = (voltIn/1023.)*13.95; //float för att få decimaler. 13.95 kaliberas efter uppmätt inspänning
    if(voltUt >= 12.4){
 Serial.print("Batterier: "); 
 Serial.print(voltUt);
 Serial.println(" volt");
    }
    if(voltUt < 12.4 && voltUt >= 12.2){
 Serial.print("Batterier: "); 
 Serial.print(voltUt);
 Serial.println(" volt");
 Serial.println("Dags att ladda"); 
    }
    if(voltUt < 12.2){
 Serial.print("Batterier: "); 
 Serial.print(voltUt);
 Serial.println(" volt");
 Serial.println("Kritiskt! - Dags att ladda"); 
    }
     if(voltUt < 11.8){
 Serial.print("Batterier: "); 
 Serial.print(voltUt);
 Serial.println(" volt");
 Serial.println("Batteribanken tom!"); 
    }
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Variosboy
Inlägg: 834
Blev medlem: 5 september 2005, 17:10:03
Ort: kristinehamn

Re: Båtlarm med GPS och GSM

Inlägg av Variosboy »

Vore fiffigt att med hjälp av gps:en bestämma hur vattengivares värde ska tolkas, alltså olika tabeller beroende på vart du är med båten.
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Re: Båtlarm med GPS och GSM

Inlägg av ojje »

Kul idé. Blir nog inte i version 1, men förstås helt möjligt. Det trixigaste just nu är om jag får ett sötvattenslarm när båten ligger i Mälaren. Är det dricksvatten eller sjövatten....
na2jojon
Inlägg: 7
Blev medlem: 19 maj 2013, 00:06:42

Re: Båtlarm med GPS och GSM

Inlägg av na2jojon »

Skulle man inte kunna koppla en sensor till vattentanken och om denna meddelar att det är tomt, alternativt snabb sänkning av nivån, samtidigt som det går ett sötvattenslarm så är det dricksvatten.
Användarvisningsbild
netrunner
Inlägg: 5510
Blev medlem: 4 februari 2005, 12:26:05
Ort: 127.0.0.1

Re: Båtlarm med GPS och GSM

Inlägg av netrunner »

Hur stor sötvattentank har du? Man kan ju ha en mekanisk nivåbrytare som larmar när det garanterat är mer vatten än vad sötvattentanken rymmer.
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Re: Båtlarm med GPS och GSM

Inlägg av ojje »

Jag har närmare 400 liter fördelade på två olika tankar. Enda gången det blir ett problem är ju om jag har båten liggandes i sötvatten och jag samtidigt får ett "sötvattenslarm". Båten ligger i princip hela tiden i saltvatten och då vet jag per automatik om det är ett dricksvattenläckage eller om vattnet kommer utifrån.
Jag ser det inte som ett så stort problem om dricksvattnet läcker ut. Båten sjunker inte och den mängden vatten ställer inte till någon skada (max 200 liter som rinner ut då tankarna är åtskilda med kran)
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Temperatur och luftfuktighet

Inlägg av ojje »

Temperaturen är kanske inte så viktig under sommarsäsongen, men är mycket viktig att känna till om man till exempel har båten liggandes i sjön en vinter.
Att få kännedom om luftfuktigheten är dock viktigare. En relativ luftfuktighet som överstiger 75% innebär stor risk för mögeltillväxt. Mycket bra att få en varning om detta under hösten eller vårvintern så man vet om torrboll eller luftavfuktare måste åtgärdas.

Jag använder en enkel DHT11 fukt och temperaturgivare med tillhörande bibliotek. Det finns givare som är mycket mer exakta, men detta fungerar gott och för mitt behov.
Se mer fakta om givaren t.ex. här: http://www.adafruit.com/products/386

Koden testar själva funktionen och kommer att byggas på med någon form av larm när jag sedan bygger ihop det hela.

Kod: Markera allt

//Temperatur och fuktgivare
#include "DHT.h"

int tempfukt = 12;     // Temp och fuktgivaren kopplas in på pin 12
DHT dht(tempfukt, DHT11);

void setup()
{
  Serial.begin(19200);               
  dht.begin();
}
 
void loop()
{
temp();
delay(1000);  
}

// ------- Funktion för att skriva fukt och temperatur ------- 
void temp(){
  int h = dht.readHumidity();
  int t = dht.readTemperature();
  if (isnan(t) || isnan(h)) {
    Serial.println("Lyckades inte läsa temperatur eller fukt");
  } else {
    Serial.print("Fukt: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperatur: ");
    Serial.print(t);
    Serial.println(" *C");
  } 
}
// --------------- 
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Morpheuzz
Inlägg: 17
Blev medlem: 11 november 2007, 08:18:24
Ort: Trosa
Kontakt:

Re: Båtlarm med GPS och GSM

Inlägg av Morpheuzz »

Mycket intresant projekt! Har själv funderat på ett liknande projekt för att hålla kolla på temp position stöm mm och även en mer exakt knopmätare.

Är inte en DHT22 givare att föredra efter som den även kan mäta minusgrader? DHT11 givaren klarar bara av att mäta från 0-50°C medans DHT22 mätter mellan -40 to 125°C och är mer nogrann mm http://learn.adafruit.com/dht
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Re: Båtlarm med GPS och GSM

Inlägg av ojje »

Aah, det visste jag inte. Då får det bli byte av sensor. Tack för det. .
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

Gaslarm

Inlägg av ojje »

Gaslarm
Äntligen kom gassensorn från DX: http://dx.com/p/mq-6-combustible-gas-pr ... ino-179926
Hittade ett datablad här: https://www.sparkfun.com/datasheets/Sen ... c/MQ-6.pdf
Tyvärr har ”skyddshuven” fått sig en smäll i transporten och blir rejält bucklig.
Sensorn har fyra pinnar. En för +5V, en för jord, en för digital output och en för analog output. Jag har inget behov av att veta om det bara är lite gas och kommer därför använda den digital avläsningen. På kortet sitter en liten trimpot där man kan justera känsligheten innan man får en hög nivå på den digitala pinnen.

Förutom att mitt larm kommer att skicka mig ett SMS om det blir ett gasläckage så vill jag också ha en summer som tjuter om läckaget sker när man är i båten (vilket torde vara högst sannolikt).

Är ännu inte helt nöjd med funktionen hos sensorn. I koden väljer jag inledningsvis att skriva ut det analoga gasvärdet för att se hur känslig sensorn är. Först hade jag problem att få någon indikation alls, men efter att ha tryckt min gasbrännare med butangas mot sensorn i några sekunder så började summern ljuda. Lyckades ventilera bort gasen och testade igen. Den här gången fick jag inte tyst på summern. Antagligen påverkar jag sensorn med min fuktiga andedräkt i kombination med att jag övermättade den stackars sensorn med gas. Efter ca 10 minuter i ren luft börjar sakta värdena gå åt rätt håll igen.
Då sensorn kommer få sin placering nere i kölsvinet där gasansamlingen troligen blir störst är jag inte speciellt orolig att inte få något utslag. Dock kommer larmet behöva provköras någon gång per säsong då sensorn är känslig både mot kondens och kyla…

Kod: Markera allt

//Gaslarm som varnar för propan och butangas

int gasSensor = 11;   // Gassensor på pin 11
int gasSummer = 10;   // Summer på pin 10
int gasStatus = 0;      // Larmstatus

int gasAnalogSensor = A0; //Bara för test av analog avläsning
int gasAnalogValue = 0;   //Bara för test av analog avläsning


void setup () {
  
   Serial.begin (19200);
   pinMode(gasSensor, INPUT);
   pinMode(gasSummer, OUTPUT);   
}


void loop () {
  gasAnalogValue = analogRead(gasAnalogSensor);   //Bara för test av analog avläsning
  Serial.println(gasAnalogValue);   //Bara för test av analog avläsning
 gasLarm(); 
   delay (500);
}



// ------- Funktion för att visa tid i sekunder, minuter och timmar ------- 
void gasLarm() {
 gasStatus = digitalRead(gasSensor);

   if(gasStatus == HIGH) {
    digitalWrite(gasSummer, HIGH);   
    Serial.println("Gaslarm!"); 
   } 
   else {
    digitalWrite(gasSummer, LOW); 
   }
}
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Båtlarm med GPS och GSM

Inlägg av johano »

Hehe det ser precis ut som du håller på o bränna upp kortet på den bilden :-)

/johan
ojje
Inlägg: 72
Blev medlem: 18 maj 2011, 22:23:04
Skype: orjan_johansson
Ort: SIGTUNA

GPS

Inlägg av ojje »

GPS
Idag anlände min andra GPS. Den här köpte jag för en hundring på Ebay (den förra slutade att fungera, troligen efter en lite statisk elektricitet…).
Det är ublox som gör hårdvaran och det verkar vara samma grejer som sitter på de flesta GPS-korten till Arduino. Kretsen heter NEO 6M och NEO-chipet verkar vara framtaget för utvärdering och lärande. Det finns en hel del dokumentation, men jag finner ingen firmware som passar till detta chip. Det förra kortet kommunicerade med 38400 baud, men det här visade sig vara inställt på 9600. Det tog lite tid innan jag listade ut det, men ublox har en suverän programvara för att analysera kortet samt göra inställningar på det: http://www.u-blox.com/en/evaluation-sof ... enter.html

Testade att koppla kortet direkt till datorn via en seriell-USBkabel och vips fick jag in positionen på datorskärmen. Upplever chipet som riktigt raskt och med bra inomhustäckning.

I min kod använder jag biblioteket TinyGPS och har knåpat ihop ett meddelande som skall skickas som SMS. I min första version kommer meddelandet se ut så här:
-------------
Datum: 2013-12-18 Tid: 21:56:17 UTC
Position: 59.61558 N, 17.70077 E
Hastighet: 0.13 knop
Kurs: 0.00°
Google Maps: https://maps.google.com/maps?q=59.61558 ... tput=embed
-------------

Kod: Markera allt

#include <TinyGPS.h>
#include <SoftwareSerial.h>

SoftwareSerial gpsSerial(2, 3); 

TinyGPS gps;
void gpsdump(TinyGPS &gps);
void printFloat(double f, int digits = 2);


void setup()
{
  Serial.begin(9600);
  gpsSerial.begin(9600);
}

void loop()
{
// ------- Skriver ut data från GPS ------- 
  bool newdata = false;

    if (gpsSerial.available()) {
      char c = gpsSerial.read();
       if (gps.encode(c)) {
        newdata = true;
      }
    }
  if (newdata) {
    Serial.println("-------------");
    Serial.print("Data fr"); Serial.write(229);Serial.println("n GPS");
    gpsdump(gps);
    Serial.println("-------------");
    Serial.println();
  }
// --------------      
}

// ------- Fuktion för att konfigurera data som skall skrivas ut från GPS ------- 
void gpsdump(TinyGPS &gps)
{
  float flat, flon;
  int year;
  byte month, day, hour, minute, second;

  gps.crack_datetime(&year, &month, &day, &hour, &minute, &second);
  Serial.print("Datum: "); Serial.print(static_cast<int>(year)); Serial.print("-"); 
    Serial.print(static_cast<int>(month)); Serial.print("-"); Serial.print(day);
  Serial.print("  Tid: "); Serial.print(static_cast<int>(hour)); Serial.print(":"); 
    Serial.print(static_cast<int>(minute)); Serial.print(":"); Serial.print(static_cast<int>(second)); Serial.print(" UTC");
    Serial.println(); 

  gps.f_get_position(&flat, &flon);
  Serial.print("Position: "); printFloat(flat, 5); Serial.print(" N"); Serial.print(", "); printFloat(flon, 5); Serial.print(" E");
    Serial.println();

  Serial.print("Hastighet: "); printFloat(gps.f_speed_knots()); Serial.print(" knop");
    Serial.println();
    
  Serial.print("Kurs: ");
    printFloat(gps.f_course()); Serial.write(176);
    Serial.println();
    
  gps.f_get_position(&flat, &flon);    
 Serial.print("Google Maps: "); Serial.print("https://maps.google.com/maps?q="); printFloat(flat, 5); Serial.print(","); printFloat(flon, 5); Serial.print("+(Safari)&z=17&output=embed");
    Serial.println();  
}
// -------------- 

// ------- Fuktion för att korrigera data från GPS ------- 
void printFloat(double number, int digits)
{
  // Handle negative numbers
  if (number < 0.0) {
     Serial.print('-');
     number = -number;
  }

  // Round correctly so that print(1.999, 2) prints as "2.00"
  double rounding = 0.5;
  for (uint8_t i=0; i<digits; ++i)
    rounding /= 10.0;
  
  number += rounding;

  // Extract the integer part of the number and print it
  unsigned long int_part = (unsigned long)number;
  double remainder = number - (double)int_part;
  Serial.print(int_part);

  // Print the decimal point, but only if there are digits beyond
  if (digits > 0)
    Serial.print("."); 

  // Extract digits from the remainder one at a time
  while (digits-- > 0) {
    remainder *= 10.0;
    int toPrint = int(remainder);
    Serial.print(toPrint);
    remainder -= toPrint;
  }
}
// -------------- 
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Båtlarm med GPS och GSM

Inlägg av jesse »

trevligt projekt. Jag hade något liknande på gång för något år sedan, men det stupade på tidsbrist - det blev bara ett slarvigt prototypkort som jag aldrig kom mig för att programmera... Så jag följer ditt projekt istället med viss förtjusning. :)
Skriv svar