Alarmanlage – Wo ist mein geklautes Rad?

Alarmanlage – Wo ist mein geklautes Rad?

Permanent werden Fahrräder geklaut. Ich dachte mir es wäre eine gute Idee, einen Beschleunigungssensor mit einem GPS zu koppeln und an das TTN anzubinden. Sollte also jemand mein Rad bewegen, erfahre ich es und weiß auch wohin sich mein Rad bewegt. Über Node-RED werte ich die Payload aus und lasse mich mittels Pushover benachrichtigen. Das ist nur eine der vielen Möglichkeiten. Denkbar ist auch eine Anwendung im Auto oder anderen Objekten.

Das Prinzip

Ein Beschleunigungssensor vom Typ ADXL345 ist für die Bewegungserkennung zuständig. Sobald hier der eingestellt Schwellwert erreicht ist, wertet der Sensor eine Bewegung als Aktivität. Darauf hin, wird das GPS-Modul mit Strom versorgt und der Node beginnt damit seine Positionsdaten an das TTN zu senden. Im Ruhezustand sendet der Node ca. alle 15 Minuten die Akku-Spannung. Damit weiß ich der Node funktioniert noch, bzw. kenne den Ladestand des Akkus.

Per beliebigem Downlink kann der Node wieder in den Ruhemodus versetzt werden. So muss ich bei einem Fehlalarm nicht zum Rad laufen, sondern kann über die Konsole oder Node-RED einfach den Node wieder schlafen legen.

Ich habe insgesamt zwei Ansätze getestet. Bei der ersten Variante frage ich nach jedem Durchlauf des Ruhezustandes den Status des Beschleunigungssensors ab. Bei der zweite Variante nutze ich einen Interrupt. Ich würde aktuell zur ersten Variante tendieren, da ich doch recht viele Probleme mit dem Interrupt hatte und kein wirklicher Vorteil vorhanden ist. Einziger Vorteil ist das schnellere Einschalten des GPS-Sensors.

Der Aufbau

Ich verwende einen ArduinoProMini, einen Adafruit ADXL345 und ein GPS Modul mit Ublox Neo-7M Chip. Über einen Spannungsteiler erfasse ich die Spannung meiner LiIon-Zelle. Solltet ihr einen anderen Chip verwenden, ist eventuell eine Anpassung des Sketches notwendig.

Der Spannungsteiler besteht aus zwei gleichen Widerständen (100 KOhm), somit kann die gemessene Spannung mit dem Faktor zwei multipliziert werden, um die Zellenspannung zu erhalten.

Nicht sichtbar ist ein Spannungsregler, welcher aus den bis zu 4,2Volt der LiIon-Zelle, die notwendigen 3,3 Volt erstellt. Ihr den Aufbau also nicht direkt aus der Zelle mit Strom versorgen.

Hier die Pinbelegung

ProMiniADXL345GPS-ModulRFM95WSonstiges
2INT-1
4DIO0
5DIO1
8TX
9RX
10NSS
11MOSI
12MISO
13SCK
A0Spannungsteiler
A1-A3VCC
A4SDA
A5SCL
VCCVINVCC
GNDGNDGNDGND

Das Pin-Mapping müsst ihr evtl. euren Gegebenheiten anpassen.

Der Sketch

Ich habe beide Varianten auf GitHub abgelegt, ihr könnt sie gerne frei verwenden und anpassen.

  1. Ohne Interrupt
  2. Mit Interrupt

Auf GitHub liegt ebenfalls ein Beispiel Flür Node-RED. Die GPS Koordinaten werden als Geo Hashes gespeichert. Dieses ist aber nur ein Beispiel.

Was habe ich gelernt

Bei dem Aufbau und der Programmierung bin ich über drei Dinge gestolpert. Dem Einen mag das völlig klar sein, aber ich zähle mich immer noch zu den Anfänger, was die Programmierung mit der Arduino IDE angeht.

  • SoftwareSerial, Rocket Scream Low-Power und der Pin Change Interrupt

Den zweiten benötigten Seriellen Port, erzeuge ich dank SoftwareSerial. Das funktioniert und ist kein Problem. Anschließend funktionierte jedoch mein Stromsparmodus nicht mehr. Durch Ausprobieren habe ich immerhin festgestellt, das mein Serieller Port schuld sein muss. Nach etwas suche habe ich im Internet auch die Antwort gefunden. SoftwareSerial nutzt Pin Change Interrupts, welche den Node wieder Sofort aus seinem Tiefschlaf aufwecken. Die Lösung besteht nun darin den den PCI auszulesen und anschließen zu deaktivieren. Nach dem erfolgreichen Schlaf, wird der vorherige Zustand wieder hergestellt. Folgernder Code zeigt die Vorgehensweise:


