Skip to content
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

IR Transponder lap-timing support #2642

Open
wants to merge 21 commits into
base: master
Choose a base branch
from

Conversation

hydra
Copy link
Contributor

@hydra hydra commented Apr 6, 2024

IR transponder support

This is a PR that adds support for IR based lap timing systems.

What is an IR transponder system?

An IR transponder system is made up of a multiple transmitters, usually one per model, and one or more receivers placed around the track, for example at the start/finish line. The transmitters continually send out a code, and as they pass the receiver the receiver records the time in a timing system in order to count laps and time how long each lap takes.

IR transponder systems work for RC cars, drones, and aircraft. For models with video transmitters other systems that record the strength of the video signal can be used, but where video transmitters are not used, for example indoor RC car racing, IR transponders are a great choice.

IR transponder code

Here's what a transponder code looks like on a scope.

ExpressLRS IR Transponder

https://www.youtube.com/watch?v=9q-G_QQi4rM

Hardware

The SPRacingRXN1 is the first ELRS RX to have built-in support for this - ExpressLRS/targets#57

Schematic:

image

(Note, on the RXN1 ESP_GPIO21 is connected to ESP_GPIO21_EX via a mezzanine connector, you can treat them as connected to each other for the discussion of this here.

The MOSFET is a PMXB40UNE, it's very small and has been used on many SPRacing products. The Q1 MOSFET is used as a high-side switch, the anode (positive/long-leg) is connected to 5V, and the cathode (negative/short-leg/flat-spot) is connected to the MOSFET's DRAIN via a 10ohm resistor.

IMPORTANT: Make sure your LED, resistor and mosfet can handle the current.

There are various IR leds than can be used, the selection depends on what IR protocol system and receivers you are using.

e.g. Fast FPV drones in sunlight work best with narrow angle (Angle of half intensity: ± 10°) lens and lots of receivers. Indoor RC cars can get away with wider angle lenses and fewer receivers.

Transponder system support

Initially the following systems are supported.

System State Url
iLap Verified on official iLap receiver hardware https://www.rclapcounter.com/
Robitronic Pending verification https://shop.robitronic.com/de/rc-elektronik/zeitmessung/lapcounter-zubehoer/

Others systems for which support could be added (not in this PR) include :

Note: Open source solutions exist for the Robitronic hardware/software which appears to be discontinued.

TODO

  • Support for Robitronic
  • Support for 2nd protocol.
  • Support for iLap.
  • Verification against iLap receiver.
  • Verification against Robitronic receiver.
  • Ensure DShot and IR Transponder don't interfere with each other (they both use the RMT)
  • Storing transponder code in config (currently iLap is outputting a signal of the correct length with correct timings and Robitronic generates an ID based on the binding code).
  • Config migration (default values for codes, etc)
  • WebUI support for changing protocol.
  • WebUI support for entering transponder code and basic validation.
  • LUA support for changing protocol? (EDIT: deferred, separate PR can follow)
  • LUA support for entering transponder code and basic validation?
  • Code-cleanup (formatting, style, etc)

Design decisions

  • Since not all possible iLap codes work with receivers, vendors are to supply the purchaser of suitable hardware with a suitable LED and a known-good transponder code. e.g. The same codes supplied by SPRacing as used in Betaflight work for ELRS too!

Authors

This is a joint effort:

@hydra (Dominic Clifton) - Multiple protocols support, refactoring, iLap support, hardware design, bug fixing, technical documentation.
@mha1 - Initial support for Robitronic

@hydra
Copy link
Contributor Author

hydra commented Apr 6, 2024

Some scope screenshots:

Signal comparison to an iLap transponder - note timing variations from guessed specification probably exist on both the iLap side an the ELRS side, see comments in the code.
image

Close-up of reference iLap carrier signal:

image

Robitronic signal:

image

@pkendall64
Copy link
Collaborator

Should we mark this as draft as theres still a bit to do?

@hydra
Copy link
Contributor Author

hydra commented Apr 6, 2024

Should we mark this as draft as theres still a bit to do?

yes please.

If you have any feedback regarding that code and changes that would be appreciated. The transponder driver code is functional, so if you have some time to review that's a good place to start and I can go ahead and work on anything you think needs updating.

@pkendall64 pkendall64 marked this pull request as draft April 6, 2024 20:05
@pkendall64
Copy link
Collaborator

Why not make the IR transponder more like I2C pins. i.e. selectable on a PWM pin or a hard-wired pin.
That way users can add this to PWM recievers.

@mha1
Copy link
Contributor

mha1 commented Apr 9, 2024

@pkendall64 No problem to to that. The IR diode already has it's config item for the pin to use and it'll work on PWM pins just fine (I used a ER6 as RXN1 replacement to implement the IR code RMT). It just needs the UI. And I've done similar in my second serial PR #2605.

To spare me all the merge conflicts I ask you to please review #2605 first. I'd like to have those UI extension in before adding the ones necessary here to avoid my own merge nightmare. And, if approved I know it'll be ok to use the same approach.

@ot0tot
Copy link
Contributor

ot0tot commented Apr 9, 2024

Will this be compatible with DShot output, which also uses RMT?

@mha1
Copy link
Contributor

mha1 commented Apr 9, 2024

Yes, it will be compatible with DShot. RMT has multiple channels. We are working on a common RMT resource handler.

@pkendall64 pkendall64 added the enhancement 🪄 New feature or request label Apr 10, 2024
@hydra
Copy link
Contributor Author

hydra commented Apr 11, 2024

Why not make the IR transponder more like I2C pins. i.e. selectable on a PWM pin or a hard-wired pin. That way users can add this to PWM recievers.

I would not advise this. The IR led circuit should not accidentally driven by the user incorrectly setting PWM output on the pin hooked up to the IR receiver FET. It could result in burnout of the resistor, burnout of the IR LED, increased heat generation of the PCB and could lead to additional support requests.

There's also the additional logic of making sure that only a single pin is selected in the UI, not sure if there's already code to handle this, but it's still extra code.

I feel it's better that user's don't accidentally mess with the IR output and that the pin configuration is set once as part of the hardware setup.

@pkendall64
Copy link
Collaborator

pkendall64 commented Apr 11, 2024

If only an ir_transponder pin is defined then the hardware is expected to have an IR transponder. This is the option a manufacturer would use when they have specific hardware support.

If the pin is only in the PWM list then a user can select any pin to be an IR transponder pin, but it's up to the user to get it correct and have the correct hardware attached. This is for DIYers.

If the pin is defined as ir_transponder and in the PWM list then it means that only that pin can be used as an IR transponder. Again the user must get it correct and the manufacturer is just providing a plug for it but it could be for other things as well.

@hydra
Copy link
Contributor Author

hydra commented Apr 11, 2024

Code entry for iLap transponder codes is working, here's a screenshot of a code being received by an iLap recevier.

image

@hydra
Copy link
Contributor Author

hydra commented Apr 11, 2024

If only an ir_transponder pin is defined then the hardware is expected to have an IR transponder. This is the option a manufacturer would use when they have specific hardware support.

If the pin is only in the PWM list then a user can select any pin to be an IR transponder pin, but it's up to the user to get it correct and have the correct hardware attached. This is for DIYers.

If the pin is defined as ir_transponder and in the PWM list then it means that only that pin can be used as an IR transponder. Again the user must get it correct and the manufacturer is just providing a plug for it but it could be for other things as well.

yeah, I suppose that would work, can we add support for selectable pin in a second PR in order to keep this focused as there are per-requisits from another PR (#2605). @mha1 can look at doing the user-selectable pin after this and #2605 are merged.

I will design a small little IR LED+FET board with a servo plug and get that shipping too. I have all the parts in stock for that.

Speaking of focused PR, the transponder config by LUA can be done as a separate PR.

@hydra
Copy link
Contributor Author

hydra commented Apr 11, 2024

I've added the RMT allocator, example log:

Initializing DShot: gpio: 25, ch: 0, rmtChannel: 0
Initializing DShot: gpio: 26, ch: 1, rmtChannel: 1
Initializing digital output: ch: 2, pin: 10
Initializing digital output: ch: 3, pin: 9
...
TransponderRMT::init, channel: 2, desired_resolution_hz: 460800, actual_resolution_hz: 462427, divider: 173, carrier_hz: 460800, carrier_duty: 50

@hydra
Copy link
Contributor Author

hydra commented Apr 11, 2024

@pkendall64 This is ready for review now. I think you can remove the Draft tag.

ILap is fully tested, the Robitronic is not verified against a Robitronic receiver, but the scope signal driving the FET has been compared to other scope captures from Robitronic reverse engineering projects so we're not expecting any changes, if there are it'll just be in the RobitronicTransponder.cpp file and likely only constrained to the encode_bit function. Hopefully @mha1 will be able to test it in Sunday at his track if the RXN1 I sent gets to him in time.

Of note is that I applied the RMT allocator to the TX autodetect & PPM code, which was complicated slightly by the fact that the S3's RMT peripheral channel capabilities are different from other ESP32 chips.

IMHO the RMT allocator cleans things up quite nicely, fewer #define's, const's and local variables now.

Please also highlight any code style changes and I'll get right on them.

@pkendall64 pkendall64 marked this pull request as ready for review April 11, 2024 20:01
Copy link
Collaborator

@pkendall64 pkendall64 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass, quick review.
I'll go through it more thoroughly.

src/lib/RMTAllocator/rmtallocator.h Outdated Show resolved Hide resolved
src/lib/IRTransponder/TransponderRMT.h Outdated Show resolved Hide resolved
src/lib/Handset/handset.h Outdated Show resolved Hide resolved
src/lib/Handset/PPMHandset.cpp Outdated Show resolved Hide resolved
src/lib/Handset/AutoDetect.cpp Outdated Show resolved Hide resolved
src/lib/IRTransponder/Transponder.h Outdated Show resolved Hide resolved
src/lib/IRTransponder/devIRTransponder.cpp Outdated Show resolved Hide resolved
src/lib/IRTransponder/devIRTransponder.cpp Outdated Show resolved Hide resolved
src/lib/IRTransponder/devIRTransponder.cpp Outdated Show resolved Hide resolved
src/lib/IRTransponder/devIRTransponder.cpp Outdated Show resolved Hide resolved
@hydra
Copy link
Contributor Author

hydra commented Apr 13, 2024

First pass, quick review. I'll go through it more thoroughly.

Great, I'll get right on these, also I'd forgotten about the one TODO where I need to move the detail of the delay pause to inside each transponder implementation, so I'll address that this morning too.

@hydra
Copy link
Contributor Author

hydra commented Apr 13, 2024

ILap minimum jitter:
RigolDS80

ILap maximum jitter:
RigolDS81

As captured from an original ILap transponder.

@hydra
Copy link
Contributor Author

hydra commented Apr 13, 2024

@pkendall64 I've hopefully addressed all your points in your first review and did a little more cleanup, ready for round 2! 😃

@hydra
Copy link
Contributor Author

hydra commented Apr 13, 2024

Example of ELRS generated iLap signal and jitter:

RigolDS82

mha1 and others added 2 commits April 29, 2024 21:52
* Went un-noticed because stop-bit is always 0 which had the same on-wire signal level as idle level.
* Credits to Mickey for spotting the same bug in the refactored Robitronic code which led to different issues.
* Verified against an original iLap transmitter and verified against an iLap receiver.
@hydra
Copy link
Contributor Author

hydra commented Apr 29, 2024

Fixed a bug in the iLap code where the last stop bit was missing. Here's a scope capture of ELRS (orange) and an iLap transponder (Yellow) transmitting the same code.

image

There's a small timing variance, likely due to the original iLap transponder's choice of mcu, crystal, baud-rate error, but both within spec of the receiver.

@mha1
Copy link
Contributor

mha1 commented May 5, 2024

Robitronic/Easylap IR transponder protocol was successfully tested using a ZRound lap timing system. The system registered the expected transponder ID 902156 and successfully identified the transponder passing the timing bridge.

image

@hydra
Copy link
Contributor Author

hydra commented May 6, 2024

This PR is now feature complete and tested on two different IR transponder systems, ready for final review and merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement 🪄 New feature or request V3.5 🍩
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants