BREmote - Future Development Topic

start logic would probably be an Arduino + relay driver
be aware this schematic has the start logic always attached, so it will draw power until you unplug the battery
technically the on button can be left out, if the start logic is used to also supply the Rx, in that case the Rx could be used to wake up and power off the main circuit

1 Like

Both in series, so either can break the circuit.

MOSFET was just to protect the relay from sparks and high current switching. Your simple pre charge circuit would probably work just as well.

It was just an idea, and I am probably just overcomplicating things again.

I have 3 actual scenarios that did happen to me.

A) Foil assist after a long day, probably degraded mental state, have to get the board 100m out into deep water, first start, no power, ESC goes to 90° C instantly, followed by E7 on the remote. I did not close the hatch properly, was just loosely sitting on top. So lots of seawater inside. Had to get it all the way back and me somewhat dry to disconnect the battery. Took like 5 minutes.

In the end nothing was damaged after I cleaned everything with IPA, got lucky. So switch would not have changed anything. But in the 5 minutes the complete setup could have started a fire.

B) the one linked above, heard a slight clicking when connecting battery, but did not react. After I closed the hatch and checked with the remote if everything is working, ESC temp already was 40° C and rising with no load. By the time I had the tool to open the lid there was smoke coming out of it and before I had it open, it already stopped.

ESC was probably already dead when the temp was rising, so again would not have mattered.

But also could have been much worse

C) Tow boogie gets seriously washed by several waves and is floating upside down. By the time I get to it and turn it over the BEC died from water inside. Again mild outcome.

If I could have, I would have turned it off immediately.

In general I dislike handling the systems on land as long as the props are potentially powered. It’s probably an unneeded fear as with no remote input it should not matter. But I feel better once I disconnect the battery.

If it were simple and I could just use the remote to depower the system I would surely use that.

But the solution sounds like it could be just as complex as to introduce additional problems instead of solving any. Especially if I am the only one who potentially considers this useful.

Valid points that make the system worth it

Adding the detection would be simple, either Arduino or capacitor and op-amp

Adding the actors (relays, anti spark, power supply for these) are the part that will be hard to get perfect and pricey

1 Like

a very dirty hack but it works.. a cut off key,

small and only in case of emergency.. Note I am using an anti-spark male connector, not that is much better than non-antispark… but it will cut power. :slight_smile:

BREmote V2.5-Evo update: new remote screens, easier Follow-Me, front stations, setup wizard

Hi all, there's been a lot of work on new version since my last post, far too much to list here. These are the highlights; the commits and changelog on GitHub have every detail.

The new Follow-Me screens

Every Follow-Me state now has its own look, so one glance tells you what the buggy is doing. The numbers are the metres between your remote and the buggy.

Remote screen: one dot hopping, scanner sweeping
Waiting
One dot hopping. Follow-Me is armed, not following yet. A parked auto-return looks the same.
Remote screen: two steady dots, bar from the centre
Following
Two steady dots. The buggy is towing behind you; the bar grows from the centre with distance.
Remote screen: dots filling down, metres counting down
Coming to you
The dots fill down from the top. Auto-return or return-to-me: metres count down, the bar shrinks.

Try the glance quiz (can you read it in a third of a second?): BREmote Follow-Me Screens

Highlights

  • Serial console on the buggy's WiFi page (long on the wishlist): run any command from your phone at the dock or the beach, with one-tap buttons for everyday calibrations and a dropdown to pick commands. No laptop or USB cable needed.
  • Water testing without the compass, on GPS course only, to get away from the motors' magnetic interference. Next: the compass mounted much farther from the motors.
  • Easier Follow-Me with ideas from Heiguga. Auto-return stays on for easy summoning: stop, squeeze, and the buggy comes back. Manual return-to-me is still there.
  • Radio improvements from Ludwig's upstream, merged as far as possible (some were already done or extended in my fork).
  • Testing a new VESC Lisp script on both VESCs: a 5-second launch boost when getting up.
  • Nightly builds: all of this is in the nightly firmware on the fm-stations branch (binaries in the latest-FM-stations folders). It is bleeding edge and still being water-tested, so it is for me and those who dare. After more water testing the commits move to master step by step, and new nightlies keep coming. Update the remote and the buggy together, and download your buggy logs before flashing.
  • To be water-tested: front stations F4/F5 (Heiguga's idea). The buggy can run ahead-left or ahead-right, never dead ahead. A protection cone on your projected path that it never cuts through: small when you're slow, stretching forward as you speed up. Extra distance forward plus a side margin, so it's hard to hit the buggy.

Safety rules the remote now follows

  • Manual always wins. If GPS, the compass or any automatic mode fails, the automation switches itself off and you can always drive home by hand.
  • "St" means not working. One signal for anything that stopped or was refused.
  • "Waiting" means it will work. If the buggy can't come back, you get "St", not a waiting screen.
  • On arrival you get steering back at once, but the throttle stays limited until you let go once, so a buggy arriving while you're at full throttle can't run into you.
  • Return and arm gestures only work with the trigger released. Steering a returning buggy never cancels it; a magnet tap still arms Follow-Me while you're being towed.

Settings without reading every parameter

  • The best settings come as defaults.
  • For early new adopters: a setup wizard. Answer the questions (about 8 minutes), get your settings as a small file to load with the web serial config tool over USB, or to paste on the board's WiFi page from your phone. Review them carefully before saving: setup wizard

Note: the guide, the screens and the setup wizard match the nightly firmware, not master.

Guide and firmware: github.com/monterman/BREmote-V2. Feedback welcome, especially from anyone riding Follow-Me in waves, and post your quiz scores!

4 Likes

I’m getting excited. I have all my parts in the post including some SLS Nylon housing. I have plenty of 3D printed but wanted to try to SLS Nylon printing service out.

1 Like

Sorry for derailing the other thread a bit.

Thanks for explaining, that helps! I looked through the radio code, and I think we might have been talking past each other a bit. Let me try to explain my idea more clearly.

As far as I can tell, each Tx sends every 100 ms on its own timer. The Rx answers every valid packet addressed to it, and address filtering happens in software. So if I simply copied the address into several remotes, the Rx would answer all of them, and I agree that would get busy quickly.

My idea is to add one check in front of the existing logic:

  • All remotes share the pairing address and add a small remote ID.
  • The Rx only processes and answers the active remote. Packets from the others are dropped right after the address check, just like packets from another rider’s remote.
  • The Rx still sends one telemetry reply per packet. Because all remotes share the address, every remote receives it.
  • Once the active remote has been at zero throttle for a while, another remote can take over.

The main point for me: two remotes with this feature should always be at least as good as two remotes without it, for example two riders next to each other. Those already transmit unsynchronized on the same channel, and their two receivers each answer as well. With the feature you get the same remote packets but only one reply, so less traffic. And since we control our own remotes, inactive ones could even send less often or with some random timing.
That’s not possible with other riders.

So as far as I can see, no synchronization is needed. It’s mainly extra filtering and handover logic on the Rx. But you know the system much better than I do, so I might be missing something. Happy to help test it if you think it makes sense. :slightly_smiling_face:

One more thought on the ID. Instead of adding a configurable ID, each remote could just use the last 3bytes of its ESP32 MAC address. That’s already unique per chip, so no configuration and no change to pairing wouldbe needed. You’d copy the pairing address to each remote just like today.

A few things that make it nice: With a single remote, it would behave exactly as it does now, so the feature could simply always be on. If I calculated it correctly, at SF6 the payload is coded in 24-bit blocks, so 3 extra bytes cost the same airtime as 1 extra byte (packet ~7.5 ms → ~9.3 ms).

The ID only matters between remotes paired to the same Rx. With 3 bytes, the chance of two remotes clashing is about 1 in 16 million.

The only catch is that Tx and Rx would need to be updated together, since the packet format changes slightly.

How do you define / signal which remote is “active”?

No they do not. Since the last update: The Tx sends to Rx, waits for an immediate telemetry response. If it does not get it, it assumes there was a collision and it hops to another timeslot to send. This is the fundamental change that now allows using multiple systems at once, before that there was always a problem where multiple Tx over time with slightly faster/slower clocks were running into each others timeframes causing problems. And that is why there needs to be synchronization between multiple independent Tx as well, otherwise there will be random collisions.

Generally I would keep packets the same, just add more possible src_addresses that are allowed to allow more Tx’s. Or just have all Tx’s with the same address and decide which one to listen to. Anyways they would have to be synchronized so all packets can be received and analyzed separately by the Rx, the response (Rx telemetry) could of course be broadcast, but then the current hopping / collision detection strategy will not work anymore.

__

Probably easiest solution:
Keep Tx code exactly like it is
In Rx have additional parings (dest / src addresses)
React to each Tx packet like now (keep the code the same), this way the Tx’s will synchronize with the existing hopping system
Decide which of the Tx packets has priority, probably by throttle status or something else
I will fiddle this together in code for 1-3 remotes and share in the next days

Are we on the same page that we basically just listen to all Tx’s and do whatever the one with active throttle or steering input does? Or the one with the highest input? Basically just use max(T1,T2,T3)? Or is there a smarter way how to react if 2 Tx are non-0 throttle? @Jan12 and everyone else interested?

EDIT: The Rx will only accept throttle or steering, if 2 out of 3 remotes are sending 0 throttle/steering, and then listen to the remaining one that is sending signal
If 2 or 3 Tx send at the same time a throttle/steering != 0, it will not accept any input (stop the motors) and send an Error code (“E9”) and this will be displayed like the water error and make the TXs vibrate. It will resume working once only 1 Tx is active again

2 Likes

Thanks, that clears it up. I had missed the collision hop. Every Tx needs its own reply, so a shared address with a broadcast reply is out.

Note: this is just a proposal. I’m in bed with the flu, so the code reading was mostly done by AI and I haven’t checked the facts myself. The proposals are mine. You know the facts better anyway.

Addressing: Agreed: keep the hopping, add pairings in the Rx, and answer every Tx like now. But the Tx only sends the Rx address, so a list of Tx addresses alone doesn’t help: the Rx can’t tell who sent a packet or where to send the reply. Suggestion: the Tx sends its own address in those 3 bytes instead (one line in sendData). Same 3 bytes, and the Rx filters against its list of paired remotes and knows the sender. Pairing stays as it is, and the Rx can still accept packets to its own address as one legacy remote. Each remote has to pair itself, because a copied config copies own_address.

Active remote: Mode is owning. With no remote active, the first one with input (throttle != 0 or steering != 127) takes control. The Tx already sends exactly 0/127 when released or locked. Only its input is used. The others still get their replies (for hopping), but their input is ignored. Control is released after a timeout without input (Rx config, e.g. 5 s) or on link loss. If two start at once, the first packet decoded wins.

Failsafe: While a remote is active, only its packets refresh last_packet. With no remote active, any paired remote keeps the output at neutral.

E9: Only to the ignored remote, with the motors kept running. Otherwise a bumped spare remote stops the towed rider (max() has the same problem). The Tx keeps remote_error until the user deletes it, so clearing E9 needs a Tx change (in your version too). Locked remotes send 0/127, so they can never take over.

Airtime / step 2: Replies are about 7.5 ms each (calculated). Answering every Tx at 100 ms means about 15% Rx duty cycle with 2 remotes and 22% with 3, against the EU limit of 10%. Step 2 (Tx change): the top bit of telemetry_index means “not in control”. An old Tx ignores the value but still counts the reply for hopping. A Tx that isn’t in control, or has been released, drops to a slow rate (about 300 ms or slower with 2 remotes, 600 ms with 3) and goes back to 100 ms on its own input. That’s close to the 1 s failsafe_time, so the Rx needs a longer timeout while nobody is in control (the output is neutral anyway).

Happy to test with two remotes.

The Rx has 3 addresses it is listening to, one for each Tx is what I meant in my proposal, so it knows who is talking to it by which address is being talked to
This way the Tx code stays 100% what it is

Sounds good, but don’t understand why clearing E9 would need a change? Clearing errors is implemented already independent of the error

The limit is per device, not per system :wink:

Get well soon, Jan! My comments... I like the "owning" model, and I agree on E9 going only to the ignored remote with the motors kept running. A bumped spare remote should never stop the rider who is being towed. +1 on each remote sending its own address: every remote gets its own ID for free, and the Rx can accept or decline each one by its paired list. A few additions from my own multi-remote notes (two people sharing one tow buggy):

Master and guest roles: since the Rx knows each remote by its ID, it can also store a role per remote. My idea: the first remote paired is the master, the others are guests.

  • A guest can only take control when nobody owns it, or when the owner has released it (timeout or lock).
  • A guest can never take control from an active master.
  • The master can take control back from an active guest, for recovery: the guest is out of range, dropped the remote, or freezes while the buggy needs stopping. That needs the master's throttle at zero and a deliberate double-press-and-hold of 1-2 s, and it is refused while FM/RTM is armed. The guest's remote shows that control was taken, so it doesn't look like the remote died.

Airtime margin: I measured a 6-byte packet at 7.49 ms on the remote (radio.getTimeOnAir()), so your estimate holds. But with one remote at 100 ms the Rx is already at 7.5 %, and the idle remotes at 300 ms (2 remotes) or 600 ms (3 remotes) add exactly 2.5 %. That lands right on 10.0 %, with no margin. With idle remotes at \~1 s the Rx stays around 8-9 %, which leaves room for meta packets and retries. Your point about a longer Rx timeout while nobody is in control covers the slow rate.

Takeover only from neutral: "first input takes control" is fine, as long as the new remote can't step straight to wherever its throttle happens to be. I'd make a takeover start like an unlock: the new remote has to be at zero throttle first, then ramps up from there. A thumb resting on a spare remote then can't launch the buggy the moment the owner's timeout runs out.

Follow-Me / RTM: only the remote in control should be able to arm them, and only its GPS should be followed. Any change of control should disarm FM/RTM first, so the buggy never follows or returns to the wrong person.

Pairing: since each remote pairs itself, it would help to pair all remotes in one Rx pairing window, keeping the new list in RAM until the window closes. An aborted pairing then never unpairs the buggy.

US (902-928 MHz): there is no 10 % duty limit there, but as far as I can tell FCC 15.247 needs frequency hopping or at least 500 kHz of bandwidth at this power, and a fixed 250 kHz channel fits neither. A 500 kHz US preset would fix that and halve the time on air, which also gives multi-Tx more room, at about 3 dB less sensitivity. (Not legal advice; happy to be corrected. I was too quick in August to call it simply "legal in the US".)

Happy to test too. I have two remotes and can try the takeover, E9 and slow-rate cases on the bench and on the water.

Yes, the US rules are a bit more complicated, you would either need to reduce output power or duty cycle to be fully legal, or do the FHSS

I understood you already have a working multi-remote solution in your fork?

Yes, understood. Claude also explained this to me. It’s easy and does work.

But it’s also a bit of a hack and any changes (not in code, in use) need config changes on both TX and RX. Still far better than current situation and simple to do. Simple is always good.

And yes taking over should need zero throttle first and then a low limit.

still coding Multi-TX, and it is on the back burner ATM.
Been testing and coding the FM stations branch giving forward buggy stations for FM. So far very happy with the FM behavior on all rear follow me (not yet fully tested forward stating to trust).

1 Like

I think any pairing needs change to the configuration, say you proposal:

How does the Rx obtain this list of “paired remotes” ? The pairing process will also have to write these addresses to some config, won’t it?
No matter how, you will have to tell the Rx in some way or another the address of Tx1,2,3
If that is by receiving address or by address of Tx1,2,3 should not change the procedure?

Hi,

I’m building my Bremote v2 with GPS. I initially got a kit from Jasmin that used the BN-220 gps module. I can see things have moved on a bit and the m100 mini is preferred so I’ve bought that and I’m ready to solder the 4 cables from the m100 mini to the tx board. In Ludwigs video he has the BN-220 soldered to the GND, g19, g18 and the 3.3v pins. The m100 mini comes with cables pre-soldered to the GND, 5v, tx and rx pins on the m100. Which pins do these connect to on the Bremote tx? I can see the Bremote tx has a tx and rx pin as well as a g19 and g18. Also, is 5v connected to the 3.3v ok? Any guidance is much appreciated given I’ve only got one shot at this before potting it.

Thanks

On the BN-220 that I showcase, RED=5V, GRN=Rx, WHITE=Tx, BLACK=GND
Match this to your module
Should be:
G18: UART-Rx of GPS
G19: UART-Tx of GPS
Most modules need/want >3.3V like 5V, but connecting them to 3.3V works. The Tx does not have any 3.3V so there is no other choice really

2 Likes

Thanks for the speedy reply.

1 Like

During pairing, the Rx would add each Tx address to a list.

I normally edit the config manually anyway. With the Tx already configured, I’d simply add its address to the Rx’s list—only the Rx config needs changing.

Functionally, the addressing approaches make little difference. But with the other approach, we have three “Rx addresses” even though there is only one Rx. We also have three Tx addresses for replies, but it’s the so-called “Rx addresses” that identify which Tx sent a packet.

That’s why I prefer the other proposal: each Tx’s own address identifies the sender and addresses the reply. An address identifying a Tx should simply be called the Tx address—that seems clearer to me.

Of course, my proposal requires a Tx code change. The alternative avoids that, but at the cost of making the addressing setup more confusing, at least to me.

Either option would be great, since tow boogie sharing is super fun, but currently a bit odd.