Squeak: GPS pet tracker

Squeak is a LoRaWAN GPS pet tracker with a very long battery life. It allows you to ask your pets to share their location

Public Chat
Similar projects worth following
Goals for Squeak:
- More than 2 months of battery life (GPS off, 15 minute uplinks)
- decent size for dogs & big-ish cats

There are many other GPS pet/asset trackers, some of them also using LoRa in one form or another. These all have their own advantages and drawbacks. Here are some of the ones I'm aware of:

LTE connectivity

LoRaWAN, very configurable

LoRaWAN, somewhat configurable

LoRa (LoRaWAN coming), very small, open source

LoRaWAN, just for Orange France, very small


The size is 38mm x 20mm x 12mm. This does not include battery and antenna


The tracker uses the RN2483 module from Microchip as an application processor, thanks to Microchip publishing the source code to the module. The general architecture of the tracker is the following:

The module is always powered by the top LDO but is kept in sleep most of the time. On request it can switch on the LDO to the GPS module and wait to get a fix that it can then uplink through LoRaWAN. The GPS module's RAM is always kept powered through its V_BACKUP line (not shown here) and there's also a battery voltage measurement circuit.



Uplink data

Measurements are periodically reported through uplink messages that use the lowest data rate possible (DR0 - SF12BW125 in EU), to maximise the chances of a packet being picked up by a gateway. Packet structure is, in bytes:

[0] - Header: 0x80 - GPS off; 0x81 - GPS on for N transmissions then will be switched off; 0x82 - GPS switched on every M transmissions. GPS mode, N and M are set via downlink config messages

[1-2] - 16 bit counter of number of packets sent. Can be used to check if packets have been missed (e.g. bad network coverage)

[3] - Battery charge state, roughly in %

[4] - Temperature in deg. C. Signed int, 1 degree resolution.

[5-8] - Time of last valid GPS fix. 27 packed bits: (7 bits year), (4 bits month), (5 bits day), (5 bits hour), (6 bits minute)

[9-12] - GPS Latitude

[13-16] - GPS Longitude

Downlink data

Downlinks configure the behaviour - how often uplinks are sent and which of these uplinks should contain GPS measurements. Packet structure:

[0] - Uplink interval, in multiples of 2 minutes

[2] - GPS mode. 0x00 - GPS off; 0x01 - GPS on for N transmissions then will be switched off; 0x02 - GPS switched on every M transmissions

