TWR Deployment Scenario

Sascha, the “No” was meant as “No, the receiver cannot decode messages that arrive at the same time”. It also can’t receive a message while it is in the process of sending a message. Regarding receiving a message while it is processing another one it all depends on what you mean by “processing”. I am not sure there is much processing that occurs after the last bit of message is received. Also, it has been a while since I worked on the code; but, my recollection was that you have to send the message, wait for the message send to complete then change the DW1000 to receive mode and do a blocked wait (with timeout) on a message. The dwm1001-examples code shows this and it works. The problem for us is that for us to do peer-to-peer, we couldn’t afford to do the simple loop with the send then a blocking read. This would not allow us to receive multiple packets. We were able to get it to work multi-threaded but it took some playing to get there. Also, we were able to get the code to work with multiple responders. We would still miss packets but we got enough. I tested it with 4 stationary units and one mobile one and then did a 3 unit peer-to- peer demonstration - me an my two sons in the basement wearing units showing how they worked on a video call. There are some things that were difficult to get running in the code; but, my next step would have probably been mostly on paper - use cases and timing diagrams to figure an algorithm that at least worked on paper.

Ok, thanks. Your recollection of how it works is just that. You start a transmission, but can also have the hardware automatically transition to receive mode once it finishes the transmission. (Using the wait4trans bit in the ctrl register). Then you do a blocked wait, waiting on a successful response or a timeout. Then if you want to keep looking for responses, you have to set a bit to re-enable the receiver. The processing I was referring to was mainly just the SPI reads for the status of the response, frame length, and the actual rxdata. I will have to see how long this takes and also see how the filtering works. I do not need to be able to get distance superfast (maybe get the distance of a tag every 2 seconds) so I think I should be able to come up with some kind of solution to be able to get the distance of multiple responders. Thanks again for your input!

I like the idea of doing acknowledgments and this could be the way I go. My anchor can acknowledge each tag and if the tag doesn’t get an acknowledgement, it can resend the frame. I will have to do some testing to see how well it works. The plan is the anchor sends out the data frame to get the distance to each tag and the first response it gets, it will send the ack to that tag. Then I will keep the anchor in receive mode and wait for anymore data responses that would be resent by the tags. I will have to use a timeout on the anchor to know that all the tags that are in proximity have been read (either use the receive timeout bit from the dw1000 or create a software timer that waits for X amount of time for all the responses). Will take some work to code it all up, but I think the operation using the ACK could be the best way. I will have to implement the frame filtering, ack frames, and the tags switching between transmit and receive modes (and resending the data frame). I also think I will try out the double buffering to see if that helps.

I am not exactly sure the maximum amount of tags that will be able to communicate with each anchor. It could be many hundreds so I am not sure if I could do something with the transmit delay on the tags. I also plan on implementing power saving on the tags so they could wake up each second or so to listen for a preamble. Thinking about it this way, it could be possible to have each tag have a different delay based on an ID and combine this with the sleep mode. The odds of having two tags with the same transmit delay as well as both waking up at the same time would probably be low, right? What do you think? The tags transmit delay / sleep would be something easy to test so I will try that too. Perhaps transmit delays, sleep, and double buffering will be enough.

It’s easy to get a rough estimate of how well it will work.

Say each poll to see which anchors are in view takes 10 ms and then each two way range takes 2ms. If you are typically in range of 3 anchors at a time that’s 16 ms that a tag is active for. Let’s round up and call it 20 ms per tag.
If you try to update at 1 Hz then you’re active for 2% of the time per tag.

If the tags aren’t exactly at 1 Hz, there is a little bit of variation in that then tag to tag collisions are random.

So with 2 tags you only have 2% of measurements lost due to collisions. But with 10 of them you have a 20% change that for any given tag measurement cycle will collide. That’s about as high as you want it to get, any more and it’s not going to work well.

Two simple changes that would greatly help this:
Reduce the update rate, obviously a lower update rate will reduce the chances of collisions. While 1 Hz is a nice number it’s probably far faster than you’d need.
Listen before transmit - work out in your tags active window what the maximum idle time would be (probably a timeout waiting for a reply). When a tag wakes up it first listens for a little longer than that maximum time. If it sees something then it goes back to sleep for a tag update period (20ms in the case above) then wakes up and tries again. Not perfect and slightly higher power usage but it would drastically reduce collisions.

That is good methodology. In my case I will have an anchor in each room and it only cares about tags that are in close proximity to that anchor in the room. That was why I was trying to have the anchor start the two way range process and figure out a way to have each tag respond with its distance so the anchor would receive each one successfully. I also want to get the distance of each tag over UART from the anchor.

We also aren’t sure if the anchor will be battery powered or plugged in to the wall. I think either way having it on most of the time should be ok as they battery will be large as it has to accommodate the UWB, Wifi, BLE and some motors. Using the tags in your method here might make more sense if the battery life for the tag would be ok. (I think it is the same method you described in your first reply, just more details). I guess I could just create custom data frames for a “who’s there”, “measure my distance”, etc. since we can send any data we want, I just need to code it up how the tag/anchor interprets this data. We plan on having the tag in a badge that the person wears, powered by a coin cell or something similar. I don’t think I would have to worry much about other tags picking up a “whos there” frame (that is meant for an anchor) since the tags would wake up and be in transmit mode.

I want to make sure I understand something correctly we have been discussing. I don’t have a ton of experience with low level aspects of wireless technologies. When I am doing my tests, I will have one anchor and 3 tags (the tags are fairly close together). When I send out a poll message and then wait for responses from them (if the responses are set for the same transmission delay), I usually only get 1 response. When we are talking about collisions, are collisions happening with the other two responses? I guess from a basic level, why aren’t the other two responses getting through? Are they “colliding” in the air, or is it a case of the DW1000 having status and data for the 1st response that hasn’t been read out yet that it cannot accept data for the other responses? Is there any other RF transactions happening “behind” the scenes that are not controlled by my firmware writes/reads to the DW1000’s registers? The way I understand it is my firmware is in control of what UWB packets are sent (by the transmission buffer and tx control bits) as well as switching to receive mode and being able to read the raw UWB data portion of the packet that was received. (I guess if I was using PANS, most of the low level transactions would be taken care of, but for my use case I think it is best to just write the UWB “drivers” myself). Just want to make sure I am understanding the main issue here, which is being able to have multiple responders send data frames back to the anchor successfully.

There are whole books on getting radio signals to coexist so this is going to be a very brief overview, I’m skipping a lot of detail here.

What we are aiming for is known as TDMA, Time Division Multiple Access, each transmitter takes turns sending data.

When two or more radios transmit at the same time then the radio signals are effectively added together. For normal radio systems this means that either both signals are lost completely (it’s still all there but too distorted to reliably decode) or one signal is correctly picked up and the other is considered part of the background noise. Generally the first situation occurs when the signals are about the same strength and the second when one is significantly stronger than the other.
There are ways to allow multiple active transmitters at once, with different xDMA acronyms but the signal has to be designed to work in that way.

But UWB is a little different, because it is transmitting short pulses during the “active” period the transmitter is still off most of the time. So if two UWB transmitters start at almost exactly the same time then there is a fair chance that to the receiver the second transmission is going to look like a distorted reflection of the first. Since the UWB system is designed to ignore reflections as much as possible there is a fair chance that the first signal will be received even if the second is a lot stronger.
The second packet is completely lost.

There is also the possibility that the reception of the first packet starts but then the data becomes corrupted due to transmissions from the second unit being mistaken for ones from the first. In this situation a receive error condition will be generated and both packets are lost.

This is assuming that the two packets overlap, depending on packet length and radio settings a packet transmission takes between 170 us and several ms.

If the two packets don’t overlap then it is possible to receive both if the receiver is re-enabled quickly enough after reception of the first packet. In this situation your protocol needs to decide what to do, does it handle one then the other, try to handle both at once or completely ignore one.
If you expect multiple devices to reply to a single message then you want to get the replies to be spaced out enough that you are always in this situation.

e.g. PANS uses a ranging protocol where one message from the tag triggers replies from 4 anchors. The anchors space these replies out sufficiently that the tag can receive each one in turn rather than all 4 replying at the same time.

1 Like

Thanks Andy for that great response. Yeah I read the documentation about the PANS software and how it handles everything. Looks like it has the superframe concept and each tag has a designated slot to do the TWR. But as we talked about in the beginning, I don’t need the PANS. Thank you again to you and Mark for helping me out. I think I have some ideas to try to get TWR working with many tags. Ill probably try methods with ACKs/retries as well as your idea about the tag waking up periodically , looking for an anchor ,and then performing the TWR. I guess the benefit of programming at a very low level reading/writing the registers (as opposed to using PANS or something similar) is that I have total control of the UWB operation of the chips. Thus I have the freedom to come up with a unique TWR ranging scheme with all my tags that will fit my deployment scheme the best.

Also, do you think it is worthwhile to purchase the 802.15.4 specification? I think it is a few hundred dollars. For example, I cannot seem to find the structure of the 5 byte ACK frame. I can probably figure it out by looking at some example code and actually seeing what is sent in an ACK frame, but would be nice to be able to see a description of it.

Depends if you need to be interoperable with things that do follow the standard. If it’s an isolated system running your own packets then what benefit do you get from conforming to the standard?

Not so much conforming, I was just wondering if there would be more information in it to help me understand the general operation better. All the decawave documentation is pretty good and I think it covers most everything I need to know to get something up and running. There were just a couple things I couldn’t find clear answers on, but I can figure them out without buying the spec.

When you mentioned using acknowledgments, did you mean to use the auto acknowledgment? I have gotten the auto acknowledgement to work for the most part between a single initiator and responder. It looks like the acknowledgment is 5 bytes and is comprised of the frame control field, sequence field, and CRC. I couldn’t really find any info on the ack frame before I decided to try it, but I do not think it is going to work after testing. I don’t have anyway to determine which responder the ACK was directed to. I don’t think I could use the sequence number for it. I thought the ACK frame would have a destination address.

But, I guess I could just create my own “ACK” frame that has the address in it ? Instead of using the auto ack functionality, just write the frame data in the transmit buffer like any other message I transmit. (I guess I could have the frame type for data or ACK since I control the protocol from each end).

I’d create your own ack rather than using the auto one. It will be a little slower and add more complexity but gives you a lot more flexibility.

1 Like