Portenta C33 UWB Shield Library Appears To Be Incomplete

We've successfully built the demos using the sample code available via both the Stella and Portenta shield libraries.

According to the page for the shield (Portenta UWB Shield User Manual | Arduino Documentation, we should be able to develop TDoA, AoA, as well as set a sync master for TDoA. There are no references to any of this in the TrueSense library that is provided with this board. See below:

Portenta UWB Shield Library
The PortentaUWBShield library contains an application programming interface (API) to read data from the Portenta UWB Shield and control its parameters and behavior. This library is designed to work with the DCU150 module on the shield and supports the following:

One-way ranging (Time Difference of Arrival - TDoA) and two-way ranging (TWR).
Angle of Arrival (AoA) measurement for 2D and 3D positioning.

Is this functionality on the roadmap, and if so, is there a target timeframe? If not, I'll simply return the unopened boxes as we had high hopes that this would be a straightforward implementation as with all things Arduino.

Also, for TWR, the library requires that before the anchor responds to a Stella tag, it has to have the tag's MAC address stored in the Portenta. This limits the "Pro" hardware to DIY/enthusiast level since professional commercial implementations would need to scale to hundreds of tags. We've deployed other vendors' UWB products and developed solutions using their APIs and SDKs and none of them require prior knowledge of the mobile tag's MACs in order to respond to them. Also, a scanning function would be quite helpful - it is related to the last point about not requiring the anchors to be pre-populated with tag MAC addresses.

Lasty, there are references to WGS84 and, depending on the project, we convert cartesian coordinates to WGS84 coordinates (lat/long). There's no mention of this publicly, but it is visible in the Portenta shield library. Is there a complete implementation of the use of WGS84 coordinates or conversion functions from cartesian coordinates?

Regards,

jd

hello @symtech /jd
thanks for reporting.
The TDoA demo will be ready by next week and libraries (both Tag and Shield) will be updated accordingly. It will also include a Python library that performs anchor sync and tag position triangulation.

Ref TWR and MAC addresses, I'm not sure which products you have used before but in the FiRA standard a MAC address is required. Please note how in the NearbyDemo code the MAC addresses are exchanged out of band (via BLE).
Anyway, in TDoA mode the MAC address of the tag doesn't really count much, what is really important is the fact that the tag will transmit a 64 bits unique ID (see UWBAppParamList::tdoaDeviceId) which could be derived from, for example, the boards BLE MAC address. You will see this in the updated code.

Finally, ref the usage of WGS84 coordinates, that is not intended for classic TDoA mode, that's in preparation of a further demo that implements reverse/downlink TDoA. I will come in late July.

Hope the above helps for now

Best Regards

Pier
(Author of the StellaUWB and PortentaUWBShield libraries)

@pierpaolo_lento,

Thank you for your timely response. I appreciate you addressing my questions/concerns - and I'm very pleased to know that we're going to be able to move forward with, what I consider, an excellent hardware and software stack.

You are correct about the FIRA standard - we'll be using BLE for out-of-band exchanges (such as for discovery). I also understand what you are referring to with regard to TDOA mode and the 64-bit unique ID - that makes sense.

We're looking forward to learning what the full scope of the WGS84 features will be as we are also proponents of reverse/downlink TDoA for the scalability and I believe this has the potential to add new use cases/applications to the already numerous uses of UWB.

I'm sure that I'm in good company when I say that I'm very much looking forward to the updates to the library.

Cheers,

jd

hi jd,
thanks again for your interest. I can confirm we are going ahead with TDoA examples as per the schedule.

Ref the Reverse TDOA, I agree with you about the scalability which is virtually endless but I need to point out that it also has some peculiarities:

  • the Reverse TDoA mode for now is only supported by the sr150 chips (those on the Portenta shield) but not on the SR040 (those on the Stella Tags)

  • in Reverse TDoA mode, although in listening mode only, the radio on the tag nodes is always on, which implies much higher power consumption compared to a 'traditional' TDoA tag which instead only sends blinks at regular intervals and then shuts down the radio for the rest of the time.

  • the position of the tag is calculated on the tag itself which, compared to TDoA, implies no data transfer over wifi/ethernet thus reducing latency and making it a good configuration for applications where a drone or autonomous vehicle needs to react in very short time.

  • the WGS84 metadata (or custom position metadata which is another option) is transmitted by the anchors and detected by the tag. That's how the tag can calculate its own absolute absolute position.

hope the above helps

Best Regards

Pier

Piers,

Thanks again - these points are expected (except the inability to perform reverse TDoA in the SR040 chips). This is fine, as over 50% of our use cases are for UGVs (or other self-powered vehicles) on a campus or warehouse. In those cases, we prefer to simplify the deployment and calculate the position on the rover which, as you mentioned, reduces the latency to obtain a position.

We've also used larger radios than the Portenta+shield, so the size/power are non-issues for us (in the case of UGVs). This configuration also simplifies the infrastructure configuration as we will be sending the position from the rovers to our cloud-based fleet management system where latency isn't as critical. For field-based smaller mobile deployments we typically only use TWR/AoA to for the moving vehicles to determine relative positions between themselves. This is much more accurate than performing this with GPS (and we don't want to incur the expense and overhead of RTK GPS + NTRIP). For asset management, we use TDoA as it lends itself well to this use case.

I'm truly looking forward to working with the WGS84 data. Handing lat/lon positions to customers that have existing mapping solutions helps us win those opportunities. We've had to create our own system for this for tracking trains in tunnels and areas where GPS is poor. It allowed the MTA teams a way to continue using their existing systems to track the train positions.

I'm sure you can see why the Stella/Portenta UWB products are of interest to us.

Thanks again for the timely updates,

jd

Hello,
I hope you are doing well. As per my experience i think there is support for AOA on the hardware level but the library is still not compatible with it. Could i ask when the AOA support will come to the library and if there is gonna be an code example for it. Because we are facing a similar problem and it would be really helpfully to have this feature.
Kind regards,
AT

1 Like

Hello,
Dear @pierpaolo_lento, could you please confirm that the support for AOA is coming out next week to the library plus the code example? If yes, could you please give a rough date of the new update.
Kind regards,
AT

I think you meant this to be directed to @pierpaolo_lento.

1 Like

hi,
in reality the AoA feature is already there, I didn't expose it in the demo sketches because I think it needs a bit of cosmetics.

Infact in the rangingHandler() callback you can already use something like:

twr[j].aoa_azimuth

The point is that the reported value is the raw one that needs to be translated into Q9.7 format, i.e. the integer part of the measurement is obtained by:

twr[j].aoa_azimuth >> 7

while the non integer part is obtained by:

twr[j].aoa_azimuth & 0x7F

This will give you the angle measurement.

That said, I really need to set clarify the behavior of the AoA feature:

  • only azimuth angle will be measured
  • angle value will be within -60.0 and +60.0 (this is the max field of view). When you exceed the field of view the value will saturate
  • AoA precision depends a lot on the copolarization of the antennas on the 2 sides of the measurement. If you look closely at the sensor you will see the antennas, they look like an oval notch. The 'trick' is that the more you keep them on the same orientation, the more you get good AoA results. For example if you use the Portenta Shield in portrait orientation (which is the suggested one) to range against a Stella tag, then you better rotate the Stella around it's z-axis with the antenna pointing to the right (looking at it from the front).

Please have a try and let me know, you may also notice some offset from the real angle which is something we are optimizing.

That's all for now

Best Regards

Pier

1 Like

Hi Pier,

I've been waiting to see if there will be a demo for how to use TWR from the Stella to multiple Portenta C33 UWB modules so we can begin multilateration and TDoA. Is there an expected time frame for these APIs & demos?

Also, for our planning, will the TDoA clock master be able to also be used as an anchor in the UWB constellation?

Thanks,

jd

Hi JD,
UWB part is done, seems there is an issue with the MQTT library though, we are working to solve it.

P.

Thanks Pier,

Using MQTT is worth the wait!

jd

Hi Thanks for your responses so far.

I am trying to get intuition for the optimal orientation of the antennas for AoA.

I am looking at the hardware, and I see the small oval shaped impressions on the white sensors that you mention. The Stella tag has 1 and the C33/UWB shield has 3.

Is it okay to compare these oval shaped antennas to the eyes on a persons face? The 1 eye on the Stella and the 3 on the Shield should be in the same horizontal orientation, like the eyes on a persons face?

  • If the Stella's 'eye' is turned on it's side, like a person turning their head to the side, while the Shield's 'eyes' were normal, would that be a non-optimal orientation?
  • Do the 'eyes' need to be looking at each other, like the way two people would look towards each other in a conversation, or can the stella "look away" and still get a reliable AoA measurement?

Hi Pier @pierpaolo_lento,

Thanks for your great work on the StellaUWB and PortentaUWBShield libraries. I've been experimenting with the UWB_Ultdoatag.ino demo and setting up my Portenta C33 + UWB Shield infrastructure as described—very excited about what the uplink TDoA system could enable.

In your earlier message, you mentioned that anchor-side support for uplink TDoA and the Python triangulation tools would be available "next week." Since that timeframe has passed, I wanted to check if there's an updated timeline or early preview available. I'd love to begin testing with anchors and integrate the full system.

Additionally, I've noticed recurring errors and warnings when compiling or running other examples—particularly related to GPIO Pin 6, which seems to trigger misconfiguration or undefined behavior in certain contexts. It would be helpful to know if this is a known issue or if there's a recommended workaround.

Thanks again and looking forward to your update!

Best regards,
Alexander

Hi @rose_alex , the GPIO Pin 6 error is not a real error, the message will be removed soon, however I would appreciate if you could please report which misconfigurations or undefined behaviors you are seeing.

For the TDoA stuff, as per my previous message in this thread, the UWB part is ready, the issue is with the MQTT stack that freezes after few messages are sent. As you may notice via the issues posted on the Arduino Renesas Core github repo, this issue seems to be part of a larger problem with the networking stack. We are trying to address it by ourselves but for now it's very difficult to commit on a firm date.

I will update ASAP

Best Regards

Pier

hi @huttonstephen,
yes it's correct to compare the antennas on the tag and on the shield, they essentially share the same design.
The best orientation is to keep the Shield in portrait mode (upright) while the Tag shall have the white DCU040 module on a side, not at the top or at the bottom, so that the longer axis of the oval 'eye' is horizontal, thus matching the orientation of the 'eyes' on the Shield.
The more the eyes they look away from each other, the more measurement error you will get.

Hope it helps

Best Regards

Pier

Stella Tag + Shield C33 Anchors — Feedback on GPIO, MQTT Freeze, and IMU Behavior

Hi @pierpaolo_lento,
Thanks for the clarification regarding GPIO Pin 6 — helpful to know it's non-critical and slated for removal. I wanted to share my experience using the Stella board as a tag in a multi-anchor setup, in case it’s useful for future development or firmware refinement.
My goal is real-time indoor positioning using:

  • Stella as the tag
  • 5 anchors (Portenta + UWB Shield C33), one acting as master
  • TWR sessions via the StellaUWB and PortentaUWBShield libraries
  • Data formatted as:
    <a, anchorcount, ax, ay, az, gx, gy, gz, distance1, angle1, distance2, angle2, ...>
  • Output transmitted via UDP to a PC

Current Test Scope
So far, I’ve tested with 2 Shield C33 anchors to validate core functionality before assembling and flashing all five units. Once stability is confirmed, I’ll expand to the full configuration.
I previously used a DW1000-based setup, but switched to Arduino’s solution in hopes of more robust support and tighter integration. Brand trust and the promise of fused AoA and IMU data (which the DW1000 didn’t provide) motivated the transition.

GPIO Observations
I consistently receive this warning at startup:
GPIO Pin 9: mode mismatch

It usually appears just before UWB initialization and tends to correlate with other errors:

HALUCI  :ERROR:phNxpUciHal_uwbDeviceInit: Sem Timed out  
TMLUWB  :WARN :Command error in SPI Write...  
HALUCI  :WARN :phNxpUciHal_write_unlocked phTmlUwb_Write Failed  
UWBAPI  :ERROR:UwbApi_GetUwbDevState: UWB Device is not initialized

These issues lead to unstable sessions and zeroed-out data packets like:
<a, 1, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00>

Mitigations I’ve added:

  • Delayed initialization of BLE and IMU
  • Retry logic before starting UWB sessions
  • Session creation only after confirming UWB state is ready
    This improved consistency, but SPI write errors still occur occasionally — possibly due to timing or bus contention.

IMU Behavior (SC7A20)
The Stella board is documented to include an onboard SC7A20 accelerometer. However, I’m unable to access it through I²C.

  • Scanned addresses 0x18, 0x19, and 0x1C
  • Tried minimal WHO_AM_I detection logic
  • Added delays and scoped I²C comms separately
    Each test fails with:
    No SC7A20 IMU found
    IMU not responding

It’s unclear whether the IMU is powered, connected, or supported in current firmware. The StellaUWB library does not expose IMU access directly. Until there's confirmation on availability or support, I'm disabling motion data and returning zeroes in those fields.

MQTT Instability
As noted in recent threads, the MQTT stack freezes after a few transmissions — affecting my setup as well. For now, I’ve disabled MQTT entirely and rely on a clean UDP pipeline, which is stable.

Summary of Current Status

  • UWB: Functional with cautious init
  • IMU: Inaccessible
  • GPIO Pin 9: Repeating warning, unclear significance
  • MQTT: Frozen; disabled
  • UDP messaging: Working as intended
  • Test anchors: 2 (will expand to 5 when stable)

If I can provide logs, firmware diffs, or session telemetry to help with future updates, I’d be happy to share. I’m hopeful the Arduino stack can deliver on fused UWB + IMU tracking — and will continue testing toward that goal.

Best regards,
Alexander

Hello,

Thank for your answer. I have been experimenting with the AOA feature of the module and i have observed the followings:

  • The AOA calculation is not too bad generally, but there is a random value between 56 and 58 that occurs when i move from positive angle to negative angle. But the maximum angle that it could measure is +/- 45. Then what is this random value.
  • The chips AOA range is from 45 to -45 degree. This limited range plus the 10cm angle inaccuracy is actually the biggest downside. is the angle range issue from the hardware?
  • The initialization of connection between two devices are really great and also works great if the antennas are covered.
  • What is the recommended sampling rate for the both modules?
  • The code on the Arduino documentation does not run, but the one in GitHub works.

Kind regards,
AT

Hi, Is there any news regarding when the TDoA section of this library might be available?

1 Like

hi @jjmilad ,
in practice you should have a +/- 60 degrees AoA measurement and this is what we see from our tests.
Angle measurement is heavily dependent on the Phase Difference of Arrival (PDoA) of the signal to the 2 RX antennas so yes, it is very dependednt on HW but is is also dependent on a calibration procedure that we keep running against a zoo of ranging counterparts (e.g. the Stella Tag, iPhones, Android UWB phones and more). There will be an update of calibration quite soon in august but I think you should see better results anyway, have you checked the previous part of this thread where we talk about antenna cross-polarization?

There is no recommended sampling rate: it depends on your specific application and on your power budget, espcially if the ranging counterpart is powered by a battery (e.g. a tag).

Arduino team is already aware of the issue on the code samples in the guide and are acting to fix it.

Best Regards

Pier