[3] - N or M, depending on GPS mode

  • Adding a logo

    mihai.cuciuc3 days ago 0 comments

    I could not resist the temptation to add a logo to the case. Also made the case a bit taller to remove the humps for the GPS antenna and temperature sensor.

  • (Almost) No code data logging to Google Sheets

    mihai.cuciuc11/29/2022 at 05:13 0 comments

    Helium has this cool integration to Google Sheets through Google Forms. Once you register the tracker on the Helium console you can follow this guide on how to dump the data into Google Sheets.

    The only code you need to massage the data is in the custom decoder. For example if you just want to fill counter, battery and temperature values in your spreadsheet this can be as simple as filling which bytes go where in the template built by the Helium console from your Google Form.

    function Decoder(bytes, port) {
      // TODO: Transform bytes to decoded payload below
      var decodedPayload = {
        "battery": bytes[3],
        "counter": (bytes[1] << 8) + bytes[2],
        "temperature": bytes[4]
      // END TODO
      return Serialize(decodedPayload)

    You can add fancier fields, like latitude and longitude by decoding them similarly to how you do it for Datacake.

    Then you can plot your data in Google Sheets or download the Excel file and do it locally.

  • Adding a temperature sensor

    mihai.cuciuc11/28/2022 at 06:04 0 comments

    For testing the performance of the tracker I'd want to leave one in my car. But it contains a rechargable lithium battery and I'd feel much better if it could alert me if the temperature is outside the battery's recommended range.

    To make no changes on the PCB I repurposed a UART header I used for debugging to accomodate a TO-92 Microchip MCP9701. This was possible since the UART pins can also be used as ADC inputs on the PIC18F46K22 used in the RN2483.

    So I used one pin for reading the voltage from the MCP9701 and the other for turning it on or off. It's fairly low power (6uA or so) so it can safely be powered from a GPIO.

    Now every uplink contains temperature data that can trigger an alert.

  • Magnetic charging connector

    mihai.cuciuc11/25/2022 at 05:45 0 comments

    While I initially considered a USB connector for charging the battery, I eventually settled on this magnetic connector. There are also 3D files to make designing it into the case real easy. The tracker is getting heavy though, at 36 g (1.27 oz).

  • Datacake integration: Seeing Squeak on a map

    mihai.cuciuc11/20/2022 at 18:05 0 comments

    Datacake can be used to integrate and visualize IoT data. It's a paid service, but you get two devices for free. It readily integrates with The Things Network and you can easily have a web interface for the Squeak tracker.

    After registering Squeak in the The Things Network application, define a webhook for bidirectional communication with Datacake.

    Use a custom payload decoder for Datacake to make sense of what's being sent

    function Decoder(payload, port) {
        var decoded = {};
        decoded.counter =  (payload[1] << 8) | payload[2];
        decoded.battery = payload[3];
        decoded.temperature = payload[4];
        gpsYy = payload[5] >> 1;
        gpsMo = ((payload[5] & 0x01) << 3) | ((payload[6] & 0xE0) >> 5);
        gpsDd = payload[6] & 0x1F;
        gpsHh = (payload[7] & 0xF8) >> 3;
        gpsMi = ((payload[7] & 0x07) << 3) | ((payload[8] & 0xE0) >> 5);
        lat = ((payload[9] << 24) | (payload[10] << 16) | (payload[11] << 8) | payload[12]);
        lng = ((payload[13] << 24) | (payload[14] << 16) | (payload[15] << 8) | payload[16]);
        gpsTs = 0;
        gpsLat = -1000;
        gpsLon = -1000;
        if ((lat > -500) && (lng > -500))
            ts = new Date(2000 + gpsYy, gpsMo - 1, gpsDd, gpsHh, gpsMi, 0, 0);
            //console.log(ts.getTimezoneOffset());  // Maybe one needs to adjust for timezones here. For now it looks like Datacake runs on the UTC timezone which is great.
            gpsTs = ts.getTime() / 1000;
            gpsLatF = lat / 10000000.0;
            gpsLatDD = ~~gpsLatF;
            gpsLatMM = (gpsLatF - gpsLatDD) * 100.0/60.0;
            gpsLat = gpsLatDD + gpsLatMM;
            gpsLonF = lng / 10000000.0;
            gpsLonDD = ~~gpsLonF;
            gpsLonMM = (gpsLonF - gpsLonDD) * 100.0/60.0;
            gpsLon = gpsLonDD + gpsLonMM;
        decoded.timestamp = gpsTs;
        decoded.location = "(" + gpsLat + "," + gpsLon + ")";
        return decoded;

    Add fields for the values you're interested in from the decoded structure. Things like battery, location, etc. Also add a downlink configuration to be able to send a command to turn on the GPS.

    function Encoder(measurements, port) {
        return [0x02, 0x01, 0x03];

    This payload says it should try to send an uplink every 4 minutes, and the GPS should be on for the following 3 packets. A UI is fairly easy to build up once you have the decoder, fields, and encoder set up.

  • Case design with internal antenna

    mihai.cuciuc11/20/2022 at 08:19 0 comments

    As this is supposed to spend most of its time on a pet's collar, I tried a different case design that's flatter and longer. The goal is to get something smaller than the Tractive. So far no effort has been put into details like actually attaching it to a collar or a charging port.

    Size is: 76mm x 29mm x 17mm, 34g. That's 3" x 1.2" x 0.7", 1.2 oz

    Tractive is 71mm x 28mm x 17mm, 35g. That's 2.8" x 1.1" x 0.7", ~1.2 oz

  • Quick battery test with GPS on

    mihai.cuciuc11/19/2022 at 08:02 0 comments

    I ran a battery capacity test. System was configured to stay in sleep and wake up every 10 minutes. Then try to get a GPS fix and transmit an uplink. Then tested this in two scenarios, shown in the following plot.

    On the left, a GPS fix is easily obtained and power draw is small. For the middle section the GPS cannot get a fix and it keeps trying for 10 minutes. During this phase 62% of the battery capacity is lost in 8.7 hours.

    But something does not add up. With this power profile I expect 14h of run time. Further tests needed. Possible causes:

    • Lower than advertised battery capacity at 0.1C discharge rate
    • I'm measuring battery voltage wrong
    • I'm using a voltage-to-charge LUT that's not appropriate for the battery

  • Quick case design

    mihai.cuciuc11/18/2022 at 06:21 0 comments

    For easier field testing with the small battery I printed a very basic case. This also allows me to get the first real measurement for the total weight of the device.

    30 grams is 1.06 ounces.

    Weights of other LoRaWAN GPS trackers

    RAK Wireless TrackIt: 22 grams

    ioTracker 3: 35 grams

    Dragino TrackerD: 58 grams

  • Battery and antenna

    mihai.cuciuc11/17/2022 at 05:06 0 comments

    The antennas and batteries arrived. Weight of complete electronics: 20 grams (0.7 ounces).

  • Current consumption

    mihai.cuciuc11/16/2022 at 06:46 0 comments

    Adding up the maximum currents for the components for each state I got:

    • Sleep: ~20uA
    • GPS on: 34mA
    • Tx: 45mA
    • Rx: 15mA

    On measurement things improve a little:

    • Sleep: ~9uA
    • GPS on: 35mA
    • Tx: 33mA
    • Rx: 14mA

    Using a 400mAh battery, keeping the GPS off and sending one uplink every 15 minutes should give ~130 days of battery life on 80% of the battery charge.

View all 11 project logs

Enjoy this project?



Benjamin König wrote 11/20/2022 at 11:24 point

Looks good. Seems you a pretty far already. I hope you can sort out these power drain issues. That RN2483 is a bit bulky though. Have you have also looked at the AcSiP S76G?

  Are you sure? yes | no

mihai.cuciuc wrote 11/20/2022 at 14:53 point

Thanks, I'm having a blast working on it. Wow, the AcSiP S76G looks really good but it seems it's discontinued. I also don't feel confident enough to integrate any of the RF part on the PCB. Moving forward I'm looking at the smaller WLR089U0 and maybe a Quectel L96 GPS.

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates