-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add Cellular Tracking Technologies Life/Power/HybridTag Support #3335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Add Cellular Tracking Technologies Life/Power/HybridTag Support #3335
Conversation
|
There are some comments in [ Additionally, since this is such a niche device - I'm open to leaving it disabled by default - though I guess, in theory, decodes in the wild could happen if a tagged bird happens to fly by. 😉 |
|
My take is that as long as the decoder will not generate false decodes, it's ok to leave it enabled. So far we aren't really having CPU time problems, and getting a decode like that would be cool. I see in the comments about 5 bits encoded into a byte with a table. I am wondering if this is supposed to be ECC, or if it's a way to reject bad decodes. |
|
If I had to guess - the 5 bits to a byte mapping is apart of the design for reliability reasons. I wouldn't call it ECC because I can't see that being used practically for error correction, just a way to reject bad decodes. Tag IDs are 20-bits long, but get converted with that table to 32-bits on the air. Again guessing, it was probably a combination of trying to maintain Hamming distance between valid symbols and DC balance. |
|
Sounds sensible. The rtl_433 decoder should reject all frames that are considered invalid, as part of avoiding bad decodes. The rarer the actual use, probably the rarer bad decodes need to be for it to make sense to be default on. I suspect opinions differ; I lean to enable unless false decodes personally. |
|
Some notes: |
|
That 5-to-8 coding with e.g. 0x00, 0x80, and 0xff does not look like a proper constant-weight code and won't much help clock recovery (it doesn't limit runs effectively). Somewhat strange. E.g. The Radiohead protocol has a proper constant-weight code: https://github.com/merbanan/rtl_433/blob/master/src/devices/radiohead_ask.c#L28 |
Tags actually have 32-bit identifiers - not 20
|
Your point made me dig a bit more - I don't actually think the mapping is required. I was wrong - tags actually have 32-bit identifiers. This is consistent even from their site (https://celltracktech.com/collections/digital-radio-products/products/lifetag-with-flex-tab)
20-bit tags identifiers would get nowhere near that - 2^32 lines up nicely. There's a typo elsewhere on their website (https://celltracktech.com/pages/hybridtag) where they say 4 million instead of billion and so I very incorrectly off-the-cuff told myself 2^20 would be in that ballpark (not even, it's off by a factor of 4). Motus itself even represents it in that way as 32-bits (Manufacturer ID) - if it was really 20-bits, it wouldn't make sense for them to use the "on-the-air" value.
I fell for a red-herring as the reverse-engineered tag implementation I was referencing (CTTTestTag/src/main.cpp) had the mapping logic as residual code that got #ifdef'ed out. I figured the author had manually done the mapping of 20-bits -> 32-bits to save a processing step and just #define'd that value instead. Turns out, that was the actual ID all along. Sorry for the confusion - I'm not quite sure how I missed all that before. |
|
After some more chatting with folks and experimenting, I have some clarity, however confusing it may be. Tag IDs are 32-bits long - and that's how they're generally represented. However, from previous experiments/research (thanks @tve), behind the scenes, only a 20-bit subset of that 32-bit space are considered "valid" tags and get decoded by the official hardware used for Motus. It's... a little strange, but as @gdt pointed out, it's probably an extra error-detection step. Even stranger considering CTT advertises “Over 4 billion unique digital IDs” - weird to advertise a 32-bit ID space and then only use a subset of that. 🤷♂️ With that said, I'll touch up this PR and get everything squared away for another pass. |
|
But you wouldn't want to collect random ID's anyway, right? You'd have a catalog of used tags and then compare to that? |
|
I am shocked, shocked that marketing people would say something that is untrue/misleading. If the way the protocol really works is that only a subset are valid, that's a kind of checksum and it would be great if rtl_433 rejected ids that aren't valid. As for whether the Motus-built receivers or rtl_433 receive and log all tag values, or only some configured set, idk on the Motus, but i'd think they'd log all valid decodes, and researchers might share, because any decode is interesting. The rtl_433 way should be to decode what's there, and let the user sort out what's wanted. It's not like we decline to decode thermometers because the id isn't in a config file, so I don't understand where you're going with the random ID comment. |
|
With "collect random ID" I wanted to say that you wouldn't assign value to just any ID, in some encoded subset or not. You'd need to know that it's a tag you (or someone you forward it to) know something about. In other words, ID + known usage = usable value, and not ID + valid coding = usable value. To me it seems that way at least. Maybe other vendors/users use other parts of the possible ID space? |
|
I am not following "assign value". If I am randomly listening, and some tag shows up, I find that interesting, and I'd just as soon it is logged, and then if in the mood I might see if it recurs etc. This is sort of like watching neighbor thermometers. As for the pseudo-checksum 20/32 scheme, so far we have one known kind of transmitter and that's what it does, so it makes sense to align the code. Evidence of similar devices with compatible coding and a different subset or no subset would warrant changes. I therefore come down on
and I am not understanding what you are wanting the code to do that is different. |
|
All I wanted to convey is: I don't see the intersting'ness of an ID increasing by limiting it to a subset. An ID does not get better or more interesting with that filter. An ID get's interesting by combining it with knowledge about the tag. We did have some subset filters in decoders before and that later resulted in users asking why their devices are not received. |
|
I understand now and I see your point. The real question is if there are devices that use this scheme and don't do the subset. But a motus_20bit_valid boolean seems like a good way to begin to gather info. |
|
Tags can/are used outside of Motus, but it feels strange to have such a large ID space "wasted" for outside use. I would presume any use of these tags outside of Motus would be a minority, not the majority - but I'm speculating. CTT makes its own hardware for tag tracking as well - so maybe the rest of the tag space is aimed towards that - tags that will never be on the Motus network. However, I'm not 100% sure - all I have to go off of are my observations with Motus. CTT used to sell a "Motus" adapter - https://celltracktech.com/pages/motus-adapter - and from what I've heard/tested (you can make one yourself now) - the filtering is done at the dongle level - it won't pass a tag ID along if it's not in that subset. The separation makes sense - Motus stations shouldn't decode non-Motus tags, but it feels strange to have that enforced at the station-level and not somewhere further along the chain. Now you're stuck with a "rigid" definition built into the firmware of each station instead of being able to tweak that more easily in the future somewhere in the data processing pipeline (especially considering tags have to be pre-registered with Motus - just check against that) - but I digress, I'm not here to police design decisions. But I like to what you're both leaning towards - consider all tags as valid, and then add a Motus "bit" if we know it's valid for Motus - that's handy because it can tip people off to go to the website and enter that ID if they're interested in learning more. But we don't strictly limit ourselves to just Motus tags, which is nice. However, that means, all we have to validiate against false decodes is the syncword, CRC, and packet length - I haven't run into trouble with any other decoders yet - if we're ok with that being the only three things defining the protocol, then I'll make those changes. I'm curious if there's been trouble with simple decoders like this when another device comes along that just happens to use the same syncword, packet length, etc... |
|
My take is we're ok until people are annoyed by false decodes and we can revisit it. Not a big deal. |
|
Sync, length and CRC are good enough. Usually we'd need to exclude an ID of all 0's as that CRC will be 0 and bitbuffers of all 0's might happen. But then there won't be a good sync I guess. |
|
I went ahead and also moved away from the "Motus" naming scheme for the file + device - I figured that was a misnomer after all the discussion. Let me know if there's anything else I should tweak/change. |
I can't type coherent sentences
|
Timings might need a revision. It's 40 µs PCM. You don't need a .tolerance with PCM, 25% is default. 200 µs .gap_limit will only allow 5 consecutive 0's and then 50 ms reset is not effective but would allow 1250 0 bits. |
|
Adjusted - decodes feel much smoother now (placebo maybe?). Thank you! Also, it's one packet per transmission - |
8d2ffe8 to
a796732
Compare

Hello,
This decoder [
ctt.c] adds support for decoding Cellular Tracking Technologies Life/Power/HybridTag(s) which are lightweight transmitters used for wildlife tracking and research - most commonly used with the Motus Wildlife Tracking System.The CTT tags transmit on 434.00 MHz using FSK modulation at 25 kbps. The packet format consists of:
0xD3 0x91marking the packet startI have to give credit to @tve for the CTT tag implementation details via their work on RadioJay (https://radiojay.org/) and Motus Test Tags (https://github.com/tve/motus-test-tags).
I'm planning on adding test data to https://github.com/merbanan/rtl_433_tests once I get a good variety of tags/IDs to test + some good recordings.