byte savedPCICR = PCICR; //Read the status of all pin change interrupts
PCICR = 0; // Disable all pin change interrupts
for (int i=0; i<sleepcycles; i++) {
// Enter power down state for 8 s with ADC and BOD module disabled
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

// LMIC uses micros() to keep track of the duty cycle, so
// hack timer0_overflow for a rude adjustment:
cli();
timer0_overflow_count+= 8 * 64 * clockCyclesPerMicrosecond();
sei();
}
PCICR = savedPCICR; // Restore any pin change interrupts that were disabled.

Interessant sind dabei die folgenden drei Zeilen:

byte savedPCICR = PCICR //Save status of pin change interrupts;
PCICR = 0; // Disable all pin change interrupts
... //your sleep routine
PCICR = savedPCICR; // Restore any pin change interrupts that were disabled.

  • Voltage Drop

In einem meiner vorhergehenden Beiträge, hatte ich beschrieben, wie man mit den Ausgängen des Pro Minis, seine Sensoren mit Strom versorgen kann. Leider war das nur die halbe Wahrheit. Der ProMini kann zwar bis zu 40mA an seinen Ausgängen liefern, jedoch ist die Ausgangsspannung abhängig vom Stromverbrauch der Quelle. In der nachfolgenden Grafik sieht man das Problem. Anstelle von 3 Volt, liefert ein Ausgang mit 20 mA belastet, nur noch 2,2V.

Mein GPS-Sensor verbraucht angeblich 35mA. Durch diese Belastung sinkt die Spannung am Ausgang auf weit unter 2 Volt und das GPS-Modul funktioniert nicht. Meine Lösung bestand  nun darin mehrere Ausgänge zusamen zuschalten. Ich schalte nun drei PINs am ProMini gleichzeitig auf High und lege sie gemeinsam auf VCC des GPS-Moduls. Damit verteilt sich die Belastung gleichmäßig auf alle drei Ausgänge und die Spannung reicht zum Betrieb des Moduls aus.

Atmel ATmega328/P [DATASHEET] S. 390
  • Interrupts

Um meinem Node aufzuwecken, experimentierte ich auch mit Interrupts. Dabei ist mir jedoch regelmäßig die Software abgestürzt. Hilfreich war mir dabei die Zusammenfassung zu Thema Interrupts von Nick Gammon. Es gibt ein paar Dinge an die man sich halten sollte, wenn man eine ISR schreibt:

When writing an Interrupt Service Routine (ISR):

  • Keep it short
  • Don’t use delay ()
  • Don’t do serial prints
  • Make variables shared with the main code volatile
  • Variables shared with main code may need to be protected by „critical sections“
  • Don’t try to turn interrupts off or on

Bei mir waren es die serial prints. Damit ich den Ablauf nachverfolgen konnte, habe ich mir immer Nachrichten in die serielle Konsole schreiben lassen. Dieses hat dann aber zum Programmcrash geführt.

FPorts im LoRaWAN / TTN

Daneben habe ich auch LoRaWAN spezifisches Wissen mitnehmen können. Ich wollte zwei verschiedene Arten von Payload verschicken. Das eine ist die Batteriespannung und daneben noch die GPS-Daten. LoRaWAN kennt glücklicherweise FPorts und so kann für eine Payload auch ein bestimmter Port gewählt werden. Dieser kann später auch im Payload-Decoder ausgewertet werden.

In diesem Beispiel wird der FPort 1 und 2 verwendet:


LMIC_setTxData2(2, (uint8_t*) coords, sizeof(coords), 0);

Ein Payload-Decoder kann dabei so aussehen:

function Decoder(bytes, port)
{
var decoded = {};

if (port === 1) {
decoded.batt = (bytes[0] +250) / 100.0;
if (decoded.batt === 0)
delete decoded.batt;
}

if (port === 2) {
decoded.lat = ((bytes[0]<<16)>>>0) + ((bytes[1]<<8)>>>0) + bytes[2];
decoded.lat = (decoded.lat / 16777215.0 * 180) – 90;
decoded.lon = ((bytes[3]<<16)>>>0) + ((bytes[4]<<8)>>>0) + bytes[5];
decoded.lon = (decoded.lon / 16777215.0 * 360) – 180;
}
return decoded;
}

Variationen

Ihr könnt natürlich den Sketch entsprechend eurer Vorstellungen anpassen und umbauen. Interessant ist die Überlegung wie oft der Node seinen Standort bei Aktivität senden soll und mit welchem Spreading Factor. Wichtig ist auch die Anpassung des Activity Thresholds, damit ihr keine Fehlalarme generiert.

