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
ProMini | ADXL345 | GPS-Modul | RFM95W | Sonstiges |
2 | INT-1 | |||
4 | DIO0 | |||
5 | DIO1 | |||
8 | TX | |||
9 | RX | |||
10 | NSS | |||
11 | MOSI | |||
12 | MISO | |||
13 | SCK | |||
A0 | Spannungsteiler | |||
A1-A3 | VCC | |||
A4 | SDA | |||
A5 | SCL | |||
VCC | VIN | VCC | ||
GND | GND | GND | GND |
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.
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:
[code] 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. [/code]
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.
- 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.
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
Hallo Reinhard,
zur Stromversorgung habe ich noch einen Spannungswandler vorgeschaltet. Pololu 3.3V Step-Up/Step-Down Voltage Regulator S7V8F3
Genau, ich schalte es hart aus. Wie lange es dauert, hängt davon ab ob die Bahndaten noch im Speicher sind. Das Modul hat eine kleine Backup Batterie, womit der Speicher erhalten bleibt. Ich habe eben getestet und hatte und war selbst überrascht. Das GPS-Modul hatte einen Fix nach ca. 15 Sekunden. Ansonsten dauert es länger, aber auch unter einer Minute. Verwendetes GPS-Modul
Grüße,
Björn
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.
Hallo.
Beim Kompilieren erhalte ich die Meldung, dass der Sketch zu gross sei.
Habe das korrekte Board ausgewählt.
Wie kann das sein?
Das könnte an der verwendeten LMIC Bibliothek liegen. Verwende mal die von Matthijs Kooijman. Diese ist kompakter als das Original.
Yep!
Jetzt geht’s weiter… 🙂
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
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.
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
Hi,
ich hätte auch gedacht es macht keinen Unterschied. Wieder was gelernt.
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
Hallo Björn,
das Senden der Payload via FPort ist genau das, was ich heute gesucht habe. Nun kann ich hoffentlich meine verschiedenen LoRaWAN-Test-Devices mit unterschiedlichen Payloads unter einer TTN-Applikation laufen lassen. Ich baue gerade einen CargoBikoMeter-Prototypen für die Lastenräder unserer fLotte (flotte-berlin.de), der auf der Basis der Nabendynamofrequenz die gefahrenen Kilometer sammelt und via TTN-HTTP-Integration an einen eigenen Testserver zur Auswertung (es werden nur die Gesamtkilometer erfasst, um den nächsten Wartungstermin für ein Rad zu bestimmen) mittels ELK-Stack sendet.
Wie hast Du das Gerät diebstahlsicher und unauffällig am Fahrrad befestigst?
Viele Grüße
Roland
Hallo Roland,
aus Mangel an Zeit und dem nötigen Werkzeug, habe ich bisher nichts an das Rad gebaut.
Meine Idee war es alles unter dem Sattel zu befestigen, habe das Thema aber nicht aktiv angegangen.
Eventuell gibt es auch diebstahlsichere Boxen zu kaufen.
Grüße,
Björn
Hallo Björn,
ich möchte für ein ähnliches Projekt deinen Tracker gerne nachbauen. Auf dem Foto hast du den Pro Mini, Antenne und den RFM95 auf einem gemeinsamen Trägerboard verbaut. Gibt es ein solches Board irgendwo zu kaufen? Falls ja, kannst du mir eine Quelle nennen?
Vielen Dank und liebe Grüße
Uwe
Hallo Uwe,
es gibt mehrere Platinen, welche man kaufen kann. Hier mal zwei:
1. Variante von Doug Larue
Thickness auf 1,6 mm setzen!!
2. Nucleon Base Node
Grüße,
Björn
Super, vielen Dank!
Hallo
Vielen Dank für das schöne Projekt.
Ich würde gerne an Stelle des ADXL345 ein LSM303 nehmen.
Ich weiß nur nicht wie das Teil einbinde.
Eine Andere Frage ?
Wie groß ist der Widerstandswert vom Spannungsteiler für den Akku ?
Grüße,
André
Hi,
zum LSM303 kann ich nichts sagen.
Bzgl des Widerstandes:
Grüße