Was ebenfalls auf dem Programm steht, ist die gesamte Konstruktion an das Rad zu bekommen. Ich hatte an die Sattelstütze, bzw. den Sattel selbst gedacht. Das hat aber bis zum nächsten Jahr zeit, da ich aktuell kaum fahre. Der gesamte Aufbau kann jedenfalls noch verkleinert werden. Als Proof Of Concept reicht es erst mal.

  Gefällt mir

15 Gedanken zu “Alarmanlage – Wo ist mein geklautes Rad?”

  1. Hi Bjoern,
    wieder mal ein Super User-Case, perfekt umgesetzt.
    Wieder mal was gelernt: das mit dem Port kannte ich auch noch nicht.
    Frage zur Spannungsversorgung: gehst du direkt mit der LiPo Spannung aufs Board?
    Du schaltest das GPS Modul immer hart an/aus , also kein sleep-modus. Wie lange dauert es nach dem Einschalten bis der GPS.fix da ist?
    Gruß
    Reinhard

  2. Hallo Björn
    Muss das GPS-Modul einen bestimmten Modus haben damit es in den Sleep Modus versetzt werden kann?
    Oder kann ich hier jedes GPS-Modul verwenden?
    Danke

    • Hi,

      Ich schalte das Modul hart aus, da ich die Stromversorgung kappe, ich nutze also keinen Sleep Mode für das GPS. Dieses kommt evtl später noch.
      Daher kannst du jedes Modul verwenden, es sollte aber ein Batterie Backup haben.

  3. Hallo Björn.
    Sorry….
    Ich bekomme bei den PIN’s A1-A3 keinerlei Spannung raus!
    Ob ich den Mini mit dem USB-Adapter betreibe noch mit einer ext Speisung.

    Hast Du mir einen Tipp?
    Danke
    Patrick

    • Hi Patrick,

      ich würde erst mal alles aus dem Sketch werfen was wir nicht brauchen und die PINs sofort auf HIGH setzen. Dann weißt du ob die PINs generell funktionieren.

      Grüße,
      Björn

  4. Hallo Björn
    Habe ich nun alles gemacht.
    Ausser die 3 PIN’s auf high setzen, ist der Sketch leer.
    Auch einen weiteren Pro Mini versucht…kein Erfolg.
    Mehr als 0.1V bringe ich nicht aus den PIN’s.

    any ideas?
    Gruss
    Patrick

    • Moin Patrick,

      es sollte bei dir so aussehen:

      void setup(){

      Serial.begin(9600); // Start the serial terminal
      Serial.println("Starting");

      pinMode(A0, OUTPUT);
      pinMode(A1, OUTPUT);
      pinMode(A2, OUTPUT);

      digitalWrite(A0, HIGH);
      digitalWrite(A1, HIGH);
      digitalWrite(A2, HIGH);

      }

      void loop(){

      }

      Ansonsten haben deine ProMinis eine Macke, was ich aber kaum glauben kann.

  5. Hallo Björn.
    Danke es läuft, aber…
    wenn ich mir Dein Sketch ansehe:

    int gpsvcc3 = 15; //GPS Sensor OUTPUT
    int gpsvcc1 = 16; //GPS Sensor OUTPUT
    int gpsvcc2 = 17; //GPS Sensor OUTPUT

    pinMode(gpsvcc1, OUTPUT);
    pinMode(gpsvcc2, OUTPUT);
    pinMode(gpsvcc3, OUTPUT);

    gem. Pinout sind ja die 15-17 auch A1-A3.
    Daher bin ich auf diesen PIN’s geblieben.

    Gruss
    Patrick

  6. Servus Björn,

    coole Dinge machst du mit LoRaWAN :-). Habe beim Spannungsteiler Verständnisschwierigkeiten. Wie schleifst du den am LiPo ein? Im Fritzing Plan ist er „freischwebend“ 🙂

    Danke und Gruß

    Jakob

    • Hi Jakob,

      der Spannungsteiler kommt direkt zwischen + und – des Akkus. Wenn du zwei gleiche Widerstände verwendest (z.B. 100K Ohm), dann fällt genau die Hälfte über jeden ab und die kannst du gemessene Spannung mit zwei multiplizieren.
      Was ebenfalls fehlt, ist der Spannungsregler, welcher mir 3,3 Volt liefert. Ich zapfe die Zelle also nicht direkt an.

      Grüße,
      Björn

Schreibe einen Kommentar